bump next and deps, fix header buttons
This commit is contained in:
parent
5e4ecbb803
commit
dc11f8eb0c
14 changed files with 1001 additions and 924 deletions
|
@ -6,7 +6,6 @@ const nextConfig = {
|
||||||
experimental: {
|
experimental: {
|
||||||
// esmExternals: true,
|
// esmExternals: true,
|
||||||
appDir: true,
|
appDir: true,
|
||||||
serverComponentsExternalPackages: ["prisma", "@prisma/client"],
|
|
||||||
},
|
},
|
||||||
rewrites() {
|
rewrites() {
|
||||||
return [
|
return [
|
||||||
|
|
58
package.json
58
package.json
|
@ -13,73 +13,73 @@
|
||||||
"jest": "jest"
|
"jest": "jest"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@next-auth/prisma-adapter": "^1.0.5",
|
"@next-auth/prisma-adapter": "^1.0.6",
|
||||||
"@next/eslint-plugin-next": "^13.2.4",
|
"@next/eslint-plugin-next": "13.4.4-canary.0",
|
||||||
"@prisma/client": "^4.11.0",
|
"@prisma/client": "^4.14.1",
|
||||||
"@radix-ui/react-dialog": "^1.0.3",
|
"@radix-ui/react-dialog": "^1.0.3",
|
||||||
"@radix-ui/react-dropdown-menu": "^2.0.4",
|
"@radix-ui/react-dropdown-menu": "^2.0.4",
|
||||||
"@radix-ui/react-popover": "^1.0.5",
|
"@radix-ui/react-popover": "^1.0.5",
|
||||||
"@radix-ui/react-tabs": "^1.0.3",
|
"@radix-ui/react-tabs": "^1.0.3",
|
||||||
"@radix-ui/react-tooltip": "^1.0.5",
|
"@radix-ui/react-tooltip": "^1.0.5",
|
||||||
"@vercel/og": "^0.4.0",
|
"@vercel/og": "^0.5.2",
|
||||||
"client-only": "^0.0.1",
|
"client-only": "^0.0.1",
|
||||||
"client-zip": "2.3.0",
|
"client-zip": "2.3.1",
|
||||||
"cmdk": "^0.2.0",
|
"cmdk": "^0.2.0",
|
||||||
|
"date-fns": "^2.30.0",
|
||||||
"jest": "^29.5.0",
|
"jest": "^29.5.0",
|
||||||
"lodash.debounce": "^4.0.8",
|
"lodash.debounce": "^4.0.8",
|
||||||
"next": "^13.2.4",
|
"next": "13.4.4-canary.0",
|
||||||
"next-auth": "^4.20.1",
|
"next-auth": "^4.22.1",
|
||||||
"next-themes": "^0.2.1",
|
"next-themes": "^0.2.1",
|
||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
"react-cookie": "^4.1.1",
|
"react-cookie": "^4.1.1",
|
||||||
"react-datepicker": "4.10.0",
|
"react-datepicker": "4.11.0",
|
||||||
"react-dom": "18.2.0",
|
"react-dom": "18.2.0",
|
||||||
"react-dropzone": "14.2.3",
|
"react-dropzone": "14.2.3",
|
||||||
"react-error-boundary": "^3.1.4",
|
"react-error-boundary": "^4.0.4",
|
||||||
"react-feather": "^2.0.10",
|
"react-feather": "^2.0.10",
|
||||||
"react-hot-toast": "2.4.0",
|
"react-hot-toast": "2.4.1",
|
||||||
"server-only": "^0.0.1",
|
"server-only": "^0.0.1",
|
||||||
"swr": "^2.1.0",
|
"swr": "^2.1.5",
|
||||||
"textarea-markdown-editor": "1.0.4",
|
"textarea-markdown-editor": "1.0.4",
|
||||||
"ts-jest": "^29.0.5",
|
"ts-jest": "^29.1.0",
|
||||||
"uuid": "^9.0.0",
|
"uuid": "^9.0.0"
|
||||||
"zlib": "^1.0.5"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@next/bundle-analyzer": "13.2.4",
|
"@next/bundle-analyzer": "13.4.4-canary.0",
|
||||||
"@total-typescript/ts-reset": "^0.4.2",
|
"@total-typescript/ts-reset": "^0.4.2",
|
||||||
"@types/bcrypt": "^5.0.0",
|
"@types/bcrypt": "^5.0.0",
|
||||||
"@types/git-http-backend": "^1.0.1",
|
"@types/git-http-backend": "^1.0.1",
|
||||||
"@types/jest": "^29.4.1",
|
"@types/jest": "^29.4.1",
|
||||||
"@types/lodash.debounce": "^4.0.7",
|
"@types/lodash.debounce": "^4.0.7",
|
||||||
"@types/node": "18.15.3",
|
"@types/node": "18.15.11",
|
||||||
"@types/react": "18.0.28",
|
"@types/react": "18.0.35",
|
||||||
"@types/react-datepicker": "4.10.0",
|
"@types/react-datepicker": "4.10.0",
|
||||||
"@types/react-dom": "18.0.11",
|
"@types/react-dom": "18.0.11",
|
||||||
"@types/uuid": "^9.0.1",
|
"@types/uuid": "^9.0.1",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.55.0",
|
"@typescript-eslint/eslint-plugin": "^5.58.0",
|
||||||
"@typescript-eslint/parser": "^5.55.0",
|
"@typescript-eslint/parser": "^5.58.0",
|
||||||
"@wcj/markdown-to-html": "^2.2.1",
|
"@wcj/markdown-to-html": "^2.2.1",
|
||||||
"clsx": "^1.2.1",
|
"clsx": "^1.2.1",
|
||||||
"cross-env": "7.0.3",
|
"cross-env": "7.0.3",
|
||||||
"csstype": "^3.1.1",
|
"csstype": "^3.1.2",
|
||||||
"dotenv": "^16.0.3",
|
"dotenv": "^16.0.3",
|
||||||
"eslint": "8.36.0",
|
"eslint": "8.38.0",
|
||||||
"eslint-config-next": "13.2.4",
|
"eslint-config-next": "13.4.4-canary.0",
|
||||||
"jest-mock-extended": "^3.0.3",
|
"jest-mock-extended": "^3.0.3",
|
||||||
"next-unused": "0.0.6",
|
"next-unused": "0.0.6",
|
||||||
"postcss": "^8.4.21",
|
"postcss": "^8.4.21",
|
||||||
"postcss-flexbugs-fixes": "^5.0.2",
|
"postcss-flexbugs-fixes": "^5.0.2",
|
||||||
"postcss-hover-media-feature": "^1.0.2",
|
"postcss-hover-media-feature": "^1.0.2",
|
||||||
"postcss-nested": "^6.0.1",
|
"postcss-nested": "^6.0.1",
|
||||||
"postcss-preset-env": "^8.0.1",
|
"postcss-preset-env": "^8.4.1",
|
||||||
"prettier": "2.8.4",
|
"prettier": "2.8.7",
|
||||||
"prisma": "^4.11.0",
|
"prisma": "^4.12.0",
|
||||||
"typescript": "4.9.5",
|
"typescript": "5.0.4",
|
||||||
"typescript-plugin-css-modules": "4.2.3"
|
"typescript-plugin-css-modules": "5.0.1"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"sharp": "^0.31.3"
|
"sharp": "^0.32.0"
|
||||||
},
|
},
|
||||||
"next-unused": {
|
"next-unused": {
|
||||||
"alias": {
|
"alias": {
|
||||||
|
|
1652
pnpm-lock.yaml
1652
pnpm-lock.yaml
File diff suppressed because it is too large
Load diff
|
@ -191,7 +191,7 @@ const getProviderIcon = (provider: string) => {
|
||||||
switch (provider) {
|
switch (provider) {
|
||||||
case "github":
|
case "github":
|
||||||
return <GitHub />
|
return <GitHub />
|
||||||
case "keycloak":
|
case "keycloak":
|
||||||
return <Key />
|
return <Key />
|
||||||
default:
|
default:
|
||||||
return <User />
|
return <User />
|
||||||
|
|
|
@ -17,9 +17,12 @@ import Input from "@components/input"
|
||||||
import ButtonDropdown from "@components/button-dropdown"
|
import ButtonDropdown from "@components/button-dropdown"
|
||||||
import { useToasts } from "@components/toasts"
|
import { useToasts } from "@components/toasts"
|
||||||
import { fetchWithUser } from "src/app/lib/fetch-with-user"
|
import { fetchWithUser } from "src/app/lib/fetch-with-user"
|
||||||
|
import "./react-datepicker.css"
|
||||||
import dynamic from "next/dynamic"
|
import dynamic from "next/dynamic"
|
||||||
const DatePicker = dynamic(() => import("react-datepicker"))
|
|
||||||
|
const DatePicker = dynamic(() => import("react-datepicker"), {
|
||||||
|
ssr: false
|
||||||
|
})
|
||||||
|
|
||||||
const emptyDoc = {
|
const emptyDoc = {
|
||||||
title: "",
|
title: "",
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import { getMetadata } from "src/app/lib/metadata"
|
import { getMetadata } from "src/app/lib/metadata"
|
||||||
import NewPost from "src/app/(drift)/(posts)/new/components/new"
|
import NewPost from "src/app/(drift)/(posts)/new/components/new"
|
||||||
import "./react-datepicker.css"
|
|
||||||
|
|
||||||
export default function New() {
|
export default function New() {
|
||||||
return <NewPost />
|
return <NewPost />
|
||||||
|
|
|
@ -39,7 +39,7 @@ const ExpirationBadge = ({
|
||||||
if (!expirationDate) {
|
if (!expirationDate) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
const isExpired = expirationDate < new Date()
|
const isExpired = expirationDate < new Date()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
"use client"
|
"use client"
|
||||||
|
|
||||||
import Button from "@components/button"
|
import Button from "@components/button"
|
||||||
|
import Link from "@components/link"
|
||||||
import Note from "@components/note"
|
import Note from "@components/note"
|
||||||
import { useRouter } from "next/navigation"
|
import { useRouter } from "next/navigation"
|
||||||
// an error fallback for react-error-boundary
|
// an error fallback for react-error-boundary
|
||||||
|
@ -16,6 +17,9 @@ function ErrorFallback({ error, resetErrorBoundary }: FallbackProps) {
|
||||||
<Note type="error" style={{ width: "100%" }}>
|
<Note type="error" style={{ width: "100%" }}>
|
||||||
<h3>Something went wrong:</h3>
|
<h3>Something went wrong:</h3>
|
||||||
<pre>{error.message}</pre>
|
<pre>{error.message}</pre>
|
||||||
|
<Link href="https://github.com/MaxLeiter/Drift/issues/new">
|
||||||
|
<Button>Report an issue</Button>
|
||||||
|
</Link>
|
||||||
<Button onClick={resetErrorBoundary}>Try again</Button>
|
<Button onClick={resetErrorBoundary}>Try again</Button>
|
||||||
</Note>
|
</Note>
|
||||||
)
|
)
|
||||||
|
|
|
@ -46,15 +46,17 @@ export function HeaderButtons({
|
||||||
theme: string
|
theme: string
|
||||||
}) {
|
}) {
|
||||||
const { isAdmin, userId } = useSessionSWR()
|
const { isAdmin, userId } = useSessionSWR()
|
||||||
const { resolvedTheme } = useTheme();
|
const { resolvedTheme } = useTheme()
|
||||||
return <>
|
return (
|
||||||
{getButtons({
|
<>
|
||||||
isAuthenticated,
|
{getButtons({
|
||||||
theme: resolvedTheme ? resolvedTheme : initialTheme,
|
isAuthenticated,
|
||||||
isAdmin,
|
theme: resolvedTheme ? resolvedTheme : initialTheme,
|
||||||
userId
|
isAdmin,
|
||||||
})}
|
userId
|
||||||
</>
|
})}
|
||||||
|
</>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function NavButton(tab: Tab) {
|
function NavButton(tab: Tab) {
|
||||||
|
@ -102,86 +104,83 @@ function ThemeButton({ theme }: { theme: string }) {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** For use by mobile */
|
|
||||||
export function getButtons({
|
export function getButtons({
|
||||||
isAuthenticated,
|
isAuthenticated,
|
||||||
theme,
|
theme,
|
||||||
// mutate: mutateSession,
|
|
||||||
isAdmin,
|
isAdmin,
|
||||||
userId
|
userId
|
||||||
}: {
|
}: {
|
||||||
isAuthenticated: boolean
|
isAuthenticated: boolean
|
||||||
theme: string
|
theme: string
|
||||||
// mutate: KeyedMutator<Session>
|
isAdmin?: boolean
|
||||||
isAdmin?: boolean,
|
|
||||||
userId?: string
|
userId?: string
|
||||||
}) {
|
}) {
|
||||||
return [
|
return (
|
||||||
<NavButton
|
<>
|
||||||
key="home"
|
|
||||||
name="Home"
|
|
||||||
icon={<Home />}
|
|
||||||
value="home"
|
|
||||||
href="/home"
|
|
||||||
/>,
|
|
||||||
<NavButton
|
|
||||||
key="new"
|
|
||||||
name="New"
|
|
||||||
icon={<PlusCircle />}
|
|
||||||
value="new"
|
|
||||||
href="/new"
|
|
||||||
/>,
|
|
||||||
<NavButton
|
|
||||||
key="yours"
|
|
||||||
name="Yours"
|
|
||||||
icon={<User />}
|
|
||||||
value="mine"
|
|
||||||
href="/mine"
|
|
||||||
/>,
|
|
||||||
<NavButton
|
|
||||||
name="Settings"
|
|
||||||
icon={<Settings />}
|
|
||||||
value="settings"
|
|
||||||
href="/settings"
|
|
||||||
key="settings"
|
|
||||||
/>,
|
|
||||||
<ThemeButton key="theme-button" theme={theme} />,
|
|
||||||
isAdmin ? (
|
|
||||||
<FadeIn>
|
|
||||||
<NavButton
|
|
||||||
name="Admin"
|
|
||||||
key="admin"
|
|
||||||
icon={<Settings />}
|
|
||||||
value="admin"
|
|
||||||
href="/admin"
|
|
||||||
/>
|
|
||||||
</FadeIn>
|
|
||||||
) : undefined,
|
|
||||||
isAuthenticated === true ? (
|
|
||||||
<NavButton
|
<NavButton
|
||||||
name="Sign Out"
|
key="home"
|
||||||
key="signout"
|
name="Home"
|
||||||
icon={<UserX />}
|
icon={<Home />}
|
||||||
value="signout"
|
value="home"
|
||||||
onClick={() => {
|
href="/home"
|
||||||
signOut({
|
|
||||||
callbackUrl: `/signedout${
|
|
||||||
userId ? "?userId=" + userId : ""
|
|
||||||
}`
|
|
||||||
})
|
|
||||||
}}
|
|
||||||
width={SIGN_IN_WIDTH}
|
|
||||||
/>
|
/>
|
||||||
) : undefined,
|
|
||||||
isAuthenticated === false ? (
|
|
||||||
<NavButton
|
<NavButton
|
||||||
name="Sign In"
|
key="new"
|
||||||
key="signin"
|
name="New"
|
||||||
|
icon={<PlusCircle />}
|
||||||
|
value="new"
|
||||||
|
href="/new"
|
||||||
|
/>
|
||||||
|
<NavButton
|
||||||
|
key="yours"
|
||||||
|
name="Yours"
|
||||||
icon={<User />}
|
icon={<User />}
|
||||||
value="signin"
|
value="mine"
|
||||||
href="/signin"
|
href="/mine"
|
||||||
width={SIGN_IN_WIDTH}
|
|
||||||
/>
|
/>
|
||||||
) : undefined
|
<NavButton
|
||||||
].filter(Boolean)
|
name="Settings"
|
||||||
|
icon={<Settings />}
|
||||||
|
value="settings"
|
||||||
|
href="/settings"
|
||||||
|
key="settings"
|
||||||
|
/>
|
||||||
|
<ThemeButton key="theme-button" theme={theme} />
|
||||||
|
{isAdmin && (
|
||||||
|
<FadeIn>
|
||||||
|
<NavButton
|
||||||
|
name="Admin"
|
||||||
|
key="admin"
|
||||||
|
icon={<Settings />}
|
||||||
|
value="admin"
|
||||||
|
href="/admin"
|
||||||
|
/>
|
||||||
|
</FadeIn>
|
||||||
|
)}
|
||||||
|
{isAuthenticated === true && (
|
||||||
|
<NavButton
|
||||||
|
name="Sign Out"
|
||||||
|
key="signout"
|
||||||
|
icon={<UserX />}
|
||||||
|
value="signout"
|
||||||
|
onClick={() => {
|
||||||
|
signOut({
|
||||||
|
callbackUrl: `/signedout${userId ? "?userId=" + userId : ""}`
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
width={SIGN_IN_WIDTH}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{isAuthenticated === false && (
|
||||||
|
<NavButton
|
||||||
|
name="Sign In"
|
||||||
|
key="signin"
|
||||||
|
icon={<User />}
|
||||||
|
value="signin"
|
||||||
|
href="/signin"
|
||||||
|
width={SIGN_IN_WIDTH}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@ export default function MobileHeader({
|
||||||
</DropdownMenu.Trigger>
|
</DropdownMenu.Trigger>
|
||||||
<DropdownMenu.Portal>
|
<DropdownMenu.Portal>
|
||||||
<DropdownMenu.Content>
|
<DropdownMenu.Content>
|
||||||
{buttons.map((button) => (
|
{buttons.props.children.map((button: JSX.Element) => (
|
||||||
<DropdownMenu.Item
|
<DropdownMenu.Item
|
||||||
key={`mobile-${button?.key}`}
|
key={`mobile-${button?.key}`}
|
||||||
className={styles.dropdownItem}
|
className={styles.dropdownItem}
|
||||||
|
|
|
@ -132,6 +132,7 @@ const PostList = ({
|
||||||
})}
|
})}
|
||||||
</ul>
|
</ul>
|
||||||
) : null}
|
) : null}
|
||||||
|
{!showSkeleton && posts && posts.length === 0 && <NoPostsFound />}
|
||||||
</Stack>
|
</Stack>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,6 @@ import {
|
||||||
File as ServerFile
|
File as ServerFile
|
||||||
} from "@prisma/client"
|
} from "@prisma/client"
|
||||||
import * as crypto from "crypto"
|
import * as crypto from "crypto"
|
||||||
import { cache } from "react"
|
|
||||||
export type {
|
export type {
|
||||||
User as ServerUser,
|
User as ServerUser,
|
||||||
File as ServerFile,
|
File as ServerFile,
|
||||||
|
@ -258,29 +257,28 @@ type GetPostByIdOptions = Pick<
|
||||||
"include" | "rejectOnNotFound" | "select"
|
"include" | "rejectOnNotFound" | "select"
|
||||||
>
|
>
|
||||||
|
|
||||||
export const getPostById = cache(
|
export const getPostById = async (
|
||||||
async (postId: ServerPost["id"], options?: GetPostByIdOptions) => {
|
postId: ServerPost["id"],
|
||||||
const post = await prisma.post.findUnique({
|
options?: GetPostByIdOptions
|
||||||
where: {
|
) => {
|
||||||
id: postId
|
const post = await prisma.post.findUnique({
|
||||||
},
|
where: {
|
||||||
...options
|
id: postId
|
||||||
})
|
},
|
||||||
|
...options
|
||||||
|
})
|
||||||
|
|
||||||
return post
|
return post
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
export const getAllPosts = cache(
|
export const getAllPosts = async (
|
||||||
async (
|
options?: Prisma.PostFindManyArgs
|
||||||
options?: Prisma.PostFindManyArgs
|
): Promise<
|
||||||
): Promise<
|
ServerPost[] | ServerPostWithFiles[] | ServerPostWithFilesAndAuthor[]
|
||||||
ServerPost[] | ServerPostWithFiles[] | ServerPostWithFilesAndAuthor[]
|
> => {
|
||||||
> => {
|
const posts = await prisma.post.findMany(options)
|
||||||
const posts = await prisma.post.findMany(options)
|
return posts
|
||||||
return posts
|
}
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
export const userWithPosts = Prisma.validator<Prisma.UserArgs>()({
|
export const userWithPosts = Prisma.validator<Prisma.UserArgs>()({
|
||||||
include: {
|
include: {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
generator client {
|
generator client {
|
||||||
provider = "prisma-client-js"
|
provider = "prisma-client-js"
|
||||||
previewFeatures = ["fullTextSearch"]
|
previewFeatures = ["fullTextSearch", "jsonProtocol"]
|
||||||
}
|
}
|
||||||
|
|
||||||
datasource db {
|
datasource db {
|
||||||
|
|
Loading…
Reference in a new issue