mirror of https://github.com/MaxLeiter/Drift
cookies fixes, hook improvement, more porting
parent
95d1ef31ef
commit
cf7d89eb20
@ -1,67 +1,33 @@
|
||||
import styles from "@styles/Home.module.css"
|
||||
import NewPost from "@components/new-post"
|
||||
import PageSeo from "@components/page-seo"
|
||||
import { Page } from "@geist-ui/core/dist"
|
||||
import Head from "next/head"
|
||||
import { GetServerSideProps } from "next"
|
||||
import { Post } from "@lib/types"
|
||||
import cookie from "cookie"
|
||||
|
||||
|
||||
const NewFromExisting = async () => {
|
||||
return (
|
||||
// <Head>
|
||||
// {/* TODO: solve this. */}
|
||||
// {/* eslint-disable-next-line @next/next/no-css-tags */}
|
||||
// <link rel="stylesheet" href="/css/react-datepicker.css" />
|
||||
// </Head>
|
||||
<NewPost initialPost={post} newPostParent={parentId} />
|
||||
)
|
||||
import { useRouter } from "next/navigation"
|
||||
import { cookies } from "next/headers"
|
||||
import { TOKEN_COOKIE_NAME } from "@lib/constants"
|
||||
import { getPostWithFiles } from "app/prisma"
|
||||
import { useRedirectIfNotAuthed } from "@lib/server/hooks/use-redirect-if-not-authed"
|
||||
const NewFromExisting = async ({
|
||||
params
|
||||
}: {
|
||||
params: {
|
||||
id: string
|
||||
}
|
||||
}) => {
|
||||
const { id } = params
|
||||
const router = useRouter()
|
||||
const cookieList = cookies()
|
||||
useRedirectIfNotAuthed()
|
||||
const driftToken = cookieList.get(TOKEN_COOKIE_NAME)
|
||||
|
||||
if (!driftToken) {
|
||||
return router.push("/signin")
|
||||
}
|
||||
|
||||
if (!id) {
|
||||
return router.push("/new")
|
||||
}
|
||||
|
||||
const post = await getPostWithFiles(id)
|
||||
|
||||
return <NewPost initialPost={post} newPostParent={id} />
|
||||
}
|
||||
|
||||
// export const getServerSideProps: GetServerSideProps = async ({
|
||||
// req,
|
||||
// params
|
||||
// }) => {
|
||||
// const id = params?.id
|
||||
// const redirect = {
|
||||
// redirect: {
|
||||
// destination: "/new",
|
||||
// permanent: false
|
||||
// }
|
||||
// }
|
||||
|
||||
// if (!id) {
|
||||
// return redirect
|
||||
// }
|
||||
|
||||
// const driftToken = cookie.parse(req.headers.cookie || "")[`drift-token`]
|
||||
|
||||
// const post = await fetch(`${process.env.API_URL}/posts/${id}`, {
|
||||
// method: "GET",
|
||||
// headers: {
|
||||
// "Content-Type": "application/json",
|
||||
// Authorization: `Bearer ${driftToken}`,
|
||||
// "x-secret-key": process.env.SECRET_KEY || ""
|
||||
// }
|
||||
// })
|
||||
|
||||
// if (!post.ok) {
|
||||
// return redirect
|
||||
// }
|
||||
|
||||
// const data = await post.json()
|
||||
|
||||
// if (!data) {
|
||||
// return redirect
|
||||
// }
|
||||
|
||||
// return {
|
||||
// props: {
|
||||
// post: data,
|
||||
// parentId: id
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
export default NewFromExisting
|
||||
|
||||
@ -0,0 +1,4 @@
|
||||
export default function NewLayout({ children }: { children: React.ReactNode }) {
|
||||
// useRedirectIfNotAuthed()
|
||||
return <>{children}</>;
|
||||
}
|
||||
@ -1,10 +1,6 @@
|
||||
import NewPost from "@components/new-post"
|
||||
import '@styles/react-datepicker.css'
|
||||
|
||||
const New = () => {
|
||||
return (
|
||||
<NewPost />
|
||||
)
|
||||
}
|
||||
const New = () => <NewPost />
|
||||
|
||||
export default New
|
||||
|
||||
@ -0,0 +1,34 @@
|
||||
import styles from "@styles/Home.module.css"
|
||||
|
||||
import MyPosts from "@components/my-posts"
|
||||
import type { GetServerSideProps } from "next"
|
||||
import { Post } from "@lib/types"
|
||||
import { Page } from "@geist-ui/core/dist"
|
||||
import { getCookie } from "cookies-next"
|
||||
import { TOKEN_COOKIE_NAME } from "@lib/constants"
|
||||
import { useRouter } from "next/navigation"
|
||||
import { cookies } from "next/headers"
|
||||
export default function Mine() {
|
||||
const router = useRouter()
|
||||
const driftToken = cookies().get(TOKEN_COOKIE_NAME)
|
||||
if (!driftToken) {
|
||||
return router.push("/signin")
|
||||
}
|
||||
|
||||
// const posts = await fetch(process.env.API_URL + `/posts/mine`, {
|
||||
// method: "GET",
|
||||
// headers: {
|
||||
// "Content-Type": "application/json",
|
||||
// Authorization: `Bearer ${driftToken}`,
|
||||
// "x-secret-key": process.env.SECRET_KEY || ""
|
||||
// }
|
||||
// })
|
||||
|
||||
if (!posts.ok) {
|
||||
return router.push("/signin")
|
||||
}
|
||||
|
||||
const { posts, error, hasMore } = await posts.json()
|
||||
|
||||
return <MyPosts morePosts={hasMore} error={error} posts={posts} />
|
||||
}
|
||||
@ -1,60 +0,0 @@
|
||||
"use client";
|
||||
|
||||
import clsx from "clsx";
|
||||
import type {
|
||||
ChangeEventHandler,
|
||||
FunctionComponent,
|
||||
PropsWithChildren,
|
||||
} from "react";
|
||||
import Cookies from "js-cookie";
|
||||
import React, { useContext, useState, createContext } from "react";
|
||||
import { DEFAULT_THEME, Theme, THEME_COOKIE_NAME } from "./theme";
|
||||
|
||||
const ThemeContext = createContext<Theme | null>(null);
|
||||
|
||||
export function useTheme(): Theme {
|
||||
return useContext(ThemeContext);
|
||||
}
|
||||
|
||||
interface Props extends PropsWithChildren {
|
||||
defaultTheme: Theme;
|
||||
}
|
||||
|
||||
const ThemeClientContextProvider: FunctionComponent<Props> = ({
|
||||
defaultTheme,
|
||||
children,
|
||||
}) => {
|
||||
const [theme, setTheme] = useState<Theme>(defaultTheme);
|
||||
const onChange: ChangeEventHandler<HTMLSelectElement> = (e) => {
|
||||
const value = e.target.value as Theme;
|
||||
setTheme(value);
|
||||
|
||||
if (value === DEFAULT_THEME) {
|
||||
Cookies.remove(THEME_COOKIE_NAME);
|
||||
} else {
|
||||
Cookies.set(THEME_COOKIE_NAME, value);
|
||||
}
|
||||
};
|
||||
const onReset = () => {
|
||||
setTheme(DEFAULT_THEME);
|
||||
Cookies.remove(THEME_COOKIE_NAME);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={clsx(theme === "dark" && "dark")}>
|
||||
<div className="mb-2">
|
||||
<h2 className="mb-2 font-bold text-xl">Theme Switcher</h2>
|
||||
<select value={theme} onChange={onChange} className="mr-2 inline-block">
|
||||
<option value="light">Light</option>
|
||||
<option value="dark">Dark</option>
|
||||
</select>
|
||||
<button className="bg-gray-300 p-2" onClick={onReset}>
|
||||
Reset
|
||||
</button>
|
||||
</div>
|
||||
<ThemeContext.Provider value={theme}>{children}</ThemeContext.Provider>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ThemeClientContextProvider;
|
||||
@ -1,27 +0,0 @@
|
||||
import { FunctionComponent, PropsWithChildren } from "react";
|
||||
import ThemeClientContextProvider from "./ThemeClientContextProvider";
|
||||
import ThemeServerContextProvider, {
|
||||
useServerTheme,
|
||||
} from "./ThemeServerContextProvider";
|
||||
|
||||
const ThemeProviderWrapper: FunctionComponent<PropsWithChildren> = ({
|
||||
children,
|
||||
}) => {
|
||||
const theme = useServerTheme();
|
||||
|
||||
return (
|
||||
<ThemeClientContextProvider defaultTheme={theme}>
|
||||
{children}
|
||||
</ThemeClientContextProvider>
|
||||
);
|
||||
};
|
||||
|
||||
const ThemeProvider: FunctionComponent<PropsWithChildren> = ({ children }) => {
|
||||
return (
|
||||
<ThemeServerContextProvider>
|
||||
<ThemeProviderWrapper>{children}</ThemeProviderWrapper>
|
||||
</ThemeServerContextProvider>
|
||||
);
|
||||
};
|
||||
|
||||
export default ThemeProvider;
|
||||
@ -1,25 +0,0 @@
|
||||
import type { FunctionComponent, PropsWithChildren } from "react";
|
||||
// @ts-ignore -- createServerContext is not in @types/react atm
|
||||
import { useContext, createServerContext } from "react";
|
||||
import { cookies } from "next/headers";
|
||||
import { Theme, THEME_COOKIE_NAME } from "./theme";
|
||||
import { DEFAULT_THEME } from "./theme";
|
||||
|
||||
const ThemeContext = createServerContext<Theme | null>(null);
|
||||
|
||||
export function useServerTheme(): Theme {
|
||||
return useContext(ThemeContext);
|
||||
}
|
||||
|
||||
const ThemeServerContextProvider: FunctionComponent<PropsWithChildren> = ({
|
||||
children,
|
||||
}) => {
|
||||
const cookiesList = cookies();
|
||||
const theme = cookiesList.get(THEME_COOKIE_NAME) ?? DEFAULT_THEME;
|
||||
|
||||
return (
|
||||
<ThemeContext.Provider value={theme}>{children}</ThemeContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export default ThemeServerContextProvider;
|
||||
@ -0,0 +1,12 @@
|
||||
import { useRouter } from 'next/navigation'
|
||||
import { isSignedIn } from "../is-signed-in"
|
||||
|
||||
export const useRedirectIfNotAuthed = (to = '/signin') => {
|
||||
const router = useRouter();
|
||||
|
||||
const signedIn = isSignedIn();
|
||||
|
||||
if (!signedIn) {
|
||||
router.push(to);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,6 @@
|
||||
import { cookies } from "next/headers"
|
||||
|
||||
export const isSignedIn = () => {
|
||||
const cookieList = cookies()
|
||||
return cookieList.has("drift-token") && cookieList.has("drift-userid")
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
import prisma from "app/prisma"
|
||||
|
||||
export const getPostsByUser = async (userId: number) => {
|
||||
const posts = await prisma.post.findMany({
|
||||
where: {
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
return posts
|
||||
}
|
||||
@ -1,67 +0,0 @@
|
||||
import styles from "@styles/Home.module.css"
|
||||
|
||||
import Header from "@components/header"
|
||||
import MyPosts from "@components/my-posts"
|
||||
import cookie from "cookie"
|
||||
import type { GetServerSideProps } from "next"
|
||||
import { Post } from "@lib/types"
|
||||
import { Page } from "@geist-ui/core/dist"
|
||||
|
||||
const Home = ({
|
||||
morePosts,
|
||||
posts,
|
||||
error
|
||||
}: {
|
||||
morePosts: boolean
|
||||
posts: Post[]
|
||||
error: boolean
|
||||
}) => {
|
||||
return (
|
||||
<Page className={styles.wrapper}>
|
||||
<Page.Content className={styles.main}>
|
||||
<MyPosts morePosts={morePosts} error={error} posts={posts} />
|
||||
</Page.Content>
|
||||
</Page>
|
||||
)
|
||||
}
|
||||
// get server side props
|
||||
export const getServerSideProps: GetServerSideProps = async ({ req }) => {
|
||||
const driftToken = cookie.parse(req.headers.cookie || "")[`drift-token`]
|
||||
if (!driftToken) {
|
||||
return {
|
||||
redirect: {
|
||||
destination: "/",
|
||||
permanent: false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const posts = await fetch(process.env.API_URL + `/posts/mine`, {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Authorization: `Bearer ${driftToken}`,
|
||||
"x-secret-key": process.env.SECRET_KEY || ""
|
||||
}
|
||||
})
|
||||
|
||||
if (!posts.ok) {
|
||||
return {
|
||||
redirect: {
|
||||
destination: "/",
|
||||
permanent: false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const data = await posts.json()
|
||||
return {
|
||||
props: {
|
||||
posts: data.posts,
|
||||
error: posts.status !== 200,
|
||||
morePosts: data.hasMore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default Home
|
||||
Loading…
Reference in New Issue