colocate components
This commit is contained in:
parent
96c4023c14
commit
96da95818f
98 changed files with 70 additions and 360 deletions
|
@ -3,7 +3,7 @@
|
|||
import { FormEvent, useState } from "react"
|
||||
import styles from "./auth.module.css"
|
||||
import { useRouter } from "next/navigation"
|
||||
import Link from "../link"
|
||||
import Link from "../../components/link"
|
||||
import { Button, Input, Note } from "@geist-ui/core/dist"
|
||||
import { signIn } from "next-auth/react"
|
||||
import { Github as GithubIcon } from "@geist-ui/icons"
|
|
@ -1,4 +1,4 @@
|
|||
import PageSeo from "@components/page-seo"
|
||||
import PageSeo from "app/components/page-seo"
|
||||
|
||||
export default function AuthHead() {
|
||||
return <PageSeo title="Sign In" />
|
|
@ -1,5 +1,5 @@
|
|||
import Auth from "@components/auth"
|
||||
import Header from "@components/header"
|
||||
import Auth from "../components"
|
||||
import Header from "app/components/header"
|
||||
|
||||
export default function SignInPage() {
|
||||
return (
|
||||
|
|
5
client/app/(auth)/signup/head.tsx
Normal file
5
client/app/(auth)/signup/head.tsx
Normal file
|
@ -0,0 +1,5 @@
|
|||
import PageSeo from "app/components/page-seo"
|
||||
|
||||
export default function AuthHead() {
|
||||
return <PageSeo title="Sign Up" />
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
import Auth from "@components/auth"
|
||||
import Header from "@components/header"
|
||||
import Auth from "../components"
|
||||
import Header from "app/components/header"
|
||||
import { getRequiresPasscode } from "pages/api/auth/requires-passcode"
|
||||
|
||||
const getPasscode = async () => {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import ShiftBy from "@components/shift-by"
|
||||
import ShiftBy from "app/components/shift-by"
|
||||
import { Button, Popover } from "@geist-ui/core/dist"
|
||||
import ChevronDown from "@geist-ui/icons/chevronDown"
|
||||
import CodeIcon from "@geist-ui/icons/fileFunction"
|
|
@ -2,10 +2,10 @@ import { File } from "@lib/types"
|
|||
import FileIcon from "@geist-ui/icons/fileText"
|
||||
import CodeIcon from "@geist-ui/icons/fileLambda"
|
||||
import styles from "./file-tree.module.css"
|
||||
import ShiftBy from "@components/shift-by"
|
||||
import ShiftBy from "app/components/shift-by"
|
||||
import { useEffect, useState } from "react"
|
||||
import { codeFileExtensions } from "@lib/constants"
|
||||
import Link from "@components/link"
|
||||
import Link from "app/components/link"
|
||||
|
||||
type Item = File & {
|
||||
icon: JSX.Element
|
|
@ -12,7 +12,7 @@ import FormattingIcons from "./formatting-icons"
|
|||
import TextareaMarkdown, { TextareaMarkdownRef } from "textarea-markdown-editor"
|
||||
|
||||
import { Button, Input, Spacer, Tabs, Textarea } from "@geist-ui/core/dist"
|
||||
import Preview from "@components/preview"
|
||||
import Preview from "./preview"
|
||||
|
||||
// import Link from "next/link"
|
||||
type Props = {
|
|
@ -8,7 +8,6 @@ type Props = {
|
|||
fileId?: string
|
||||
content?: string
|
||||
title?: string
|
||||
// file extensions we can highlight
|
||||
}
|
||||
|
||||
const MarkdownPreview = ({ height = 500, fileId, content, title }: Props) => {
|
||||
|
@ -26,18 +25,13 @@ const MarkdownPreview = ({ height = 500, fileId, content, title }: Props) => {
|
|||
setIsLoading(false)
|
||||
}
|
||||
} else if (content) {
|
||||
// add title and query to url params
|
||||
const urlQuery = new URLSearchParams({
|
||||
title: title || "",
|
||||
content
|
||||
})
|
||||
|
||||
const resp = await fetch(`/api/files/get-html?${urlQuery}`, {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Authorization: `Bearer ${getCookie(TOKEN_COOKIE_NAME)}`
|
||||
}
|
||||
method: "GET"
|
||||
})
|
||||
|
||||
if (resp.ok) {
|
|
@ -1,5 +1,5 @@
|
|||
import type { Document } from "@lib/types"
|
||||
import DocumentComponent from "@components/edit-document"
|
||||
import DocumentComponent from "./edit-document"
|
||||
import { ChangeEvent, memo, useCallback } from "react"
|
||||
|
||||
const DocumentList = ({
|
|
@ -4,17 +4,16 @@ import { Button, useToasts, Input, ButtonDropdown } from "@geist-ui/core/dist"
|
|||
import { useRouter } from "next/navigation"
|
||||
import { useCallback, useState } from "react"
|
||||
import generateUUID from "@lib/generate-uuid"
|
||||
import FileDropzone from "./drag-and-drop"
|
||||
import styles from "./post.module.css"
|
||||
import Title from "./title"
|
||||
import type { PostVisibility, Document as DocumentType } from "@lib/types"
|
||||
import PasswordModal from "./password-modal"
|
||||
import EditDocumentList from "@components/edit-document-list"
|
||||
import EditDocumentList from "./edit-document-list"
|
||||
import { ChangeEvent } from "react"
|
||||
import DatePicker from "react-datepicker"
|
||||
import getTitleForPostCopy from "@lib/get-title-for-post-copy"
|
||||
import Description from "./description"
|
||||
import { PostWithFiles } from "@lib/server/prisma"
|
||||
import PasswordModal from "./password-modal"
|
||||
import Title from "./title"
|
||||
|
||||
const emptyDoc = {
|
||||
title: "",
|
|
@ -1,7 +1,7 @@
|
|||
import { ChangeEvent, memo, useEffect, useState } from "react"
|
||||
import { Text } from "@geist-ui/core/dist"
|
||||
|
||||
import ShiftBy from "@components/shift-by"
|
||||
import ShiftBy from "app/components/shift-by"
|
||||
import styles from "../post.module.css"
|
||||
import { Input } from "@geist-ui/core/dist"
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
import NewPost from "@components/new-post"
|
||||
import NewPost from "app/(posts)/new/components/new"
|
||||
import { useRouter } from "next/navigation"
|
||||
import { getPostWithFiles } from "@lib/server/prisma"
|
||||
import Header from "@components/header"
|
||||
import Header from "app/components/header"
|
||||
|
||||
const NewFromExisting = async ({
|
||||
params
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import PageSeo from "@components/page-seo"
|
||||
import PageSeo from "app/components/page-seo"
|
||||
|
||||
export default function NewPostHead() {
|
||||
return <PageSeo title="Create a new Drift" />
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import Header from "@components/header"
|
||||
import NewPost from "@components/new-post"
|
||||
import Header from "app/components/header"
|
||||
import NewPost from "app/(posts)/new/components/new"
|
||||
import "@styles/react-datepicker.css"
|
||||
|
||||
const New = () => <>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
"use client"
|
||||
|
||||
import VisibilityBadge from "@components/badges/visibility-badge"
|
||||
import DocumentComponent from "@components/view-document"
|
||||
import VisibilityBadge from "app/components/badges/visibility-badge"
|
||||
import DocumentComponent from "./view-document"
|
||||
import styles from "./post-page.module.css"
|
||||
|
||||
import type { PostVisibility } from "@lib/types"
|
||||
|
@ -10,15 +10,15 @@ import { useEffect, useState } from "react"
|
|||
import Archive from "@geist-ui/icons/archive"
|
||||
import Edit from "@geist-ui/icons/edit"
|
||||
import Parent from "@geist-ui/icons/arrowUpCircle"
|
||||
import FileDropdown from "@components/file-dropdown"
|
||||
import ScrollToTop from "@components/scroll-to-top"
|
||||
import FileDropdown from "app/(posts)/components/file-dropdown"
|
||||
import ScrollToTop from "app/components/scroll-to-top"
|
||||
import { useRouter } from "next/navigation"
|
||||
import ExpirationBadge from "@components/badges/expiration-badge"
|
||||
import CreatedAgoBadge from "@components/badges/created-ago-badge"
|
||||
import ExpirationBadge from "app/components/badges/expiration-badge"
|
||||
import CreatedAgoBadge from "app/components/badges/created-ago-badge"
|
||||
import PasswordModalPage from "./password-modal-wrapper"
|
||||
import VisibilityControl from "@components/badges/visibility-control"
|
||||
import VisibilityControl from "app/components/badges/visibility-control"
|
||||
import { File, PostWithFiles } from "@lib/server/prisma"
|
||||
import Header from "@components/header"
|
||||
import Header from "app/components/header"
|
||||
|
||||
type Props = {
|
||||
post: PostWithFiles
|
|
@ -14,8 +14,8 @@ import {
|
|||
Tooltip,
|
||||
Tag
|
||||
} from "@geist-ui/core/dist"
|
||||
import HtmlPreview from "@components/preview"
|
||||
import FadeIn from "@components/fade-in"
|
||||
import HtmlPreview from "app/(posts)/new/components/edit-document-list/edit-document/preview"
|
||||
import FadeIn from "app/components/fade-in"
|
||||
|
||||
// import Link from "next/link"
|
||||
type Props = {
|
|
@ -1,4 +1,4 @@
|
|||
import PageSeo from "@components/page-seo"
|
||||
import PageSeo from "app/components/page-seo"
|
||||
import { getPostById } from "@lib/server/prisma"
|
||||
|
||||
export default async function Head({
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import type { GetServerSideProps } from "next"
|
||||
|
||||
import type { Post } from "@lib/types"
|
||||
import PostPage from "@components/post-page"
|
||||
import PostPage from "app/(posts)/post/[id]/components/post-page"
|
||||
import { USER_COOKIE_NAME } from "@lib/constants"
|
||||
import { notFound } from "next/navigation"
|
||||
import { getPostById } from "@lib/server/prisma"
|
||||
import { getCurrentUser, getSession } from "@lib/server/session"
|
||||
import Header from "@components/header"
|
||||
import Header from "app/components/header"
|
||||
|
||||
export type PostProps = {
|
||||
post: Post
|
||||
|
|
|
@ -4,7 +4,7 @@ import byteToMB from "@lib/byte-to-mb"
|
|||
import { Post } from "@lib/types"
|
||||
import Table from "rc-table"
|
||||
import { useEffect, useMemo, useState } from "react"
|
||||
import { adminFetcher } from "."
|
||||
import { adminFetcher } from "./admin"
|
||||
import ActionDropdown from "./action-dropdown"
|
||||
|
||||
const PostTable = () => {
|
|
@ -1,7 +1,7 @@
|
|||
import { Fieldset, useToasts } from "@geist-ui/core/dist"
|
||||
import { User } from "@lib/types"
|
||||
import { useEffect, useMemo, useState } from "react"
|
||||
import { adminFetcher } from "."
|
||||
import { adminFetcher } from "./admin"
|
||||
import Table from "rc-table"
|
||||
import SettingsGroup from "@components/settings-group"
|
||||
import ActionDropdown from "./action-dropdown"
|
|
@ -1,8 +1,5 @@
|
|||
import Admin from "@components/admin"
|
||||
import { TOKEN_COOKIE_NAME } from "@lib/constants"
|
||||
import { isUserAdmin } from "@lib/server/prisma"
|
||||
import Admin from "./components/admin"
|
||||
import { getCurrentUser } from "@lib/server/session"
|
||||
import { cookies } from "next/headers"
|
||||
import { notFound } from "next/navigation"
|
||||
|
||||
const AdminPage = async () => {
|
||||
|
|
|
@ -27,6 +27,7 @@ import { useTheme } from "next-themes"
|
|||
// import useUserData from "@lib/hooks/use-user-data"
|
||||
import Link from "next/link"
|
||||
import { usePathname } from "next/navigation"
|
||||
import { signOut } from "next-auth/react"
|
||||
|
||||
type Tab = {
|
||||
name: string
|
||||
|
@ -99,7 +100,7 @@ const Header = ({ signedIn = false }) => {
|
|||
name: "sign out",
|
||||
icon: <SignOutIcon />,
|
||||
value: "signout",
|
||||
href: "/signout"
|
||||
onClick: () => signOut()
|
||||
},
|
||||
...defaultPages
|
||||
])
|
||||
|
@ -220,4 +221,4 @@ const Header = ({ signedIn = false }) => {
|
|||
)
|
||||
}
|
||||
|
||||
export default Header
|
||||
export default Header
|
|
@ -1,5 +1,5 @@
|
|||
"use client"
|
||||
import ShiftBy from "@components/shift-by"
|
||||
import ShiftBy from "app/components/shift-by"
|
||||
import { Spacer, Tabs, Card, Textarea, Text } from "@geist-ui/core/dist"
|
||||
import Image from "next/image"
|
||||
import styles from "./home.module.css"
|
|
@ -7,7 +7,7 @@ import ListItemSkeleton from "./list-item-skeleton"
|
|||
import ListItem from "./list-item"
|
||||
import { ChangeEvent, useCallback, useEffect, useState } from "react"
|
||||
import useDebounce from "@lib/hooks/use-debounce"
|
||||
import Link from "@components/link"
|
||||
import Link from "app/components/link"
|
||||
import { TOKEN_COOKIE_NAME } from "@lib/constants"
|
||||
import { getCookie } from "cookies-next"
|
||||
import type { PostWithFiles } from "@lib/server/prisma"
|
|
@ -7,15 +7,15 @@ import {
|
|||
Badge,
|
||||
Button
|
||||
} from "@geist-ui/core/dist"
|
||||
import FadeIn from "@components/fade-in"
|
||||
import FadeIn from "app/components/fade-in"
|
||||
import Trash from "@geist-ui/icons/trash"
|
||||
import ExpirationBadge from "@components/badges/expiration-badge"
|
||||
import CreatedAgoBadge from "@components/badges/created-ago-badge"
|
||||
import ExpirationBadge from "app/components/badges/expiration-badge"
|
||||
import CreatedAgoBadge from "app/components/badges/created-ago-badge"
|
||||
import Edit from "@geist-ui/icons/edit"
|
||||
import { useRouter } from "next/navigation"
|
||||
import Parent from "@geist-ui/icons/arrowUpCircle"
|
||||
import styles from "./list-item.module.css"
|
||||
import Link from "@components/link"
|
||||
import Link from "app/components/link"
|
||||
import type { PostWithFiles } from "@lib/server/prisma"
|
||||
import type { PostVisibility } from "@lib/types"
|
||||
import type { File } from "@lib/server/prisma"
|
||||
|
@ -40,10 +40,6 @@ const ListItem = ({
|
|||
router.push(`/post/${post.parentId}`)
|
||||
}
|
||||
|
||||
{
|
||||
console.log(post)
|
||||
}
|
||||
|
||||
return (
|
||||
<FadeIn>
|
||||
<li key={post.id}>
|
|
@ -1,4 +1,4 @@
|
|||
import PageSeo from "@components/page-seo"
|
||||
import PageSeo from "app/components/page-seo"
|
||||
|
||||
export default function Head() {
|
||||
return <PageSeo title="Drift - Your profile" isPrivate />
|
|
@ -1,8 +1,8 @@
|
|||
import { redirect } from "next/navigation"
|
||||
import { getPostsByUser } from "@lib/server/prisma"
|
||||
import PostList from "@components/post-list"
|
||||
import PostList from "app/components/post-list"
|
||||
import { getCurrentUser } from "@lib/server/session"
|
||||
import Header from "@components/header"
|
||||
import Header from "app/components/header"
|
||||
import { authOptions } from "@lib/server/auth"
|
||||
|
||||
export default async function Mine() {
|
|
@ -1,7 +1,7 @@
|
|||
import Header from "@components/header"
|
||||
import Header from "app/components/header"
|
||||
import { getCurrentUser } from "@lib/server/session"
|
||||
import { getWelcomeContent } from "pages/api/welcome"
|
||||
import Home from "./home"
|
||||
import Home from "./components/home"
|
||||
|
||||
const getWelcomeData = async () => {
|
||||
const welcomeContent = await getWelcomeContent()
|
||||
|
@ -11,7 +11,7 @@ const getWelcomeData = async () => {
|
|||
export default async function Page() {
|
||||
const { content, rendered, title } = await getWelcomeData()
|
||||
const authed = await getCurrentUser();
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<Header signedIn={Boolean(authed)}/>
|
|
@ -1,4 +1,4 @@
|
|||
import PageSeo from "@components/page-seo"
|
||||
import PageSeo from "app/components/page-seo"
|
||||
|
||||
export default function Head() {
|
||||
return <PageSeo title="Drift - Settings" isPrivate />
|
|
@ -1,7 +1,7 @@
|
|||
import Header from "@components/header"
|
||||
import SettingsGroup from "@components/settings-group"
|
||||
import Password from "@components/settings/sections/password"
|
||||
import Profile from "@components/settings/sections/profile"
|
||||
import Header from "app/components/header"
|
||||
import SettingsGroup from "./components/settings-group"
|
||||
import Password from "app/settings/components/sections/password"
|
||||
import Profile from "app/settings/components/sections/profile"
|
||||
import { authOptions } from "@lib/server/auth"
|
||||
import { getCurrentUser } from "@lib/server/session"
|
||||
import { redirect } from "next/navigation"
|
|
@ -1,66 +0,0 @@
|
|||
import Header from "@components/header"
|
||||
import { GeistProvider, CssBaseline, Themes, Page } from "@geist-ui/core/dist"
|
||||
import type { NextComponentType, NextPageContext } from "next"
|
||||
import { SkeletonTheme } from "react-loading-skeleton"
|
||||
|
||||
const App = ({
|
||||
Component,
|
||||
pageProps
|
||||
}: {
|
||||
Component: NextComponentType<NextPageContext, any, any>
|
||||
pageProps: any
|
||||
}) => {
|
||||
const skeletonBaseColor = "var(--light-gray)"
|
||||
const skeletonHighlightColor = "var(--lighter-gray)"
|
||||
|
||||
const customTheme = Themes.createFromLight({
|
||||
type: "custom",
|
||||
palette: {
|
||||
background: "var(--bg)",
|
||||
foreground: "var(--fg)",
|
||||
accents_1: "var(--lightest-gray)",
|
||||
accents_2: "var(--lighter-gray)",
|
||||
accents_3: "var(--light-gray)",
|
||||
accents_4: "var(--gray)",
|
||||
accents_5: "var(--darker-gray)",
|
||||
accents_6: "var(--darker-gray)",
|
||||
accents_7: "var(--darkest-gray)",
|
||||
accents_8: "var(--darkest-gray)",
|
||||
border: "var(--light-gray)",
|
||||
warning: "var(--warning)"
|
||||
},
|
||||
expressiveness: {
|
||||
dropdownBoxShadow: "0 0 0 1px var(--light-gray)",
|
||||
shadowSmall: "0 0 0 1px var(--light-gray)",
|
||||
shadowLarge: "0 0 0 1px var(--light-gray)",
|
||||
shadowMedium: "0 0 0 1px var(--light-gray)"
|
||||
},
|
||||
layout: {
|
||||
gap: "var(--gap)",
|
||||
gapHalf: "var(--gap-half)",
|
||||
gapQuarter: "var(--gap-quarter)",
|
||||
gapNegative: "var(--gap-negative)",
|
||||
gapHalfNegative: "var(--gap-half-negative)",
|
||||
gapQuarterNegative: "var(--gap-quarter-negative)",
|
||||
radius: "var(--radius)"
|
||||
},
|
||||
font: {
|
||||
mono: "var(--font-mono)",
|
||||
sans: "var(--font-sans)"
|
||||
}
|
||||
})
|
||||
return (
|
||||
<GeistProvider themes={[customTheme]} themeType={"custom"}>
|
||||
<SkeletonTheme
|
||||
baseColor={skeletonBaseColor}
|
||||
highlightColor={skeletonHighlightColor}
|
||||
>
|
||||
<CssBaseline />
|
||||
<Header />
|
||||
<Component {...pageProps} />
|
||||
</SkeletonTheme>
|
||||
</GeistProvider>
|
||||
)
|
||||
}
|
||||
|
||||
export default App
|
|
@ -1,14 +1,14 @@
|
|||
import { PrismaAdapter } from "@next-auth/prisma-adapter"
|
||||
import { NextAuthOptions } from "next-auth"
|
||||
import GitHubProvider from "next-auth/providers/github"
|
||||
import prisma from "lib/server/prisma"
|
||||
import prisma from "@lib/server/prisma"
|
||||
import config from "@lib/config"
|
||||
|
||||
const providers: NextAuthOptions["providers"] = [
|
||||
GitHubProvider({
|
||||
clientId: config.GITHUB_CLIENT_ID,
|
||||
clientSecret: config.GITHUB_CLIENT_SECRET
|
||||
}),
|
||||
})
|
||||
]
|
||||
|
||||
export const authOptions: NextAuthOptions = {
|
||||
|
@ -41,7 +41,7 @@ export const authOptions: NextAuthOptions = {
|
|||
})
|
||||
|
||||
if (!dbUser) {
|
||||
// TODO: user should be defined?
|
||||
// TODO: user should be defined? should we invalidate/signout?
|
||||
if (user) {
|
||||
token.id = user.id
|
||||
token.role = "user"
|
||||
|
@ -59,4 +59,3 @@ export const authOptions: NextAuthOptions = {
|
|||
}
|
||||
}
|
||||
} as const
|
||||
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
import config from "@lib/config"
|
||||
import { User } from "@prisma/client"
|
||||
import prisma from "@lib/server/prisma"
|
||||
import { sign } from "jsonwebtoken"
|
||||
|
||||
export async function generateAndExpireAccessToken(userId: User["id"]) {
|
||||
const token = sign({ id: userId }, config.jwt_secret, { expiresIn: "2d" })
|
||||
|
||||
await prisma.authTokens.create({
|
||||
data: {
|
||||
userId: userId,
|
||||
token: token
|
||||
}
|
||||
})
|
||||
|
||||
// TODO: set expiredReason?
|
||||
prisma.authTokens.deleteMany({
|
||||
where: {
|
||||
userId: userId,
|
||||
token: {
|
||||
not: token
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return token
|
||||
}
|
|
@ -4,8 +4,6 @@ declare global {
|
|||
|
||||
import config from "@lib/config"
|
||||
import { Post, PrismaClient, File, User } from "@prisma/client"
|
||||
import { cache } from "react"
|
||||
import { generateAndExpireAccessToken } from "./generate-access-token"
|
||||
|
||||
const prisma = new PrismaClient()
|
||||
|
||||
|
@ -140,23 +138,11 @@ export const createUser = async (
|
|||
throw new Error("Wrong registration password")
|
||||
}
|
||||
|
||||
// const salt = await genSalt(10)
|
||||
|
||||
// the first user is the admin
|
||||
const isUserAdminByDefault =
|
||||
config.enable_admin && (await prisma.user.count()) === 0
|
||||
const userRole = isUserAdminByDefault ? "admin" : "user"
|
||||
|
||||
// const user = await prisma.user.create({
|
||||
// data: {
|
||||
// username,
|
||||
// password: await bcrypt.hash(password, salt),
|
||||
// role: userRole,
|
||||
// },
|
||||
// })
|
||||
|
||||
// const token = await generateAndExpireAccessToken(user.id)
|
||||
|
||||
return {
|
||||
// user,
|
||||
// token
|
||||
|
|
|
@ -1,59 +0,0 @@
|
|||
import "@styles/globals.css"
|
||||
import type { AppProps as NextAppProps } from "next/app"
|
||||
|
||||
import "react-loading-skeleton/dist/skeleton.css"
|
||||
import Head from "next/head"
|
||||
import { ThemeProvider } from "next-themes"
|
||||
import App from "@components/app"
|
||||
import React from "react"
|
||||
|
||||
type AppProps<P = any> = {
|
||||
pageProps: P
|
||||
} & Omit<NextAppProps<P>, "pageProps">
|
||||
|
||||
function MyApp({ Component, pageProps }: AppProps) {
|
||||
return (
|
||||
<div>
|
||||
<Head>
|
||||
<meta charSet="utf-8" />
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width, initial-scale=1, shrink-to-fit=no"
|
||||
/>
|
||||
<link
|
||||
rel="apple-touch-icon"
|
||||
sizes="180x180"
|
||||
href="/assets/apple-touch-icon.png"
|
||||
/>
|
||||
<link
|
||||
rel="icon"
|
||||
type="image/png"
|
||||
sizes="32x32"
|
||||
href="/assets/favicon-32x32.png"
|
||||
/>
|
||||
<link
|
||||
rel="icon"
|
||||
type="image/png"
|
||||
sizes="16x16"
|
||||
href="/assets/favicon-16x16.png"
|
||||
/>
|
||||
<link rel="manifest" href="/site.webmanifest" />
|
||||
<link
|
||||
rel="mask-icon"
|
||||
href="/assets/safari-pinned-tab.svg"
|
||||
color="#5bbad5"
|
||||
/>
|
||||
<meta name="apple-mobile-web-app-title" content="Drift" />
|
||||
<meta name="application-name" content="Drift" />
|
||||
<meta name="msapplication-TileColor" content="#da532c" />
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
<title>Drift</title>
|
||||
</Head>
|
||||
<ThemeProvider defaultTheme="system" disableTransitionOnChange>
|
||||
<App Component={Component} pageProps={pageProps} />
|
||||
</ThemeProvider>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default MyApp
|
|
@ -1,39 +0,0 @@
|
|||
import { CssBaseline } from "@geist-ui/core/dist"
|
||||
import Document, {
|
||||
Html,
|
||||
Head,
|
||||
Main,
|
||||
NextScript,
|
||||
DocumentContext
|
||||
} from "next/document"
|
||||
|
||||
class MyDocument extends Document {
|
||||
static async getInitialProps(ctx: DocumentContext) {
|
||||
const initialProps = await Document.getInitialProps(ctx)
|
||||
const styles = CssBaseline.flush()
|
||||
|
||||
return {
|
||||
...initialProps,
|
||||
styles: (
|
||||
<>
|
||||
{initialProps.styles}
|
||||
{styles}
|
||||
</> // TODO: Investigate typescript
|
||||
) as any
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Html lang="en">
|
||||
<Head />
|
||||
<body>
|
||||
<Main />
|
||||
<NextScript />
|
||||
</body>
|
||||
</Html>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default MyDocument
|
|
@ -1,12 +0,0 @@
|
|||
import ErrorComponent from "@components/error"
|
||||
|
||||
function Error({ statusCode }: { statusCode: number }) {
|
||||
return <ErrorComponent status={statusCode} />
|
||||
}
|
||||
|
||||
Error.getInitialProps = ({ res, err }: { res: any; err: any }) => {
|
||||
const statusCode = res ? res.statusCode : err ? err.statusCode : 404
|
||||
return { statusCode }
|
||||
}
|
||||
|
||||
export default Error
|
|
@ -1,51 +0,0 @@
|
|||
import { NextApiRequest, NextApiResponse } from "next"
|
||||
import prisma from "@lib/server/prisma"
|
||||
import bcrypt from "bcrypt"
|
||||
import { signin } from "@lib/server/signin"
|
||||
import { setCookie } from "cookies-next"
|
||||
import { TOKEN_COOKIE_NAME, USER_COOKIE_NAME } from "@lib/constants"
|
||||
|
||||
export default async function handler(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse
|
||||
) {
|
||||
const { username, password } = req.body
|
||||
if (!username || !password) {
|
||||
return res.status(400).json({ error: "Missing param" })
|
||||
}
|
||||
|
||||
const user = await prisma.user.findFirst({
|
||||
where: {
|
||||
username
|
||||
}
|
||||
})
|
||||
|
||||
if (!user || !user.password) {
|
||||
return res.status(401).json({ error: "Unauthorized" })
|
||||
}
|
||||
|
||||
const isPasswordValid = await bcrypt.compare(password, user.password)
|
||||
if (!isPasswordValid) {
|
||||
return res.status(401).json({ error: "Unauthorized" })
|
||||
}
|
||||
|
||||
const token = await signin(user.id, req, res)
|
||||
setCookie(TOKEN_COOKIE_NAME, token, {
|
||||
path: "/",
|
||||
maxAge: 60 * 60 * 24 * 7, // 1 week
|
||||
httpOnly: true,
|
||||
secure: process.env.NODE_ENV === "production",
|
||||
req,
|
||||
res
|
||||
})
|
||||
setCookie(USER_COOKIE_NAME, user.id, {
|
||||
path: "/",
|
||||
maxAge: 60 * 60 * 24 * 7, // 1 week
|
||||
httpOnly: true,
|
||||
secure: process.env.NODE_ENV === "production",
|
||||
req,
|
||||
res
|
||||
})
|
||||
|
||||
return res.status(201).json({ token: token, userId: user.id })
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
import { NextApiRequest, NextApiResponse } from "next"
|
||||
import { createUser } from "@lib/server/prisma"
|
||||
|
||||
export default async function handler(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse
|
||||
) {
|
||||
const { username, password, serverPassword } = req.body
|
||||
const { user, token } = await createUser(username, password, serverPassword)
|
||||
|
||||
return res.status(201).json({ token: token, userId: user.id })
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
import { NextApiRequest, NextApiResponse } from "next"
|
||||
import prisma from "lib/server/prisma"
|
||||
import prisma from "@lib/server/prisma"
|
||||
import { parseQueryParam } from "@lib/server/parse-query-param"
|
||||
|
||||
const getRawFile = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
|
|
|
@ -9,10 +9,10 @@ import {
|
|||
import { authOptions } from "@lib/server/auth"
|
||||
import { CreatePostSchema } from "@lib/validations/post"
|
||||
import { Post } from "@prisma/client"
|
||||
import prisma, { getPostById } from "lib/server/prisma"
|
||||
import prisma, { getPostById } from "@lib/server/prisma"
|
||||
import { NextApiRequest, NextApiResponse } from "next"
|
||||
import { unstable_getServerSession } from "next-auth/next"
|
||||
import { File } from "lib/server/prisma"
|
||||
import { File } from "@lib/server/prisma"
|
||||
import * as crypto from "crypto"
|
||||
import { getHtmlFromFile } from "@lib/server/get-html-from-drift-file"
|
||||
import { getSession } from "next-auth/react"
|
||||
|
|
|
@ -113,7 +113,6 @@ model User {
|
|||
role String? @default("user")
|
||||
password String? @db.Text
|
||||
|
||||
|
||||
@@map("users")
|
||||
}
|
||||
|
||||
|
|
|
@ -39,13 +39,13 @@
|
|||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@components/*": [
|
||||
"components/*"
|
||||
"app/components/*"
|
||||
],
|
||||
"@lib/*": [
|
||||
"lib/*"
|
||||
],
|
||||
"@styles/*": [
|
||||
"styles/*"
|
||||
"app/styles/*"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
|
Loading…
Reference in a new issue