remove next-themes, convert header to custom button

This commit is contained in:
Max Leiter 2022-11-15 20:50:54 -08:00
parent bff7c90e5f
commit dfe0d39fa0
21 changed files with 281 additions and 160 deletions

View file

@ -36,6 +36,11 @@
color: var(--fg); color: var(--fg);
} }
/* when data-theme on html is light, change font color */
[data-theme="light"] .warning {
color: var(--bg);
}
.error { .error {
background-color: red; background-color: red;
} }

View file

@ -79,7 +79,7 @@ const ButtonDropdown: React.FC<
return ( return (
<div <div
className={`${styles.main} ${className}`} className={`${styles.main} ${className || ""}`}
onMouseDown={onMouseDown} onMouseDown={onMouseDown}
onMouseUp={onMouseUp} onMouseUp={onMouseUp}
onMouseLeave={onMouseLeave} onMouseLeave={onMouseLeave}

View file

@ -46,8 +46,13 @@
margin-left: var(--gap-half); margin-left: var(--gap-half);
} }
.iconLeft {
margin-right: var(--gap-half);
}
.icon svg { .icon svg {
display: block; display: block;
width: 100%; width: 100%;
height: 100%; height: 100%;
transform: scale(1.2) translateY(-0.05em);
} }

View file

@ -7,6 +7,7 @@ type Props = React.HTMLProps<HTMLButtonElement> & {
className?: string className?: string
onClick?: (e: React.MouseEvent<HTMLButtonElement>) => void onClick?: (e: React.MouseEvent<HTMLButtonElement>) => void
iconRight?: React.ReactNode iconRight?: React.ReactNode
iconLeft?: React.ReactNode
} }
// eslint-disable-next-line react/display-name // eslint-disable-next-line react/display-name
@ -20,6 +21,7 @@ const Button = forwardRef<HTMLButtonElement, Props>(
type = "button", type = "button",
disabled = false, disabled = false,
iconRight, iconRight,
iconLeft,
...props ...props
}, },
ref ref
@ -27,11 +29,16 @@ const Button = forwardRef<HTMLButtonElement, Props>(
return ( return (
<button <button
ref={ref} ref={ref}
className={`${styles.button} ${styles[type]} ${className}`} className={`${styles.button} ${styles[type]} ${className || ""}`}
disabled={disabled} disabled={disabled}
onClick={onClick} onClick={onClick}
{...props} {...props}
> >
{iconLeft && (
<span className={`${styles.icon} ${styles.iconLeft}`}>
{iconLeft}
</span>
)}
{children} {children}
{iconRight && ( {iconRight && (
<span className={`${styles.icon} ${styles.iconRight}`}> <span className={`${styles.icon} ${styles.iconRight}`}>

View file

@ -9,7 +9,7 @@ export default function Card({
className?: string className?: string
} & React.ComponentProps<"div">) { } & React.ComponentProps<"div">) {
return ( return (
<div className={`${styles.card} ${className}`} {...props}> <div className={`${styles.card} ${className || ""}`} {...props}>
<div className={styles.content}>{children}</div> <div className={styles.content}>{children}</div>
</div> </div>
) )

View file

@ -1,18 +1,14 @@
import React, { useEffect, useState } from "react" import React, { useEffect, useState } from "react"
import MoonIcon from "@geist-ui/icons/moon" import MoonIcon from "@geist-ui/icons/moon"
import SunIcon from "@geist-ui/icons/sun" import SunIcon from "@geist-ui/icons/sun"
// import { useAllThemes, useTheme } from '@geist-ui/core'
import styles from "./header.module.css" import styles from "./header.module.css"
import { Select } from "@geist-ui/core/dist" import { Select } from "@geist-ui/core/dist"
import { useTheme } from "next-themes" import { useTheme } from "@components/theme/ThemeClientContextProvider"
const Controls = () => { const Controls = () => {
const [mounted, setMounted] = useState(false) const { theme, setTheme } = useTheme()
const { resolvedTheme, setTheme } = useTheme()
useEffect(() => setMounted(true), [])
if (!mounted) return null
const switchThemes = () => { const switchThemes = () => {
if (resolvedTheme === "dark") { if (theme === "dark") {
setTheme("light") setTheme("light")
} else { } else {
setTheme("dark") setTheme("dark")
@ -26,7 +22,7 @@ const Controls = () => {
h="28px" h="28px"
pure pure
onChange={switchThemes} onChange={switchThemes}
value={resolvedTheme} value={theme}
> >
<Select.Option value="light"> <Select.Option value="light">
<span className={styles.selectContent}> <span className={styles.selectContent}>

View file

@ -11,20 +11,37 @@
align-items: center; align-items: center;
} }
.tabs .buttons > button, .tabs .buttons button {
.tabs .buttons > a > button {
border: none; border: none;
border-radius: 0; border-radius: 0;
cursor: pointer; cursor: pointer;
background: var(--bg);
} }
.tabs .active { .tabs .buttons > a:hover,
border-bottom: 1px solid var(--darker-gray) !important; .tabs .buttons > button:hover {
color: var(--fg);
box-shadow: inset 0 -1px 0 var(--fg);
transition: box-shadow 0.2s ease-in-out;
}
.tabs a:active,
.tabs a:focus,
.tabs button:active,
.tabs button:focus {
color: var(--darker-gray);
} }
.mobile { .mobile {
position: absolute; position: absolute;
z-index: 1000; z-index: 1000;
display: flex;
flex-direction: column;
}
.mobile button {
z-index: 1000;
width: 100%;
} }
.controls { .controls {

View file

@ -1,15 +1,12 @@
"use client" "use client"
import { import {
ButtonGroup,
Button,
Page, Page,
Spacer,
useBodyScroll, useBodyScroll,
useMediaQuery useMediaQuery
} from "@geist-ui/core/dist" } from "@geist-ui/core/dist"
import { useCallback, useEffect, useMemo, useState } from "react" import { useEffect, useState } from "react"
import styles from "./header.module.css" import styles from "./header.module.css"
import HomeIcon from "@geist-ui/icons/home" import HomeIcon from "@geist-ui/icons/home"
@ -23,11 +20,12 @@ import YourIcon from "@geist-ui/icons/list"
import MoonIcon from "@geist-ui/icons/moon" import MoonIcon from "@geist-ui/icons/moon"
import SettingsIcon from "@geist-ui/icons/settings" import SettingsIcon from "@geist-ui/icons/settings"
import SunIcon from "@geist-ui/icons/sun" import SunIcon from "@geist-ui/icons/sun"
import { useTheme } from "next-themes"
// import useUserData from "@lib/hooks/use-user-data" // import useUserData from "@lib/hooks/use-user-data"
import Link from "next/link" import Link from "next/link"
import { usePathname } from "next/navigation" import { usePathname } from "next/navigation"
import { signOut } from "next-auth/react" import { signOut } from "next-auth/react"
import { useTheme } from "@components/theme/ThemeClientContextProvider"
import Button from "@components/button"
type Tab = { type Tab = {
name: string name: string
@ -44,8 +42,7 @@ const Header = ({ signedIn = false, isAdmin = false }) => {
const isMobile = useMediaQuery("xs", { match: "down" }) const isMobile = useMediaQuery("xs", { match: "down" })
// const { status } = useSession() // const { status } = useSession()
// const signedIn = status === "authenticated" // const signedIn = status === "authenticated"
const { setTheme, resolvedTheme } = useTheme() const { setTheme, theme } = useTheme()
useEffect(() => { useEffect(() => {
setBodyHidden(expanded) setBodyHidden(expanded)
}, [expanded, setBodyHidden]) }, [expanded, setBodyHidden])
@ -68,16 +65,16 @@ const Header = ({ signedIn = false, isAdmin = false }) => {
name: isMobile ? "Change theme" : "", name: isMobile ? "Change theme" : "",
onClick: function () { onClick: function () {
if (typeof window !== "undefined") if (typeof window !== "undefined")
setTheme(resolvedTheme === "light" ? "dark" : "light") setTheme(theme === "light" ? "dark" : "light")
}, },
icon: resolvedTheme === "light" ? <MoonIcon /> : <SunIcon />, icon: theme === "light" ? <MoonIcon /> : <SunIcon />,
value: "theme" value: "theme"
} }
] ]
if (isAdmin) { if (isAdmin) {
defaultPages.push({ defaultPages.push({
name: "admin", name: "Admin",
icon: <SettingsIcon />, icon: <SettingsIcon />,
value: "admin", value: "admin",
href: "/admin" href: "/admin"
@ -87,25 +84,25 @@ const Header = ({ signedIn = false, isAdmin = false }) => {
if (signedIn) if (signedIn)
return [ return [
{ {
name: "new", name: "New",
icon: <NewIcon />, icon: <NewIcon />,
value: "new", value: "new",
href: "/new" href: "/new"
}, },
{ {
name: "yours", name: "Yours",
icon: <YourIcon />, icon: <YourIcon />,
value: "yours", value: "yours",
href: "/mine" href: "/mine"
}, },
{ {
name: "settings", name: "Settings",
icon: <SettingsIcon />, icon: <SettingsIcon />,
value: "settings", value: "settings",
href: "/settings" href: "/settings"
}, },
{ {
name: "sign out", name: "Sign Out",
icon: <SignOutIcon />, icon: <SignOutIcon />,
value: "signout", value: "signout",
onClick: () => signOut() onClick: () => signOut()
@ -115,7 +112,7 @@ const Header = ({ signedIn = false, isAdmin = false }) => {
else else
return [ return [
{ {
name: "home", name: "Home",
icon: <HomeIcon />, icon: <HomeIcon />,
value: "home", value: "home",
href: "/" href: "/"
@ -147,26 +144,29 @@ const Header = ({ signedIn = false, isAdmin = false }) => {
} }
const getButton = (tab: Tab) => { const getButton = (tab: Tab) => {
const activeStyle = pathname === tab.href ? styles.active : "" const isActive = pathname === tab.href
const activeStyle = isActive ? styles.active : ""
if (tab.onClick) { if (tab.onClick) {
return ( return (
<Button <Button
auto={isMobile ? false : true}
key={tab.value} key={tab.value}
icon={tab.icon} iconLeft={tab.icon}
onClick={() => onTabChange(tab.value)} onClick={() => onTabChange(tab.value)}
className={`${styles.tab} ${activeStyle}`} className={`${styles.tab} ${activeStyle}`}
shadow={false} aria-label={tab.name}
aria-current={isActive ? "page" : undefined}
> >
{tab.name ? tab.name : undefined} {tab.name ? tab.name : undefined}
</Button> </Button>
) )
} else if (tab.href) { } else if (tab.href) {
return ( return (
<Link key={tab.value} href={tab.href} className={styles.tab}> <Link
<Button auto={isMobile ? false : true} icon={tab.icon} shadow={false}> key={tab.value}
{tab.name ? tab.name : undefined} href={tab.href}
</Button> className={`${styles.tab} ${activeStyle}`}
>
<Button iconLeft={tab.icon}>{tab.name ? tab.name : undefined}</Button>
</Link> </Link>
) )
} }
@ -180,28 +180,14 @@ const Header = ({ signedIn = false, isAdmin = false }) => {
<div className={styles.buttons}>{buttons}</div> <div className={styles.buttons}>{buttons}</div>
</div> </div>
<div className={styles.controls}> <div className={styles.controls}>
<Button <Button onClick={() => setExpanded(!expanded)} aria-label="Menu">
effect={false}
auto
type="abort"
onClick={() => setExpanded(!expanded)}
aria-label="Menu"
>
<Spacer height={5 / 6} width={0} />
<MenuIcon /> <MenuIcon />
</Button> </Button>
</div> </div>
{/* setExpanded should occur elsewhere; we don't want to close if they change themes */} {/* setExpanded should occur elsewhere; we don't want to close if they change themes */}
{isMobile && expanded && ( {isMobile && expanded && (
<div className={styles.mobile} onClick={() => setExpanded(!expanded)}> <div className={styles.mobile} onClick={() => setExpanded(!expanded)}>
<ButtonGroup {buttons}
vertical
style={{
background: "var(--bg)"
}}
>
{buttons}
</ButtonGroup>
</div> </div>
)} )}
</Page.Header> </Page.Header>

View file

@ -0,0 +1,5 @@
import styles from "./page.module.css"
export default function Page({ children }: { children: React.ReactNode }) {
return <div className={styles.page}>{children}</div>
}

View file

@ -0,0 +1,10 @@
.page {
max-width: 100vw;
min-height: 100vh;
box-sizing: border-box;
position: relative;
width: 100%;
height: auto;
padding: 0 calc(1.34 * 16px) 0 calc(1.34 * 16px);
margin: 0 auto 0 auto;
}

View file

@ -1,5 +1,5 @@
'use client'; "use client"
import { Fieldset, Text, Divider } from "@geist-ui/core/dist" import Card from "@components/card"
import styles from "./settings-group.module.css" import styles from "./settings-group.module.css"
type Props = { type Props = {
@ -9,13 +9,11 @@ type Props = {
const SettingsGroup = ({ title, children }: Props) => { const SettingsGroup = ({ title, children }: Props) => {
return ( return (
<Fieldset width={'100%'}> <Card>
<Fieldset.Content> <h4>{title}</h4>
<Text h4>{title}</Text> <hr />
</Fieldset.Content> <div className={styles.content}>{children}</div>
<Divider /> </Card>
<Fieldset.Content className={styles.content}>{children}</Fieldset.Content>
</Fieldset>
) )
} }

View file

@ -0,0 +1,62 @@
"use client"
import {
FunctionComponent,
PropsWithChildren,
useCallback,
useMemo
} from "react"
import React, { useContext, useState, createContext } from "react"
import { DEFAULT_THEME, Theme, THEME_COOKIE_NAME } from "./theme"
import { setCookie } from "cookies-next"
interface UseThemeProps {
theme: Theme
setTheme: (theme: Theme) => void
}
const ThemeContext = createContext<UseThemeProps | null>(null)
export function useTheme(): {
theme: Theme
setTheme: (theme: Theme) => void
} {
return (
useContext(ThemeContext) || {
theme: DEFAULT_THEME,
setTheme: () => {}
}
)
}
interface Props extends PropsWithChildren<{}> {
defaultTheme: Theme
}
const ThemeClientContextProvider: FunctionComponent<Props> = ({
defaultTheme,
children
}) => {
const [theme, setThemeState] = useState<Theme>(defaultTheme)
const setCookieAndDocument = useCallback(
(theme: Theme) => {
setThemeState(theme)
setCookie(THEME_COOKIE_NAME, theme)
document.documentElement.setAttribute("data-theme", theme)
},
[setThemeState]
)
const setTheme = useCallback(
(theme: Theme) => {
setCookieAndDocument(theme)
},
[setCookieAndDocument]
)
const value = useMemo(() => ({ theme, setTheme }), [theme, setTheme])
return <ThemeContext.Provider value={value}>{children}</ThemeContext.Provider>
}
export default ThemeClientContextProvider

View file

@ -0,0 +1,26 @@
import type { 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;

View file

@ -0,0 +1,24 @@
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)?.value ?? DEFAULT_THEME;
return (
<ThemeContext.Provider value={theme}>{children}</ThemeContext.Provider>
);
};
export default ThemeServerContextProvider;

View file

@ -0,0 +1,5 @@
export type Theme = "light" | "dark";
export const DEFAULT_THEME: Theme = "light";
export const THEME_COOKIE_NAME = "drift-theme";

View file

@ -1,6 +1,4 @@
"use client" import Card from "@components/card"
import { Card } from "@geist-ui/core/dist"
import * as RadixTooltip from "@radix-ui/react-tooltip" import * as RadixTooltip from "@radix-ui/react-tooltip"
import "./tooltip.css" import "./tooltip.css"
@ -16,14 +14,12 @@ const Tooltip = ({
} & RadixTooltip.TooltipProps) => { } & RadixTooltip.TooltipProps) => {
return ( return (
<RadixTooltip.Root {...props}> <RadixTooltip.Root {...props}>
<RadixTooltip.Trigger asChild className={className}>{children}</RadixTooltip.Trigger> <RadixTooltip.Trigger asChild className={className}>
{children}
</RadixTooltip.Trigger>
<RadixTooltip.Content> <RadixTooltip.Content>
<Card className="tooltip"> <Card className="tooltip">{content}</Card>
<Card.Body margin={0} padding={1 / 2}>
{content}
</Card.Body>
</Card>
</RadixTooltip.Content> </RadixTooltip.Content>
</RadixTooltip.Root> </RadixTooltip.Root>
) )

View file

@ -1,9 +1,10 @@
import "@styles/globals.css" import "@styles/globals.css"
import { ServerThemeProvider } from "next-themes"
import { LayoutWrapper } from "./root-layout-wrapper" import { LayoutWrapper } from "./root-layout-wrapper"
import styles from '@styles/Home.module.css'; import styles from "@styles/Home.module.css"
import { cookies } from "next/headers"; import { getSession } from "@lib/server/session"
import { getSession } from "@lib/server/session"; import ThemeProvider from "@components/theme/ThemeProvider"
import { THEME_COOKIE_NAME } from "@components/theme/theme"
import { useServerTheme } from "@components/theme/ThemeServerContextProvider"
interface RootLayoutProps { interface RootLayoutProps {
children: React.ReactNode children: React.ReactNode
@ -13,19 +14,33 @@ export default async function RootLayout({ children }: RootLayoutProps) {
// TODO: this opts out of SSG // TODO: this opts out of SSG
const session = await getSession() const session = await getSession()
return ( return (
<ServerThemeProvider <html lang="en">
disableTransitionOnChange <head>
attribute="data-theme" <script
enableColorScheme dangerouslySetInnerHTML={{
> __html: `
<html lang="en"> (function() {
<head> var theme = document.cookie
.split('; ')
</head> .find(row => row.startsWith('${THEME_COOKIE_NAME}='))
.split('=')[1];
document.documentElement.setAttribute('data-theme', theme);
console.log("theme on load", theme)
})();
`,
}}
/>
</head>
<ThemeProvider>
<body className={styles.main}> <body className={styles.main}>
<LayoutWrapper signedIn={Boolean(session?.user)} isAdmin={session?.user.role === "admin"}>{children}</LayoutWrapper> <LayoutWrapper
signedIn={Boolean(session?.user)}
isAdmin={session?.user.role === "admin"}
>
{children}
</LayoutWrapper>
</body> </body>
</html> </ThemeProvider>
</ServerThemeProvider> </html>
) )
} }

View file

@ -1,73 +1,24 @@
"use client" "use client"
import Header from "@components/header" import Header from "@components/header"
import { CssBaseline, GeistProvider, Page, Themes } from "@geist-ui/core/dist" import Page from "@components/page"
import { ThemeProvider } from "next-themes"
import * as RadixTooltip from "@radix-ui/react-tooltip" import * as RadixTooltip from "@radix-ui/react-tooltip"
export function LayoutWrapper({ export function LayoutWrapper({
children, children,
signedIn, signedIn,
isAdmin, isAdmin
}: { }: {
children: React.ReactNode children: React.ReactNode
signedIn?: boolean signedIn?: boolean
isAdmin?: boolean isAdmin?: boolean
}) { }) {
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(--lighter-gray)",
shadowSmall: "0 0 0 1px var(--lighter-gray)",
shadowLarge: "0 0 0 1px var(--lighter-gray)",
shadowMedium: "0 0 0 1px var(--lighter-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 ( return (
<RadixTooltip.Provider delayDuration={200}> <RadixTooltip.Provider delayDuration={200}>
<GeistProvider themes={[customTheme]} themeType={"custom"}> <Page>
<ThemeProvider <Header isAdmin={isAdmin} signedIn={signedIn} />
disableTransitionOnChange {children}
cookieName="drift-theme" </Page>
attribute="data-theme"
>
<CssBaseline />
<Page width={"100%"}>
<Page.Header>
<Header isAdmin={isAdmin} signedIn={signedIn} />
</Page.Header>
{children}
</Page>
</ThemeProvider>
</GeistProvider>
</RadixTooltip.Provider> </RadixTooltip.Provider>
) )
} }

View file

@ -47,6 +47,7 @@
--border: var(--lighter-gray); --border: var(--lighter-gray);
--warning: rgb(27, 134, 23); --warning: rgb(27, 134, 23);
--link: #3291ff; --link: #3291ff;
color-scheme: dark;
} }
[data-theme="light"] { [data-theme="light"] {
@ -69,8 +70,10 @@
--header-bg: rgba(255, 255, 255, 0.8); --header-bg: rgba(255, 255, 255, 0.8);
--gray-alpha: rgba(19, 20, 21, 0.5); --gray-alpha: rgba(19, 20, 21, 0.5);
--selection: var(0, 0, 0, .6); --selection: var(0, 0, 0, .6);
color-scheme: light;
} }
* { * {
box-sizing: border-box; box-sizing: border-box;
} }
@ -96,7 +99,6 @@ body {
font-family: var(--font-sans); font-family: var(--font-sans);
display: flex; display: flex;
flex-direction: column; flex-direction: column;
/* TODO: this should be unnecessary. Overides the browser background for color-scheme while geist-ui catches up */
background: var(--bg); background: var(--bg);
} }
@ -131,6 +133,12 @@ code {
font-family: var(--font-mono) !important; font-family: var(--font-mono) !important;
} }
hr {
border: 0;
border-bottom: 1px solid var(--light-gray);
margin: var(--gap) 0;
}
@media print { @media print {
:root { :root {
--bg: #fff; --bg: #fff;
@ -166,3 +174,4 @@ main {
margin-top: 0 !important; margin-top: 0 !important;
padding-top: 0 !important; padding-top: 0 !important;
} }

View file

@ -27,7 +27,7 @@
"jest": "^29.3.1", "jest": "^29.3.1",
"next": "13.0.3", "next": "13.0.3",
"next-auth": "^4.16.4", "next-auth": "^4.16.4",
"next-themes": "npm:@wits/next-themes@0.2.7", "next-themes": "^0.2.1",
"rc-table": "7.24.1", "rc-table": "7.24.1",
"react": "18.2.0", "react": "18.2.0",
"react-datepicker": "4.8.0", "react-datepicker": "4.8.0",
@ -69,5 +69,9 @@
"components", "components",
"lib" "lib"
] ]
},
"overrides": {
"react": "18.2.0",
"react-dom": "18.2.0"
} }
} }

View file

@ -25,7 +25,7 @@ specifiers:
katex: ^0.16.3 katex: ^0.16.3
next: 13.0.3 next: 13.0.3
next-auth: ^4.16.4 next-auth: ^4.16.4
next-themes: npm:@wits/next-themes@0.2.7 next-themes: ^0.2.1
next-unused: 0.0.6 next-unused: 0.0.6
prettier: 2.6.2 prettier: 2.6.2
prisma: ^4.6.1 prisma: ^4.6.1
@ -58,7 +58,7 @@ dependencies:
jest: 29.3.1_@types+node@17.0.23 jest: 29.3.1_@types+node@17.0.23
next: 13.0.3_biqbaboplfbrettd7655fr4n2y next: 13.0.3_biqbaboplfbrettd7655fr4n2y
next-auth: 4.16.4_ogpkrxaz2lg6nectum6dl66tn4 next-auth: 4.16.4_ogpkrxaz2lg6nectum6dl66tn4
next-themes: /@wits/next-themes/0.2.7_ogpkrxaz2lg6nectum6dl66tn4 next-themes: 0.2.1_ogpkrxaz2lg6nectum6dl66tn4
rc-table: 7.24.1_biqbaboplfbrettd7655fr4n2y rc-table: 7.24.1_biqbaboplfbrettd7655fr4n2y
react: 18.2.0 react: 18.2.0
react-datepicker: 4.8.0_biqbaboplfbrettd7655fr4n2y react-datepicker: 4.8.0_biqbaboplfbrettd7655fr4n2y
@ -1594,18 +1594,6 @@ packages:
- supports-color - supports-color
dev: false dev: false
/@wits/next-themes/0.2.7_ogpkrxaz2lg6nectum6dl66tn4:
resolution: {integrity: sha512-CpmNH3RRqf2w0i1Xbrz5GKNE/d5gMq1oBlGpofY9LWcjH225nUgrxP15wKRITRAbn68ERDbsBGEBiaRECTmQag==}
peerDependencies:
next: '*'
react: '*'
react-dom: '*'
dependencies:
next: 13.0.3_biqbaboplfbrettd7655fr4n2y
react: 18.2.0
react-dom: 18.2.0_react@18.2.0
dev: false
/abbrev/1.1.1: /abbrev/1.1.1:
resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==}
dev: false dev: false
@ -5129,6 +5117,18 @@ packages:
uuid: 8.3.2 uuid: 8.3.2
dev: false dev: false
/next-themes/0.2.1_ogpkrxaz2lg6nectum6dl66tn4:
resolution: {integrity: sha512-B+AKNfYNIzh0vqQQKqQItTS8evEouKD7H5Hj3kmuPERwddR2TxvDSFZuTj6T7Jfn1oyeUyJMydPl1Bkxkh0W7A==}
peerDependencies:
next: '*'
react: '*'
react-dom: '*'
dependencies:
next: 13.0.3_biqbaboplfbrettd7655fr4n2y
react: 18.2.0
react-dom: 18.2.0_react@18.2.0
dev: false
/next-unused/0.0.6: /next-unused/0.0.6:
resolution: {integrity: sha512-dHFNNBanFq4wvYrULtsjfWyZ6BzOnr5VYI9EYMGAZYF2vkAhFpj2JOuT5Wu2o3LbFSG92PmAZnSUF/LstF82pA==} resolution: {integrity: sha512-dHFNNBanFq4wvYrULtsjfWyZ6BzOnr5VYI9EYMGAZYF2vkAhFpj2JOuT5Wu2o3LbFSG92PmAZnSUF/LstF82pA==}
hasBin: true hasBin: true