bump next and deps, fix header buttons

This commit is contained in:
Max Leiter 2023-05-20 15:16:50 -07:00
parent 5e4ecbb803
commit dc11f8eb0c
14 changed files with 1001 additions and 924 deletions

View file

@ -6,7 +6,6 @@ const nextConfig = {
experimental: { experimental: {
// esmExternals: true, // esmExternals: true,
appDir: true, appDir: true,
serverComponentsExternalPackages: ["prisma", "@prisma/client"],
}, },
rewrites() { rewrites() {
return [ return [

View file

@ -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": {

File diff suppressed because it is too large Load diff

View file

@ -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 />

View file

@ -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: "",

View file

@ -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 />

View file

@ -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 (

View file

@ -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>
) )

View file

@ -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}
/>
)}
</>
)
} }

View file

@ -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}

View file

@ -132,6 +132,7 @@ const PostList = ({
})} })}
</ul> </ul>
) : null} ) : null}
{!showSkeleton && posts && posts.length === 0 && <NoPostsFound />}
</Stack> </Stack>
) )
} }

View file

@ -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: {

View file

@ -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 {