mirror of https://github.com/MaxLeiter/Drift
rework cookies
parent
9b9c3c1d87
commit
95d1ef31ef
@ -0,0 +1,25 @@
|
|||||||
|
import { USER_COOKIE_NAME, TOKEN_COOKIE_NAME } from "@lib/constants"
|
||||||
|
import { User } from "app/prisma"
|
||||||
|
import { setCookie } from "cookies-next"
|
||||||
|
import { NextApiRequest, NextApiResponse } from "next"
|
||||||
|
import { generateAndExpireAccessToken } from "./generate-access-token"
|
||||||
|
|
||||||
|
export const signin = async (
|
||||||
|
userId: User["id"],
|
||||||
|
req: NextApiRequest,
|
||||||
|
res: NextApiResponse
|
||||||
|
) => {
|
||||||
|
const token = await generateAndExpireAccessToken(userId)
|
||||||
|
setCookie(USER_COOKIE_NAME, userId, {
|
||||||
|
maxAge: 30 * 24 * 60 * 60, // 30 days,
|
||||||
|
req,
|
||||||
|
res
|
||||||
|
})
|
||||||
|
setCookie(TOKEN_COOKIE_NAME, token, {
|
||||||
|
maxAge: 30 * 24 * 60 * 60, // 30 days
|
||||||
|
req,
|
||||||
|
res
|
||||||
|
})
|
||||||
|
|
||||||
|
return token
|
||||||
|
}
|
||||||
@ -0,0 +1,60 @@
|
|||||||
|
"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;
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
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;
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
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;
|
||||||
Loading…
Reference in New Issue