Rework #6
@ -12,12 +12,17 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@radix-ui/react-icons": "^1.3.0",
|
||||
"@radix-ui/react-slot": "^1.0.2",
|
||||
"@radix-ui/react-tooltip": "^1.0.7",
|
||||
"class-variance-authority": "^0.7.0",
|
||||
"clsx": "^2.1.0",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-resizable-panels": "^2.0.16",
|
||||
"swr": "^2.2.5",
|
||||
"tailwind-merge": "^2.2.2",
|
||||
"tailwindcss-animate": "^1.0.7"
|
||||
"tailwindcss-animate": "^1.0.7",
|
||||
"wouter": "^3.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": ">=20.0.0",
|
||||
|
@ -0,0 +1,13 @@
|
||||
@import url('https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@100..900&display=swap');
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: "Noto Sans KR", sans-serif;
|
||||
font-optical-sizing: auto;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
#root {
|
||||
margin: 0;
|
||||
min-height: 100vh;
|
||||
}
|
@ -1,59 +1,44 @@
|
||||
import { Route, Switch, Redirect } from "wouter";
|
||||
|
||||
import './App.css'
|
||||
// import React, { createContext, useEffect, useRef, useState } from "react";
|
||||
// import ReactDom from "react-dom";
|
||||
// import { BrowserRouter, Navigate, Route, Routes } from "react-router-dom";
|
||||
|
||||
// import {
|
||||
// DifferencePage,
|
||||
// DocumentAbout,
|
||||
// Gallery,
|
||||
// LoginPage,
|
||||
// NotFoundPage,
|
||||
// ProfilePage,
|
||||
// ReaderPage,
|
||||
// SettingPage,
|
||||
// TagsPage,
|
||||
// // DifferencePage,
|
||||
// // DocumentAbout,
|
||||
// // Gallery,
|
||||
// // LoginPage,
|
||||
// // NotFoundPage,
|
||||
// // ProfilePage,
|
||||
// // ReaderPage,
|
||||
// // SettingPage,
|
||||
// // TagsPage,
|
||||
// } from "./page/mod";
|
||||
// import { getInitialValue, UserContext } from "./state";
|
||||
|
||||
import { TooltipProvider } from "./components/ui/tooltip";
|
||||
|
||||
import Gallery from "./page/galleryPage";
|
||||
import Layout from "./components/layout/layout";
|
||||
import NotFoundPage from "./page/404";
|
||||
|
||||
const App = () => {
|
||||
// const [user, setUser] = useState("");
|
||||
// const [userPermission, setUserPermission] = useState<string[]>([]);
|
||||
// (async () => {
|
||||
// const { username, permission } = await getInitialValue();
|
||||
// if (username !== user) {
|
||||
// setUser(username);
|
||||
// setUserPermission(permission);
|
||||
// }
|
||||
// })();
|
||||
// useEffect(()=>{});
|
||||
return ( <h1 className="text-3xl font-bold underline">
|
||||
Hello world!
|
||||
</h1>
|
||||
// <UserContext.Provider
|
||||
// value={{
|
||||
// username: user,
|
||||
// setUsername: setUser,
|
||||
// permission: userPermission,
|
||||
// setPermission: setUserPermission,
|
||||
// }}
|
||||
// >
|
||||
// <BrowserRouter>
|
||||
// <Routes>
|
||||
// <Route path="/" element={<Navigate replace to="/search?" />} />
|
||||
// <Route path="/search" element={<Gallery />} />
|
||||
// <Route path="/doc/:id" element={<DocumentAbout />}></Route>
|
||||
// <Route path="/doc/:id/reader" element={<ReaderPage />}></Route>
|
||||
// <Route path="/login" element={<LoginPage></LoginPage>} />
|
||||
// <Route path="/profile" element={<ProfilePage />}></Route>
|
||||
// <Route path="/difference" element={<DifferencePage />}></Route>
|
||||
// <Route path="/setting" element={<SettingPage />}></Route>
|
||||
// <Route path="/tags" element={<TagsPage />}></Route>
|
||||
// <Route path="*" element={<NotFoundPage />} />
|
||||
// </Routes>
|
||||
// </BrowserRouter>
|
||||
// </UserContext.Provider>
|
||||
);
|
||||
return (
|
||||
<TooltipProvider>
|
||||
|
||||
<Layout>
|
||||
<Switch>
|
||||
<Route path="/" component={() => <Redirect replace to="/search?" />} />
|
||||
<Route path="/search" component={Gallery} />
|
||||
{/* <Route path="/doc/:id" component={<DocumentAbout />}></Route>
|
||||
<Route path="/doc/:id/reader" component={<ReaderPage />}></Route>
|
||||
<Route path="/login" component={<LoginPage></LoginPage>} />
|
||||
<Route path="/profile" component={<ProfilePage />}></Route>
|
||||
<Route path="/difference" component={<DifferencePage />}></Route>
|
||||
<Route path="/setting" component={<SettingPage />}></Route>
|
||||
<Route path="/tags" component={<TagsPage />}></Route>*/}
|
||||
<Route component={NotFoundPage} />
|
||||
</Switch>
|
||||
</Layout>
|
||||
</TooltipProvider>);
|
||||
};
|
||||
|
||||
export default App
|
||||
|
50
packages/client/src/components/layout/layout.tsx
Normal file
50
packages/client/src/components/layout/layout.tsx
Normal file
@ -0,0 +1,50 @@
|
||||
import { useLayoutEffect, useState } from "react";
|
||||
import { ResizablePanelGroup, ResizablePanel, ResizableHandle } from "../ui/resizable";
|
||||
import { NavList } from "./nav";
|
||||
|
||||
|
||||
interface LayoutProps {
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
|
||||
export default function Layout({ children }: LayoutProps) {
|
||||
const MIN_SIZE_IN_PIXELS = 70;
|
||||
const [minSize, setMinSize] = useState(MIN_SIZE_IN_PIXELS);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
const panelGroup = document.querySelector('[data-panel-group-id="main"]');
|
||||
const resizeHandles = document.querySelectorAll(
|
||||
"[data-panel-resize-handle-id]"
|
||||
);
|
||||
if (!panelGroup || !resizeHandles) return;
|
||||
console.log(panelGroup, resizeHandles);
|
||||
const observer = new ResizeObserver(() => {
|
||||
let width = panelGroup?.clientWidth;
|
||||
if (!width) return;
|
||||
width -= [...resizeHandles].reduce((acc, resizeHandle) => acc + resizeHandle.clientWidth, 0);
|
||||
// Minimum size in pixels is a percentage of the PanelGroup's height,
|
||||
// less the (fixed) height of the resize handles.
|
||||
setMinSize((MIN_SIZE_IN_PIXELS / width) * 100);
|
||||
});
|
||||
observer.observe(panelGroup);
|
||||
for (const resizeHandle of resizeHandles) {
|
||||
observer.observe(resizeHandle);
|
||||
}
|
||||
|
||||
return () => {
|
||||
observer.disconnect();
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<ResizablePanelGroup direction="horizontal" id="main">
|
||||
<ResizablePanel minSize={minSize} collapsible maxSize={minSize}>
|
||||
<NavList />
|
||||
</ResizablePanel>
|
||||
<ResizableHandle withHandle />
|
||||
<ResizablePanel>
|
||||
{children}
|
||||
</ResizablePanel>
|
||||
</ResizablePanelGroup>
|
||||
);
|
||||
}
|
43
packages/client/src/components/layout/nav.tsx
Normal file
43
packages/client/src/components/layout/nav.tsx
Normal file
@ -0,0 +1,43 @@
|
||||
import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/tooltip"
|
||||
import { Link } from "wouter"
|
||||
import { MagnifyingGlassIcon, GearIcon, ActivityLogIcon, ArchiveIcon, PersonIcon } from "@radix-ui/react-icons"
|
||||
import { buttonVariants } from "../ui/button"
|
||||
|
||||
interface NavItemProps {
|
||||
icon: React.ReactNode;
|
||||
to: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export function NavItem({
|
||||
icon,
|
||||
to,
|
||||
name
|
||||
}: NavItemProps) {
|
||||
return <Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Link
|
||||
href={to}
|
||||
className={buttonVariants({ variant: "ghost" })}
|
||||
>
|
||||
{icon}
|
||||
<span className="sr-only">{name}</span>
|
||||
</Link>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent side="right">{name}</TooltipContent>
|
||||
</Tooltip>
|
||||
}
|
||||
|
||||
export function NavList() {
|
||||
return <aside className="h-screen flex flex-col">
|
||||
<nav className="flex flex-col items-center gap-4 px-2 sm:py-5 flex-1">
|
||||
<NavItem icon={<MagnifyingGlassIcon className="h-5 w-5" />} to="/search" name="Search" />
|
||||
<NavItem icon={<ActivityLogIcon className="h-5 w-5" />} to="/tags" name="Tags" />
|
||||
<NavItem icon={<ArchiveIcon className="h-5 w-5" />} to="/difference" name="Difference" />
|
||||
</nav>
|
||||
<nav className="mt-auto flex flex-col items-center gap-4 px-2 sm:py-5 flex-grow-0">
|
||||
<NavItem icon={<PersonIcon className="h-5 w-5" />} to="/profile" name="Profiles" />
|
||||
<NavItem icon={<GearIcon className="h-5 w-5" />} to="/setting" name="Settings" />
|
||||
</nav>
|
||||
</aside>
|
||||
}
|
57
packages/client/src/components/ui/button.tsx
Normal file
57
packages/client/src/components/ui/button.tsx
Normal file
@ -0,0 +1,57 @@
|
||||
import * as React from "react"
|
||||
import { Slot } from "@radix-ui/react-slot"
|
||||
import { cva, type VariantProps } from "class-variance-authority"
|
||||
|
||||
import { cn } from "@/lib/utils"
|
||||
|
||||
const buttonVariants = cva(
|
||||
"inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50",
|
||||
{
|
||||
variants: {
|
||||
variant: {
|
||||
default:
|
||||
"bg-primary text-primary-foreground shadow hover:bg-primary/90",
|
||||
destructive:
|
||||
"bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
|
||||
outline:
|
||||
"border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
|
||||
secondary:
|
||||
"bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
|
||||
ghost: "hover:bg-accent hover:text-accent-foreground",
|
||||
link: "text-primary underline-offset-4 hover:underline",
|
||||
},
|
||||
size: {
|
||||
default: "h-9 px-4 py-2",
|
||||
sm: "h-8 rounded-md px-3 text-xs",
|
||||
lg: "h-10 rounded-md px-8",
|
||||
icon: "h-9 w-9",
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
variant: "default",
|
||||
size: "default",
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
export interface ButtonProps
|
||||
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
|
||||
VariantProps<typeof buttonVariants> {
|
||||
asChild?: boolean
|
||||
}
|
||||
|
||||
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
||||
({ className, variant, size, asChild = false, ...props }, ref) => {
|
||||
const Comp = asChild ? Slot : "button"
|
||||
return (
|
||||
<Comp
|
||||
className={cn(buttonVariants({ variant, size, className }))}
|
||||
ref={ref}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
)
|
||||
Button.displayName = "Button"
|
||||
|
||||
export { Button, buttonVariants }
|
43
packages/client/src/components/ui/resizable.tsx
Normal file
43
packages/client/src/components/ui/resizable.tsx
Normal file
@ -0,0 +1,43 @@
|
||||
import { DragHandleDots2Icon } from "@radix-ui/react-icons"
|
||||
import * as ResizablePrimitive from "react-resizable-panels"
|
||||
|
||||
import { cn } from "@/lib/utils"
|
||||
|
||||
const ResizablePanelGroup = ({
|
||||
className,
|
||||
...props
|
||||
}: React.ComponentProps<typeof ResizablePrimitive.PanelGroup>) => (
|
||||
<ResizablePrimitive.PanelGroup
|
||||
className={cn(
|
||||
"flex h-full w-full data-[panel-group-direction=vertical]:flex-col",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
|
||||
const ResizablePanel = ResizablePrimitive.Panel
|
||||
|
||||
const ResizableHandle = ({
|
||||
withHandle,
|
||||
className,
|
||||
...props
|
||||
}: React.ComponentProps<typeof ResizablePrimitive.PanelResizeHandle> & {
|
||||
withHandle?: boolean
|
||||
}) => (
|
||||
<ResizablePrimitive.PanelResizeHandle
|
||||
className={cn(
|
||||
"relative flex w-px items-center justify-center bg-border after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-1 data-[panel-group-direction=vertical]:h-px data-[panel-group-direction=vertical]:w-full data-[panel-group-direction=vertical]:after:left-0 data-[panel-group-direction=vertical]:after:h-1 data-[panel-group-direction=vertical]:after:w-full data-[panel-group-direction=vertical]:after:-translate-y-1/2 data-[panel-group-direction=vertical]:after:translate-x-0 [&[data-panel-group-direction=vertical]>div]:rotate-90",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{withHandle && (
|
||||
<div className="z-10 flex h-4 w-3 items-center justify-center rounded-sm border bg-border">
|
||||
<DragHandleDots2Icon className="h-2.5 w-2.5" />
|
||||
</div>
|
||||
)}
|
||||
</ResizablePrimitive.PanelResizeHandle>
|
||||
)
|
||||
|
||||
export { ResizablePanelGroup, ResizablePanel, ResizableHandle }
|
28
packages/client/src/components/ui/tooltip.tsx
Normal file
28
packages/client/src/components/ui/tooltip.tsx
Normal file
@ -0,0 +1,28 @@
|
||||
import * as React from "react"
|
||||
import * as TooltipPrimitive from "@radix-ui/react-tooltip"
|
||||
|
||||
import { cn } from "@/lib/utils"
|
||||
|
||||
const TooltipProvider = TooltipPrimitive.Provider
|
||||
|
||||
const Tooltip = TooltipPrimitive.Root
|
||||
|
||||
const TooltipTrigger = TooltipPrimitive.Trigger
|
||||
|
||||
const TooltipContent = React.forwardRef<
|
||||
React.ElementRef<typeof TooltipPrimitive.Content>,
|
||||
React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>
|
||||
>(({ className, sideOffset = 4, ...props }, ref) => (
|
||||
<TooltipPrimitive.Content
|
||||
ref={ref}
|
||||
sideOffset={sideOffset}
|
||||
className={cn(
|
||||
"z-50 overflow-hidden rounded-md bg-primary px-3 py-1.5 text-xs text-primary-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
))
|
||||
TooltipContent.displayName = TooltipPrimitive.Content.displayName
|
||||
|
||||
export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }
|
70
packages/client/src/lib/atom.ts
Normal file
70
packages/client/src/lib/atom.ts
Normal file
@ -0,0 +1,70 @@
|
||||
import { useEffect, useReducer, useState } from "react";
|
||||
|
||||
interface AtomState<T> {
|
||||
value: T;
|
||||
listeners: Set<() => void>;
|
||||
}
|
||||
interface Atom<T> {
|
||||
key: string;
|
||||
default: T;
|
||||
}
|
||||
|
||||
const atomStateMap = new WeakMap<Atom<unknown>, AtomState<unknown>>();
|
||||
|
||||
export function atom<T>(key: string, defaultVal: T): Atom<T> {
|
||||
return { key, default: defaultVal };
|
||||
}
|
||||
|
||||
function getAtomState<T>(atom: Atom<T>): AtomState<T> {
|
||||
let atomState = atomStateMap.get(atom);
|
||||
if (!atomState) {
|
||||
atomState = {
|
||||
value: atom.default,
|
||||
listeners: new Set(),
|
||||
};
|
||||
atomStateMap.set(atom, atomState);
|
||||
}
|
||||
return atomState as AtomState<T>;
|
||||
}
|
||||
|
||||
export function useAtom<T>(atom: Atom<T>): [T, (val: T) => void] {
|
||||
const state = getAtomState(atom);
|
||||
const [, setState] = useState(state.value);
|
||||
useEffect(() => {
|
||||
const listener = () => setState(state.value);
|
||||
state.listeners.add(listener);
|
||||
return () => {
|
||||
state.listeners.delete(listener);
|
||||
};
|
||||
}, [state]);
|
||||
return [
|
||||
state.value as T,
|
||||
(val: T) => {
|
||||
state.value = val;
|
||||
// biome-ignore lint/complexity/noForEach: forEach is used to call each listener
|
||||
state.listeners.forEach((listener) => listener());
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
export function useAtomValue<T>(atom: Atom<T>): T {
|
||||
const state = getAtomState(atom);
|
||||
const update = useReducer((x) => x + 1, 0)[1];
|
||||
useEffect(() => {
|
||||
const listener = () => update();
|
||||
state.listeners.add(listener);
|
||||
return () => {
|
||||
state.listeners.delete(listener);
|
||||
};
|
||||
}, [state, update]);
|
||||
return state.value;
|
||||
}
|
||||
|
||||
export function setAtomValue<T>(atom: Atom<T>): (val: T) => void {
|
||||
const state = getAtomState(atom);
|
||||
return (val: T) => {
|
||||
state.value = val;
|
||||
// biome-ignore lint/complexity/noForEach: forEach is used to call each listener
|
||||
state.listeners.forEach((listener) => listener());
|
||||
};
|
||||
}
|
@ -1,15 +1,9 @@
|
||||
import { Typography } from "@mui/material";
|
||||
import React from "react";
|
||||
import { CommonMenuList, Headline } from "../component/mod";
|
||||
import { PagePad } from "../component/pagepad";
|
||||
|
||||
export const NotFoundPage = () => {
|
||||
const menu = CommonMenuList();
|
||||
return (
|
||||
<Headline menu={menu}>
|
||||
<PagePad>
|
||||
<Typography variant="h2">404 Not Found</Typography>
|
||||
</PagePad>
|
||||
</Headline>
|
||||
return (<div className="flex items-center justify-center flex-col box-border h-screen space-y-2">
|
||||
<h2 className="text-6xl">404 Not Found</h2>
|
||||
<p>찾을 수 없음</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default NotFoundPage;
|
6
packages/client/src/page/galleryPage.tsx
Normal file
6
packages/client/src/page/galleryPage.tsx
Normal file
@ -0,0 +1,6 @@
|
||||
export default function Gallery() {
|
||||
return (<div>
|
||||
a
|
||||
</div>
|
||||
);
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
import React, { createContext, useRef, useState } from "react";
|
||||
export const BackLinkContext = createContext({ backLink: "", setBackLink: (s: string) => {} });
|
||||
|
||||
export const UserContext = createContext({
|
||||
username: "",
|
||||
permission: [] as string[],
|
||||
|
109
packages/client/src/state/user.ts
Normal file
109
packages/client/src/state/user.ts
Normal file
@ -0,0 +1,109 @@
|
||||
import { atom, useAtomValue, setAtomValue } from "../lib/atom";
|
||||
|
||||
type LoginLocalStorage = {
|
||||
username: string;
|
||||
permission: string[];
|
||||
accessExpired: number;
|
||||
};
|
||||
|
||||
let localObj: LoginLocalStorage | null = null;
|
||||
function getUserSessions() {
|
||||
if (localObj === null) {
|
||||
const storagestr = localStorage.getItem("UserLoginContext") as string | null;
|
||||
const storage = storagestr !== null ? (JSON.parse(storagestr) as LoginLocalStorage | null) : null;
|
||||
localObj = storage;
|
||||
}
|
||||
if (localObj !== null && localObj.accessExpired > Math.floor(Date.now() / 1000)) {
|
||||
return {
|
||||
username: localObj.username,
|
||||
permission: localObj.permission,
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
async function refresh() {
|
||||
const res = await fetch("/user/refresh", {
|
||||
method: "POST",
|
||||
});
|
||||
if (res.status !== 200) throw new Error("Maybe Network Error");
|
||||
const r = (await res.json()) as LoginLocalStorage & { refresh: boolean };
|
||||
if (r.refresh) {
|
||||
localObj = {
|
||||
...r
|
||||
};
|
||||
} else {
|
||||
localObj = {
|
||||
accessExpired: 0,
|
||||
username: "",
|
||||
permission: r.permission,
|
||||
};
|
||||
}
|
||||
localStorage.setItem("UserLoginContext", JSON.stringify(localObj));
|
||||
return {
|
||||
username: r.username,
|
||||
permission: r.permission,
|
||||
};
|
||||
}
|
||||
|
||||
export const doLogout = async () => {
|
||||
const req = await fetch("/user/logout", {
|
||||
method: "POST",
|
||||
});
|
||||
const setVal = setAtomValue(userLoginStateAtom);
|
||||
try {
|
||||
const res = await req.json();
|
||||
localObj = {
|
||||
accessExpired: 0,
|
||||
username: "",
|
||||
permission: res.permission,
|
||||
};
|
||||
window.localStorage.setItem("UserLoginContext", JSON.stringify(localObj));
|
||||
setVal(localObj);
|
||||
return {
|
||||
username: localObj.username,
|
||||
permission: localObj.permission,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error(`Server Error ${error}`);
|
||||
return {
|
||||
username: "",
|
||||
permission: [],
|
||||
};
|
||||
}
|
||||
};
|
||||
export const doLogin = async (userLoginInfo: {
|
||||
username: string;
|
||||
password: string;
|
||||
}): Promise<string | LoginLocalStorage> => {
|
||||
const res = await fetch("/user/login", {
|
||||
method: "POST",
|
||||
body: JSON.stringify(userLoginInfo),
|
||||
headers: { "content-type": "application/json" },
|
||||
});
|
||||
const b = await res.json();
|
||||
if (res.status !== 200) {
|
||||
return b.detail as string;
|
||||
}
|
||||
const setVal = setAtomValue(userLoginStateAtom);
|
||||
localObj = b;
|
||||
setVal(b);
|
||||
window.localStorage.setItem("UserLoginContext", JSON.stringify(localObj));
|
||||
return b;
|
||||
};
|
||||
|
||||
|
||||
export async function getInitialValue() {
|
||||
const user = getUserSessions();
|
||||
if (user) {
|
||||
return user;
|
||||
}
|
||||
return refresh();
|
||||
}
|
||||
|
||||
export const userLoginStateAtom = atom("userLoginState", getUserSessions());
|
||||
|
||||
export function useLogin() {
|
||||
const val = useAtomValue(userLoginStateAtom);
|
||||
return val;
|
||||
}
|
451
pnpm-lock.yaml
451
pnpm-lock.yaml
@ -17,6 +17,12 @@ importers:
|
||||
'@radix-ui/react-icons':
|
||||
specifier: ^1.3.0
|
||||
version: 1.3.0(react@18.2.0)
|
||||
'@radix-ui/react-slot':
|
||||
specifier: ^1.0.2
|
||||
version: 1.0.2(@types/react@18.2.71)(react@18.2.0)
|
||||
'@radix-ui/react-tooltip':
|
||||
specifier: ^1.0.7
|
||||
version: 1.0.7(@types/react-dom@18.2.22)(@types/react@18.2.71)(react-dom@18.2.0)(react@18.2.0)
|
||||
class-variance-authority:
|
||||
specifier: ^0.7.0
|
||||
version: 0.7.0
|
||||
@ -29,12 +35,21 @@ importers:
|
||||
react-dom:
|
||||
specifier: ^18.2.0
|
||||
version: 18.2.0(react@18.2.0)
|
||||
react-resizable-panels:
|
||||
specifier: ^2.0.16
|
||||
version: 2.0.16(react-dom@18.2.0)(react@18.2.0)
|
||||
swr:
|
||||
specifier: ^2.2.5
|
||||
version: 2.2.5(react@18.2.0)
|
||||
tailwind-merge:
|
||||
specifier: ^2.2.2
|
||||
version: 2.2.2
|
||||
tailwindcss-animate:
|
||||
specifier: ^1.0.7
|
||||
version: 1.0.7(tailwindcss@3.4.3)
|
||||
wouter:
|
||||
specifier: ^3.1.0
|
||||
version: 3.1.0(react@18.2.0)
|
||||
devDependencies:
|
||||
'@types/node':
|
||||
specifier: '>=20.0.0'
|
||||
@ -817,6 +832,34 @@ packages:
|
||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||
dev: true
|
||||
|
||||
/@floating-ui/core@1.6.0:
|
||||
resolution: {integrity: sha512-PcF++MykgmTj3CIyOQbKA/hDzOAiqI3mhuoN44WRCopIs1sgoDoU4oty4Jtqaj/y3oDU6fnVSm4QG0a3t5i0+g==}
|
||||
dependencies:
|
||||
'@floating-ui/utils': 0.2.1
|
||||
dev: false
|
||||
|
||||
/@floating-ui/dom@1.6.3:
|
||||
resolution: {integrity: sha512-RnDthu3mzPlQ31Ss/BTwQ1zjzIhr3lk1gZB1OC56h/1vEtaXkESrOqL5fQVMfXpwGtRwX+YsZBdyHtJMQnkArw==}
|
||||
dependencies:
|
||||
'@floating-ui/core': 1.6.0
|
||||
'@floating-ui/utils': 0.2.1
|
||||
dev: false
|
||||
|
||||
/@floating-ui/react-dom@2.0.8(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-HOdqOt3R3OGeTKidaLvJKcgg75S6tibQ3Tif4eyd91QnIJWr0NLvoXFpJA/j8HqkFSL68GDca9AuyWEHlhyClw==}
|
||||
peerDependencies:
|
||||
react: '>=16.8.0'
|
||||
react-dom: '>=16.8.0'
|
||||
dependencies:
|
||||
'@floating-ui/dom': 1.6.3
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
dev: false
|
||||
|
||||
/@floating-ui/utils@0.2.1:
|
||||
resolution: {integrity: sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==}
|
||||
dev: false
|
||||
|
||||
/@humanwhocodes/config-array@0.11.14:
|
||||
resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==}
|
||||
engines: {node: '>=10.10.0'}
|
||||
@ -911,6 +954,86 @@ packages:
|
||||
requiresBuild: true
|
||||
optional: true
|
||||
|
||||
/@radix-ui/primitive@1.0.1:
|
||||
resolution: {integrity: sha512-yQ8oGX2GVsEYMWGxcovu1uGWPCxV5BFfeeYxqPmuAzUyLT9qmaMXSAhXpb0WrspIeqYzdJpkh2vHModJPgRIaw==}
|
||||
dependencies:
|
||||
'@babel/runtime': 7.24.1
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-arrow@1.0.3(@types/react-dom@18.2.22)(@types/react@18.2.71)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-wSP+pHsB/jQRaL6voubsQ/ZlrGBHHrOjmBnr19hxYgtS0WvAFwZhK2WP/YY5yF9uKECCEEDGxuLxq1NBK51wFA==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
'@types/react-dom': '*'
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
'@types/react-dom':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/runtime': 7.24.1
|
||||
'@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.22)(@types/react@18.2.71)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@types/react': 18.2.71
|
||||
'@types/react-dom': 18.2.22
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-compose-refs@1.0.1(@types/react@18.2.71)(react@18.2.0):
|
||||
resolution: {integrity: sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/runtime': 7.24.1
|
||||
'@types/react': 18.2.71
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-context@1.0.1(@types/react@18.2.71)(react@18.2.0):
|
||||
resolution: {integrity: sha512-ebbrdFoYTcuZ0v4wG5tedGnp9tzcV8awzsxYph7gXUyvnNLuTIcCk1q17JEbnVhXAKG9oX3KtchwiMIAYp9NLg==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/runtime': 7.24.1
|
||||
'@types/react': 18.2.71
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-dismissable-layer@1.0.5(@types/react-dom@18.2.22)(@types/react@18.2.71)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-aJeDjQhywg9LBu2t/At58hCvr7pEm0o2Ke1x33B+MhjNmmZ17sy4KImo0KPLgsnc/zN7GPdce8Cnn0SWvwZO7g==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
'@types/react-dom': '*'
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
'@types/react-dom':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/runtime': 7.24.1
|
||||
'@radix-ui/primitive': 1.0.1
|
||||
'@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.71)(react@18.2.0)
|
||||
'@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.22)(@types/react@18.2.71)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.71)(react@18.2.0)
|
||||
'@radix-ui/react-use-escape-keydown': 1.0.3(@types/react@18.2.71)(react@18.2.0)
|
||||
'@types/react': 18.2.71
|
||||
'@types/react-dom': 18.2.22
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-icons@1.3.0(react@18.2.0):
|
||||
resolution: {integrity: sha512-jQxj/0LKgp+j9BiTXz3O3sgs26RNet2iLWmsPyRz2SIcR4q/4SbazXfnYwbAr+vLYKSfc7qxzyGQA1HLlYiuNw==}
|
||||
peerDependencies:
|
||||
@ -919,6 +1042,277 @@ packages:
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-id@1.0.1(@types/react@18.2.71)(react@18.2.0):
|
||||
resolution: {integrity: sha512-tI7sT/kqYp8p96yGWY1OAnLHrqDgzHefRBKQ2YAkBS5ja7QLcZ9Z/uY7bEjPUatf8RomoXM8/1sMj1IJaE5UzQ==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/runtime': 7.24.1
|
||||
'@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.71)(react@18.2.0)
|
||||
'@types/react': 18.2.71
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-popper@1.1.3(@types/react-dom@18.2.22)(@types/react@18.2.71)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-cKpopj/5RHZWjrbF2846jBNacjQVwkP068DfmgrNJXpvVWrOvlAmE9xSiy5OqeE+Gi8D9fP+oDhUnPqNMY8/5w==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
'@types/react-dom': '*'
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
'@types/react-dom':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/runtime': 7.24.1
|
||||
'@floating-ui/react-dom': 2.0.8(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-arrow': 1.0.3(@types/react-dom@18.2.22)(@types/react@18.2.71)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.71)(react@18.2.0)
|
||||
'@radix-ui/react-context': 1.0.1(@types/react@18.2.71)(react@18.2.0)
|
||||
'@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.22)(@types/react@18.2.71)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.71)(react@18.2.0)
|
||||
'@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.71)(react@18.2.0)
|
||||
'@radix-ui/react-use-rect': 1.0.1(@types/react@18.2.71)(react@18.2.0)
|
||||
'@radix-ui/react-use-size': 1.0.1(@types/react@18.2.71)(react@18.2.0)
|
||||
'@radix-ui/rect': 1.0.1
|
||||
'@types/react': 18.2.71
|
||||
'@types/react-dom': 18.2.22
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-portal@1.0.4(@types/react-dom@18.2.22)(@types/react@18.2.71)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-Qki+C/EuGUVCQTOTD5vzJzJuMUlewbzuKyUy+/iHM2uwGiru9gZeBJtHAPKAEkB5KWGi9mP/CHKcY0wt1aW45Q==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
'@types/react-dom': '*'
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
'@types/react-dom':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/runtime': 7.24.1
|
||||
'@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.22)(@types/react@18.2.71)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@types/react': 18.2.71
|
||||
'@types/react-dom': 18.2.22
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-presence@1.0.1(@types/react-dom@18.2.22)(@types/react@18.2.71)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
'@types/react-dom': '*'
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
'@types/react-dom':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/runtime': 7.24.1
|
||||
'@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.71)(react@18.2.0)
|
||||
'@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.71)(react@18.2.0)
|
||||
'@types/react': 18.2.71
|
||||
'@types/react-dom': 18.2.22
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-primitive@1.0.3(@types/react-dom@18.2.22)(@types/react@18.2.71)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
'@types/react-dom': '*'
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
'@types/react-dom':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/runtime': 7.24.1
|
||||
'@radix-ui/react-slot': 1.0.2(@types/react@18.2.71)(react@18.2.0)
|
||||
'@types/react': 18.2.71
|
||||
'@types/react-dom': 18.2.22
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-slot@1.0.2(@types/react@18.2.71)(react@18.2.0):
|
||||
resolution: {integrity: sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/runtime': 7.24.1
|
||||
'@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.71)(react@18.2.0)
|
||||
'@types/react': 18.2.71
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-tooltip@1.0.7(@types/react-dom@18.2.22)(@types/react@18.2.71)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-lPh5iKNFVQ/jav/j6ZrWq3blfDJ0OH9R6FlNUHPMqdLuQ9vwDgFsRxvl8b7Asuy5c8xmoojHUxKHQSOAvMHxyw==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
'@types/react-dom': '*'
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
'@types/react-dom':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/runtime': 7.24.1
|
||||
'@radix-ui/primitive': 1.0.1
|
||||
'@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.71)(react@18.2.0)
|
||||
'@radix-ui/react-context': 1.0.1(@types/react@18.2.71)(react@18.2.0)
|
||||
'@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.2.22)(@types/react@18.2.71)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-id': 1.0.1(@types/react@18.2.71)(react@18.2.0)
|
||||
'@radix-ui/react-popper': 1.1.3(@types/react-dom@18.2.22)(@types/react@18.2.71)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-portal': 1.0.4(@types/react-dom@18.2.22)(@types/react@18.2.71)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.22)(@types/react@18.2.71)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.22)(@types/react@18.2.71)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-slot': 1.0.2(@types/react@18.2.71)(react@18.2.0)
|
||||
'@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.71)(react@18.2.0)
|
||||
'@radix-ui/react-visually-hidden': 1.0.3(@types/react-dom@18.2.22)(@types/react@18.2.71)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@types/react': 18.2.71
|
||||
'@types/react-dom': 18.2.22
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-use-callback-ref@1.0.1(@types/react@18.2.71)(react@18.2.0):
|
||||
resolution: {integrity: sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/runtime': 7.24.1
|
||||
'@types/react': 18.2.71
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-use-controllable-state@1.0.1(@types/react@18.2.71)(react@18.2.0):
|
||||
resolution: {integrity: sha512-Svl5GY5FQeN758fWKrjM6Qb7asvXeiZltlT4U2gVfl8Gx5UAv2sMR0LWo8yhsIZh2oQ0eFdZ59aoOOMV7b47VA==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/runtime': 7.24.1
|
||||
'@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.71)(react@18.2.0)
|
||||
'@types/react': 18.2.71
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-use-escape-keydown@1.0.3(@types/react@18.2.71)(react@18.2.0):
|
||||
resolution: {integrity: sha512-vyL82j40hcFicA+M4Ex7hVkB9vHgSse1ZWomAqV2Je3RleKGO5iM8KMOEtfoSB0PnIelMd2lATjTGMYqN5ylTg==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/runtime': 7.24.1
|
||||
'@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.71)(react@18.2.0)
|
||||
'@types/react': 18.2.71
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-use-layout-effect@1.0.1(@types/react@18.2.71)(react@18.2.0):
|
||||
resolution: {integrity: sha512-v/5RegiJWYdoCvMnITBkNNx6bCj20fiaJnWtRkU18yITptraXjffz5Qbn05uOiQnOvi+dbkznkoaMltz1GnszQ==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/runtime': 7.24.1
|
||||
'@types/react': 18.2.71
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-use-rect@1.0.1(@types/react@18.2.71)(react@18.2.0):
|
||||
resolution: {integrity: sha512-Cq5DLuSiuYVKNU8orzJMbl15TXilTnJKUCltMVQg53BQOF1/C5toAaGrowkgksdBQ9H+SRL23g0HDmg9tvmxXw==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/runtime': 7.24.1
|
||||
'@radix-ui/rect': 1.0.1
|
||||
'@types/react': 18.2.71
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-use-size@1.0.1(@types/react@18.2.71)(react@18.2.0):
|
||||
resolution: {integrity: sha512-ibay+VqrgcaI6veAojjofPATwledXiSmX+C0KrBk/xgpX9rBzPV3OsfwlhQdUOFbh+LKQorLYT+xTXW9V8yd0g==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/runtime': 7.24.1
|
||||
'@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.71)(react@18.2.0)
|
||||
'@types/react': 18.2.71
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-visually-hidden@1.0.3(@types/react-dom@18.2.22)(@types/react@18.2.71)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-D4w41yN5YRKtu464TLnByKzMDG/JlMPHtfZgQAu9v6mNakUqGUI9vUrfQKz8NK41VMm/xbZbh76NUTVtIYqOMA==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
'@types/react-dom': '*'
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
'@types/react-dom':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/runtime': 7.24.1
|
||||
'@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.22)(@types/react@18.2.71)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@types/react': 18.2.71
|
||||
'@types/react-dom': 18.2.22
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
dev: false
|
||||
|
||||
/@radix-ui/rect@1.0.1:
|
||||
resolution: {integrity: sha512-fyrgCaedtvMg9NK3en0pnOYJdtfwxUcNolezkNPUsoX57X8oQk+NkqcvzHXD2uKNij6GXmWU9NDru2IWjrO4BQ==}
|
||||
dependencies:
|
||||
'@babel/runtime': 7.24.1
|
||||
dev: false
|
||||
|
||||
/@rollup/rollup-android-arm-eabi@4.13.0:
|
||||
resolution: {integrity: sha512-5ZYPOuaAqEH/W3gYsRkxQATBW3Ii1MfaT4EQstTnLKViLi2gLSQmlmtTpGucNP3sXEpOiI5tdGhjdE111ekyEg==}
|
||||
cpu: [arm]
|
||||
@ -1382,7 +1776,6 @@ packages:
|
||||
|
||||
/@types/prop-types@15.7.12:
|
||||
resolution: {integrity: sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==}
|
||||
dev: true
|
||||
|
||||
/@types/qs@6.9.14:
|
||||
resolution: {integrity: sha512-5khscbd3SwWMhFqylJBLQ0zIu7c1K6Vz0uBIt915BI3zV0q1nfjRQD3RqSBcPaO6PHEF4ov/t9y89fSiyThlPA==}
|
||||
@ -1396,7 +1789,6 @@ packages:
|
||||
resolution: {integrity: sha512-fHkBXPeNtfvri6gdsMYyW+dW7RXFo6Ad09nLFK0VQWR7yGLai/Cyvyj696gbwYvBnhGtevUG9cET0pmUbMtoPQ==}
|
||||
dependencies:
|
||||
'@types/react': 18.2.71
|
||||
dev: true
|
||||
|
||||
/@types/react@18.2.71:
|
||||
resolution: {integrity: sha512-PxEsB9OjmQeYGffoWnYAd/r5FiJuUw2niFQHPc2v2idwh8wGPkkYzOHuinNJJY6NZqfoTCiOIizDOz38gYNsyw==}
|
||||
@ -1404,7 +1796,6 @@ packages:
|
||||
'@types/prop-types': 15.7.12
|
||||
'@types/scheduler': 0.23.0
|
||||
csstype: 3.1.3
|
||||
dev: true
|
||||
|
||||
/@types/responselike@1.0.3:
|
||||
resolution: {integrity: sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==}
|
||||
@ -1414,7 +1805,6 @@ packages:
|
||||
|
||||
/@types/scheduler@0.23.0:
|
||||
resolution: {integrity: sha512-YIoDCTH3Af6XM5VuwGG/QL/CJqga1Zm3NkU3HZ4ZHK2fRMPYP1VczsTUqtsf43PH/iJNVlPHAo2oWX7BSdB2Hw==}
|
||||
dev: true
|
||||
|
||||
/@types/semver@7.5.8:
|
||||
resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==}
|
||||
@ -1933,6 +2323,10 @@ packages:
|
||||
engines: {node: '>=6'}
|
||||
dev: true
|
||||
|
||||
/client-only@0.0.1:
|
||||
resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==}
|
||||
dev: false
|
||||
|
||||
/clone-response@1.0.3:
|
||||
resolution: {integrity: sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==}
|
||||
dependencies:
|
||||
@ -2079,7 +2473,6 @@ packages:
|
||||
|
||||
/csstype@3.1.3:
|
||||
resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
|
||||
dev: true
|
||||
|
||||
/data-uri-to-buffer@4.0.1:
|
||||
resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==}
|
||||
@ -3432,6 +3825,10 @@ packages:
|
||||
resolution: {integrity: sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==}
|
||||
engines: {node: '>=16 || 14 >=14.17'}
|
||||
|
||||
/mitt@3.0.1:
|
||||
resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==}
|
||||
dev: false
|
||||
|
||||
/mkdirp-classic@0.5.3:
|
||||
resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==}
|
||||
|
||||
@ -3934,6 +4331,16 @@ packages:
|
||||
scheduler: 0.23.0
|
||||
dev: false
|
||||
|
||||
/react-resizable-panels@2.0.16(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-UrnxmTZaTnbCl/xIOX38ig35RicqGfLuqt2x5fytpNlQvCRuxyXZwIBEhmF+pmrEGxfajyXFBoCplNxLvhF0CQ==}
|
||||
peerDependencies:
|
||||
react: ^16.14.0 || ^17.0.0 || ^18.0.0
|
||||
react-dom: ^16.14.0 || ^17.0.0 || ^18.0.0
|
||||
dependencies:
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
dev: false
|
||||
|
||||
/react@18.2.0:
|
||||
resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
@ -3989,6 +4396,11 @@ packages:
|
||||
resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==}
|
||||
dev: false
|
||||
|
||||
/regexparam@3.0.0:
|
||||
resolution: {integrity: sha512-RSYAtP31mvYLkAHrOlh25pCNQ5hWnT106VukGaaFfuJrZFkGRX5GhUAdPqpSDXxOhA2c4akmRuplv1mRqnBn6Q==}
|
||||
engines: {node: '>=8'}
|
||||
dev: false
|
||||
|
||||
/resolve-alpn@1.2.1:
|
||||
resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==}
|
||||
dev: true
|
||||
@ -4384,6 +4796,16 @@ packages:
|
||||
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
/swr@2.2.5(react@18.2.0):
|
||||
resolution: {integrity: sha512-QtxqyclFeAsxEUeZIYmsaQ0UjimSq1RZ9Un7I68/0ClKK/U3LoyQunwkQfJZr2fc22DfIXLNDc2wFyTEikCUpg==}
|
||||
peerDependencies:
|
||||
react: ^16.11.0 || ^17.0.0 || ^18.0.0
|
||||
dependencies:
|
||||
client-only: 0.0.1
|
||||
react: 18.2.0
|
||||
use-sync-external-store: 1.2.0(react@18.2.0)
|
||||
dev: false
|
||||
|
||||
/tailwind-merge@2.2.2:
|
||||
resolution: {integrity: sha512-tWANXsnmJzgw6mQ07nE3aCDkCK4QdT3ThPMCzawoYA2Pws7vSTCvz3Vrjg61jVUGfFZPJzxEP+NimbcW+EdaDw==}
|
||||
dependencies:
|
||||
@ -4612,6 +5034,14 @@ packages:
|
||||
punycode: 2.3.1
|
||||
dev: true
|
||||
|
||||
/use-sync-external-store@1.2.0(react@18.2.0):
|
||||
resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==}
|
||||
peerDependencies:
|
||||
react: ^16.8.0 || ^17.0.0 || ^18.0.0
|
||||
dependencies:
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/util-deprecate@1.0.2:
|
||||
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
|
||||
|
||||
@ -4681,6 +5111,17 @@ packages:
|
||||
dependencies:
|
||||
isexe: 2.0.0
|
||||
|
||||
/wouter@3.1.0(react@18.2.0):
|
||||
resolution: {integrity: sha512-hou3w+12BMTBckdWdyJp/z7+kKcbdLDWfz6omSyrO6bbx4irNuQQyLDQkfSGXXJCxmglea3c8On9XFUkBSU8+Q==}
|
||||
peerDependencies:
|
||||
react: '>=16.8.0'
|
||||
dependencies:
|
||||
mitt: 3.0.1
|
||||
react: 18.2.0
|
||||
regexparam: 3.0.0
|
||||
use-sync-external-store: 1.2.0(react@18.2.0)
|
||||
dev: false
|
||||
|
||||
/wrap-ansi@7.0.0:
|
||||
resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
|
||||
engines: {node: '>=10'}
|
||||
|
Loading…
Reference in New Issue
Block a user