feat: create sidebar and header #103

Merged
lima merged 4 commits from feat/96-create_sidebar_and_header into main 2025-06-25 10:39:18 +00:00
29 changed files with 1950 additions and 216 deletions

View file

@ -27,20 +27,24 @@
"@fortawesome/react-fontawesome": "^0.2.2",
"@hookform/resolvers": "^5.0.1",
"@prisma/client": "^6.9.0",
"@radix-ui/react-dropdown-menu": "^2.1.14",
"@radix-ui/react-avatar": "^1.1.10",
"@radix-ui/react-collapsible": "^1.1.11",
"@radix-ui/react-dialog": "^1.1.14",
"@radix-ui/react-dropdown-menu": "^2.1.15",
"@radix-ui/react-hover-card": "^1.1.13",
"@radix-ui/react-label": "^2.1.6",
"@radix-ui/react-scroll-area": "^1.2.8",
"@radix-ui/react-select": "^2.2.4",
"@radix-ui/react-separator": "^1.1.6",
"@radix-ui/react-slot": "^1.2.2",
"@radix-ui/react-separator": "^1.1.7",
"@radix-ui/react-slot": "^1.2.3",
"@radix-ui/react-switch": "^1.2.4",
"@radix-ui/react-tabs": "^1.1.11",
"@radix-ui/react-tooltip": "^1.2.7",
"@tanstack/react-query": "^5.80.7",
"bcryptjs": "^3.0.2",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"lucide-react": "^0.511.0",
"lucide-react": "^0.515.0",
"next": "15.4.0-canary.95",
"next-auth": "^5.0.0-beta.25",
"next-themes": "^0.4.6",

View file

@ -1,15 +1,13 @@
'use client';
import { RedirectButton } from '@/components/buttons/redirect-button';
import { ThemePicker } from '@/components/misc/theme-picker';
import { useGetApiUserMe } from '@/generated/api/user/user';
export default function Home() {
const { data, isLoading } = useGetApiUserMe();
return (
<div className='flex flex-col items-center justify-center h-screen'>
<div className='absolute top-4 right-4'>{<ThemePicker />}</div>
<div className='flex flex-col items-center justify-center h-full'>
<div>
<h1>
Hello{' '}

23
src/app/(main)/layout.tsx Normal file
View file

@ -0,0 +1,23 @@
import React from 'react';
import { cookies } from 'next/headers';
import { AppSidebar } from '@/components/custom-ui/app-sidebar';
import SidebarProviderWrapper from '@/components/wrappers/sidebar-provider';
import Header from '@/components/misc/header';
export default async function Layout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
const cookieStore = await cookies();
const defaultOpen = cookieStore.get('sidebar_state')?.value === 'true';
return (
<>
<SidebarProviderWrapper defaultOpen={defaultOpen}>
<AppSidebar></AppSidebar>
<Header>{children}</Header>
</SidebarProviderWrapper>
</>
);
}

View file

@ -33,6 +33,7 @@
--text-alt: var(--neutral-900);
--text-input: var(--text);
--text-muted-input: var(--neutral-450);
--text-muted: var(--neutral-300);
--muted-input: var(--neutral-600);
--background-disabled: var(--neutral-500);
--text-disabled: var(--neutral-700);
@ -55,6 +56,8 @@
--card: var(--neutral-800);
--sidebar-width-icon: 32px;
/* ------------------- */
--foreground: oklch(0.13 0.028 261.692);
@ -95,17 +98,17 @@
--chart-5: oklch(0.769 0.188 70.08);
--sidebar: oklch(0.985 0.002 247.839);
--sidebar: var(--background);
--sidebar-foreground: oklch(0.13 0.028 261.692);
--sidebar-foreground: var(--text);
--sidebar-primary: oklch(0.21 0.034 264.665);
--sidebar-primary-foreground: oklch(0.985 0.002 247.839);
--sidebar-primary-foreground: var(--text);
--sidebar-accent: oklch(0.967 0.003 264.542);
--sidebar-accent-foreground: oklch(0.21 0.034 264.665);
--sidebar-accent-foreground: var(--text);
--sidebar-border: oklch(0.928 0.006 264.531);
@ -155,6 +158,7 @@
--color-text-alt: var(--text-alt);
--color-text-input: var(--text-input);
--color-text-muted-input: var(--text-muted-input);
--color-text-muted: var(--text-muted);
--color-muted-input: var(--muted-input);
--color-background-disabled: var(--neutral-500);
@ -278,6 +282,7 @@
--text-alt: var(--neutral-900);
--text-input: var(--text);
--text-muted-input: var(--neutral-450);
--text-muted: var(--neutral-300);
--muted-input: var(--neutral-500);
--background-disabled: var(--neutral-500);
--text-disabled: var(--neutral-700);
@ -339,17 +344,17 @@
--chart-5: oklch(0.645 0.246 16.439);
--sidebar: oklch(0.21 0.034 264.665);
--sidebar: var(--background);
--sidebar-foreground: oklch(0.985 0.002 247.839);
--sidebar-foreground: var(--text);
--sidebar-primary: oklch(0.488 0.243 264.376);
--sidebar-primary-foreground: oklch(0.985 0.002 247.839);
--sidebar-primary-foreground: var(--text);
--sidebar-accent: oklch(0.278 0.033 256.848);
--sidebar-accent-foreground: oklch(0.985 0.002 247.839);
--sidebar-accent-foreground: var(--text);
--sidebar-border: oklch(1 0 0 / 10%);

View file

@ -2,7 +2,7 @@ import { ThemeProvider } from '@/components/wrappers/theme-provider';
import type { Metadata } from 'next';
import './globals.css';
import { QueryProvider } from '@/components/query-provider';
import { QueryProvider } from '@/components/wrappers/query-provider';
export const metadata: Metadata = {
title: 'MeetUp',

View file

@ -1,5 +1,5 @@
export { default as logo_colored_combo_light } from '@/assets/logo/logo_colored_combo_light.svg';
export { default as logo_colored_combo_dark } from '@/assets/logo/logo_colored_combo_dark.svg';
export { default as logo_colored_combo_light } from '@/assets/logo/new/logo_colored_combo_light.svg';
export { default as logo_colored_combo_dark } from '@/assets/logo/new/logo_colored_combo_dark.svg';
export { default as logo_colored_primary_light } from '@/assets/logo/logo_colored_primary_light.svg';
export { default as logo_colored_primary_dark } from '@/assets/logo/logo_colored_primary_dark.svg';
export { default as logo_colored_secondary_light } from '@/assets/logo/logo_colored_secondary_light.svg';
@ -12,5 +12,5 @@ export { default as logo_mono_secondary_light } from '@/assets/logo/logo_mono_se
export { default as logo_mono_secondary_dark } from '@/assets/logo/logo_mono_secondary_dark.svg';
export { default as logo_mono_submark_light } from '@/assets/logo/logo_mono_submark_light.svg';
export { default as logo_mono_submark_dark } from '@/assets/logo/logo_mono_submark_dark.svg';
export { default as logo_colored_submark_light } from '@/assets/logo/logo_colored_submark_light.svg';
export { default as logo_colored_submark_dark } from '@/assets/logo/logo_colored_submark_dark.svg';
export { default as logo_colored_submark_light } from '@/assets/logo/new/logo_colored_submark_light.svg';
export { default as logo_colored_submark_dark } from '@/assets/logo/new/logo_colored_submark_dark.svg';

View file

@ -0,0 +1,17 @@
<svg width="402" height="100" viewBox="0 0 402 100" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M234.931 38.9532C235.883 38.9532 236.684 39.3271 237.335 40.0751C237.987 40.8231 238.312 41.7437 238.312 42.8369C238.312 44.8361 236.815 46.2891 234.796 46.2891L171.031 46.3754C170.129 46.3754 169.378 46.0014 168.777 45.2535C168.126 44.563 167.8 43.7 167.8 42.6643C167.8 41.6286 168.126 40.7656 168.777 40.0751C169.378 39.3847 170.129 39.0395 171.031 39.0395L234.931 38.9532Z" fill="white"/>
<path d="M104.461 93.0499C103.487 93.0499 102.666 92.7092 102 92.0278C101.333 91.3463 101 90.5077 101 89.5117V42.5722C101 41.1569 101.487 39.9513 102.461 38.9554C103.436 37.907 104.615 37.3829 105.999 37.3829H108.538C109.563 37.3829 110.512 37.6974 111.383 38.3264C112.255 38.9554 112.871 39.7416 113.229 40.6852L130.689 85.1873L148.149 40.6852C148.559 39.7416 149.174 38.9554 149.995 38.3264C150.866 37.6974 151.815 37.3829 152.841 37.3829H155.379C156.763 37.3829 157.943 37.907 158.917 38.9554C159.891 39.9513 160.378 41.1569 160.378 42.5722V89.5117C160.378 90.5077 160.045 91.3463 159.378 92.0278C158.712 92.7092 157.891 93.0499 156.917 93.0499C155.943 93.0499 155.097 92.7092 154.379 92.0278C153.712 91.3463 153.379 90.5077 153.379 89.5117V44.8523L135.612 89.7476C135.201 90.7436 134.56 91.556 133.689 92.185C132.817 92.7616 131.817 93.0499 130.689 93.0499C129.561 93.0499 128.561 92.7616 127.689 92.185C126.818 91.556 126.177 90.7436 125.767 89.7476L107.999 44.8523V89.5117C107.999 90.5077 107.64 91.3463 106.922 92.0278C106.256 92.7092 105.435 93.0499 104.461 93.0499Z" fill="white"/>
<path d="M234.931 61.2199C235.883 61.2199 236.684 61.5939 237.335 62.3419C237.987 63.0899 238.312 64.0105 238.312 65.1037C238.312 67.1029 236.815 68.5559 234.796 68.5559L171.031 68.6422C170.129 68.6422 169.378 68.2682 168.777 67.5202C168.126 66.8298 167.8 65.9667 167.8 64.9311C167.8 63.8954 168.126 63.0324 168.777 62.3419C169.378 61.6515 170.129 61.3062 171.031 61.3062L234.931 61.2199Z" fill="#C1830D"/>
<path d="M234.931 85.6277C235.883 85.6277 236.684 86.0016 237.335 86.7496C237.987 87.4976 238.312 88.4182 238.312 89.5114C238.312 91.5106 236.815 92.9636 234.796 92.9636L171.031 93.0499C170.129 93.0499 169.378 92.6759 168.777 91.928C168.126 91.2375 167.8 90.3745 167.8 89.3388C167.8 88.3031 168.126 87.4401 168.777 86.7496C169.378 86.0592 170.129 85.714 171.031 85.714L234.931 85.6277Z" fill="white"/>
<path d="M267.963 93.0499C266.995 93.0499 266.181 92.7068 265.519 92.0205C264.857 91.3342 264.526 90.4896 264.526 89.4866V44.1136H248.943C248.026 44.1136 247.262 43.7969 246.651 43.1634C246.04 42.5299 245.734 41.738 245.734 40.7878C245.734 39.8376 246.04 39.0458 246.651 38.4123C247.262 37.726 248.026 37.3829 248.943 37.3829H286.983C287.9 37.3829 288.664 37.726 289.275 38.4123C289.937 39.0458 290.268 39.8376 290.268 40.7878C290.268 41.738 289.937 42.5299 289.275 43.1634C288.664 43.7969 287.9 44.1136 286.983 44.1136H271.477V89.4866C271.477 90.4896 271.12 91.3342 270.407 92.0205C269.745 92.7068 268.931 93.0499 267.963 93.0499Z" fill="white"/>
<path d="M338.498 3.30273C339.9 3.29168 341.204 4.05009 342.504 5.35547C344.287 7.14689 347.48 10.3467 350.621 13.4922L358.434 21.3037L358.456 21.3252L358.476 21.3486C359.393 22.4377 359.772 23.5909 359.703 24.6758C359.635 25.7528 359.129 26.695 358.402 27.375C356.958 28.7257 354.528 29.1152 352.683 27.4297L352.669 27.417L352.655 27.4033C350.775 25.4925 347.992 22.7063 345.677 20.3965C344.519 19.2419 343.48 18.2064 342.729 17.46C342.722 17.4528 342.715 17.4456 342.708 17.4385V74.9961C342.708 78.7908 342.028 82.1326 340.646 85.0029L340.647 85.0039C339.33 87.7947 337.557 90.1328 335.328 92.0059L335.32 92.0117C333.107 93.8166 330.654 95.1582 327.965 96.0342C325.293 96.9042 322.639 97.3428 320.005 97.3428C317.371 97.3428 314.716 96.9042 312.045 96.0342C309.355 95.1582 306.902 93.8166 304.689 92.0117L304.682 92.0059C302.455 90.1348 300.659 87.8002 299.29 85.0137L299.287 85.0068L299.283 84.999C297.955 82.13 297.302 78.7894 297.302 74.9961V43.5576C297.302 42.4529 297.649 41.4822 298.35 40.6836L298.494 40.5264C299.284 39.6526 300.283 39.1983 301.45 39.1982C302.613 39.1982 303.609 39.6498 304.397 40.5176C305.245 41.3395 305.675 42.3674 305.675 43.5576V75.2344C305.675 78.4181 306.366 81.0359 307.705 83.126C309.12 85.2003 310.917 86.7601 313.102 87.8184H313.101C315.307 88.8345 317.606 89.3408 320.005 89.3408C322.403 89.3408 324.702 88.8342 326.908 87.8184L327.312 87.6143C329.312 86.5634 330.947 85.0716 332.226 83.1289L332.228 83.126C333.618 81.0358 334.335 78.4183 334.335 75.2344V17.3291C333.656 18.0124 332.73 18.9438 331.672 20.0059C329.454 22.232 326.655 25.0349 324.336 27.3389L324.326 27.3486L324.315 27.3584C320.384 30.9544 315.024 25.7542 318.168 21.7617L318.193 21.7285L318.224 21.6982C321.362 18.5764 323.629 16.2939 326.017 13.8896C328.405 11.4851 330.915 8.95892 334.54 5.35254C335.811 4.08795 337.1 3.31376 338.498 3.30273Z" fill="#5770FF" stroke="#5770FF" stroke-width="1.39574"/>
<path d="M377.073 39.2316C381.146 39.2316 384.597 39.7797 387.4 40.9054H387.399C390.214 41.961 392.474 43.418 394.146 45.295C395.846 47.0923 397.064 49.0974 397.785 51.3077L397.924 51.7179C398.597 53.7677 398.935 55.8467 398.935 57.9523C398.935 60.1981 398.55 62.4136 397.785 64.5958C397.109 66.6659 395.999 68.5781 394.466 70.3322L394.154 70.6818C392.481 72.5093 390.216 73.9697 387.395 75.0812L387.388 75.0841C384.589 76.152 381.143 76.672 377.073 76.672H363.345V93.3468C363.345 94.5647 362.897 95.6139 362.018 96.4503C361.2 97.2792 360.179 97.6974 359 97.6974C357.813 97.6973 356.786 97.2729 355.965 96.4318C355.145 95.5914 354.736 94.548 354.736 93.3468V43.6642C354.736 42.463 355.145 41.4196 355.965 40.5792C356.779 39.6913 357.804 39.2317 359 39.2316H377.073ZM363.345 68.295H376.36C380.271 68.295 383.177 67.7578 385.147 66.7521C387.166 65.6658 388.491 64.3569 389.203 62.8497C389.956 61.2025 390.325 59.5717 390.326 57.9523C390.326 56.2735 389.954 54.643 389.203 53.0548C388.493 51.5512 387.172 50.2695 385.157 49.2374L385.145 49.2306C383.179 48.1733 380.274 47.6095 376.36 47.6095H363.345V68.295Z" fill="#5770FF" stroke="#5770FF" stroke-width="1.39574"/>
<rect x="7.14288" y="39.2857" width="75" height="53.5714" fill="#C1830D"/>
<path d="M3.57144 15.6832C3.57144 14.9114 4.19713 14.2857 4.96896 14.2857H84.3168C85.0886 14.2857 85.7143 14.9114 85.7143 15.6832V32.1428H3.57144V15.6832Z" fill="#5770FF"/>
<rect x="2.09627" y="12.8106" width="85.0932" height="85.0932" rx="2.09627" stroke="white" stroke-width="4.19255"/>
<line y1="35.0155" x2="89.2857" y2="35.0155" stroke="white" stroke-width="1.39752"/>
<rect x="19.2546" y="1.39752" width="9.53118" height="20.1191" rx="2.79503" fill="#C1830D" stroke="white" stroke-width="2.79503"/>
<rect x="58.5403" y="1.39752" width="9.53118" height="20.1191" rx="2.79503" fill="#C1830D" stroke="white" stroke-width="2.79503"/>
<path d="M84.6845 32.1428C85.9796 32.1428 87.0703 32.5641 87.9565 33.4066C88.8426 34.2492 89.2857 35.2862 89.2857 36.5176V95.528C89.2857 96.7594 88.8426 97.7964 87.9565 98.6389C87.0703 99.5463 85.9796 100 84.6845 100H43.6824C42.4554 100 41.4329 99.5787 40.6149 98.7362C39.7288 97.9584 39.2857 96.9863 39.2857 95.8197C39.2857 94.6531 39.7288 93.6809 40.6149 92.9032C41.4329 92.1254 42.4554 91.7366 43.6824 91.7366H79.981V70.2517H58.7396C57.5126 70.2517 56.4901 69.8304 55.6721 68.9879C54.786 68.2102 54.3429 67.238 54.3429 66.0714C54.3429 64.9048 54.786 63.9326 55.6721 63.1549C56.4901 62.3772 57.5126 61.9883 58.7396 61.9883H79.981V40.4062L43.6824 40.4062C42.4554 40.4062 41.4329 39.985 40.6149 39.1424C39.7288 38.3647 39.2857 37.3925 39.2857 36.2259C39.2857 35.0593 39.7288 34.0872 40.6149 33.3094C41.4329 32.5317 42.4554 32.1428 43.6824 32.1428H84.6845Z" fill="white"/>
<path d="M4.60123 100C3.30607 100 2.21541 99.5788 1.32924 98.7362C0.443082 97.8937 0 96.8567 0 95.6253V36.6148C0 35.3834 0.443082 34.3465 1.32924 33.5039C2.21541 32.5966 3.30607 32.1429 4.60123 32.1429H45.6033C46.8303 32.1429 47.8528 32.5642 48.6708 33.4067C49.5569 34.1844 50 35.1566 50 36.3232C50 37.4898 49.5569 38.462 48.6708 39.2397C47.8528 40.0174 46.8303 40.4063 45.6033 40.4063H9.3047V61.8911H30.5461C31.7731 61.8911 32.7956 62.3124 33.6136 63.155C34.4997 63.9327 34.9428 64.9049 34.9428 66.0715C34.9428 67.2381 34.4997 68.2102 33.6136 68.988C32.7956 69.7657 31.7731 70.1546 30.5461 70.1546H9.3047V91.7366H45.6033C46.8303 91.7366 47.8528 92.1579 48.6708 93.0004C49.5569 93.7782 50 94.7503 50 95.9169C50 97.0835 49.5569 98.0557 48.6708 98.8334C47.8528 99.6112 46.8303 100 45.6033 100H4.60123Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 8.3 KiB

View file

@ -0,0 +1,17 @@
<svg width="402" height="100" viewBox="0 0 402 100" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M234.931 38.9532C235.883 38.9532 236.684 39.3271 237.335 40.0751C237.987 40.8231 238.312 41.7437 238.312 42.8369C238.312 44.8361 236.815 46.2891 234.796 46.2891L171.031 46.3754C170.129 46.3754 169.378 46.0014 168.777 45.2535C168.126 44.563 167.8 43.7 167.8 42.6643C167.8 41.6286 168.126 40.7656 168.777 40.0751C169.378 39.3847 170.129 39.0395 171.031 39.0395L234.931 38.9532Z" fill="black"/>
<path d="M104.461 93.0499C103.487 93.0499 102.666 92.7092 102 92.0278C101.333 91.3463 101 90.5077 101 89.5117V42.5722C101 41.1569 101.487 39.9513 102.461 38.9554C103.436 37.907 104.615 37.3829 105.999 37.3829H108.538C109.563 37.3829 110.512 37.6974 111.383 38.3264C112.255 38.9554 112.871 39.7416 113.229 40.6852L130.689 85.1873L148.149 40.6852C148.559 39.7416 149.174 38.9554 149.995 38.3264C150.866 37.6974 151.815 37.3829 152.841 37.3829H155.379C156.763 37.3829 157.943 37.907 158.917 38.9554C159.891 39.9513 160.378 41.1569 160.378 42.5722V89.5117C160.378 90.5077 160.045 91.3463 159.378 92.0278C158.712 92.7092 157.891 93.0499 156.917 93.0499C155.943 93.0499 155.097 92.7092 154.379 92.0278C153.712 91.3463 153.379 90.5077 153.379 89.5117V44.8523L135.612 89.7476C135.201 90.7436 134.56 91.556 133.689 92.185C132.817 92.7616 131.817 93.0499 130.689 93.0499C129.561 93.0499 128.561 92.7616 127.689 92.185C126.818 91.556 126.177 90.7436 125.767 89.7476L107.999 44.8523V89.5117C107.999 90.5077 107.64 91.3463 106.922 92.0278C106.256 92.7092 105.435 93.0499 104.461 93.0499Z" fill="black"/>
<path d="M234.931 61.2199C235.883 61.2199 236.684 61.5939 237.335 62.3419C237.987 63.0899 238.312 64.0105 238.312 65.1037C238.312 67.1029 236.815 68.5559 234.796 68.5559L171.031 68.6422C170.129 68.6422 169.378 68.2682 168.777 67.5202C168.126 66.8298 167.8 65.9667 167.8 64.9311C167.8 63.8954 168.126 63.0324 168.777 62.3419C169.378 61.6515 170.129 61.3062 171.031 61.3062L234.931 61.2199Z" fill="#E69D11"/>
<path d="M234.931 85.6277C235.883 85.6277 236.684 86.0016 237.335 86.7496C237.987 87.4976 238.312 88.4182 238.312 89.5114C238.312 91.5106 236.815 92.9636 234.796 92.9636L171.031 93.0499C170.129 93.0499 169.378 92.6759 168.777 91.928C168.126 91.2375 167.8 90.3745 167.8 89.3388C167.8 88.3031 168.126 87.4401 168.777 86.7496C169.378 86.0592 170.129 85.714 171.031 85.714L234.931 85.6277Z" fill="black"/>
<path d="M267.963 93.0499C266.995 93.0499 266.181 92.7068 265.519 92.0205C264.857 91.3342 264.526 90.4896 264.526 89.4866V44.1136H248.943C248.026 44.1136 247.262 43.7969 246.651 43.1634C246.04 42.5299 245.734 41.738 245.734 40.7878C245.734 39.8376 246.04 39.0458 246.651 38.4123C247.262 37.726 248.026 37.3829 248.943 37.3829H286.983C287.9 37.3829 288.664 37.726 289.275 38.4123C289.937 39.0458 290.268 39.8376 290.268 40.7878C290.268 41.738 289.937 42.5299 289.275 43.1634C288.664 43.7969 287.9 44.1136 286.983 44.1136H271.477V89.4866C271.477 90.4896 271.12 91.3342 270.407 92.0205C269.745 92.7068 268.931 93.0499 267.963 93.0499Z" fill="black"/>
<path d="M338.498 3.30273C339.9 3.29168 341.204 4.05009 342.504 5.35547C344.287 7.14689 347.48 10.3467 350.621 13.4922L358.434 21.3037L358.456 21.3252L358.476 21.3486C359.393 22.4377 359.772 23.5909 359.703 24.6758C359.635 25.7528 359.129 26.695 358.402 27.375C356.958 28.7257 354.528 29.1152 352.683 27.4297L352.669 27.417L352.655 27.4033C350.775 25.4925 347.992 22.7063 345.677 20.3965C344.519 19.2419 343.48 18.2064 342.729 17.46C342.722 17.4528 342.715 17.4456 342.708 17.4385V74.9961C342.708 78.7908 342.028 82.1326 340.646 85.0029L340.647 85.0039C339.33 87.7947 337.557 90.1328 335.328 92.0059L335.32 92.0117C333.107 93.8166 330.654 95.1582 327.965 96.0342C325.293 96.9042 322.639 97.3428 320.005 97.3428C317.371 97.3428 314.716 96.9042 312.045 96.0342C309.355 95.1582 306.902 93.8166 304.689 92.0117L304.682 92.0059C302.455 90.1348 300.659 87.8002 299.29 85.0137L299.287 85.0068L299.283 84.999C297.955 82.13 297.302 78.7894 297.302 74.9961V43.5576C297.302 42.4529 297.649 41.4822 298.35 40.6836L298.494 40.5264C299.284 39.6526 300.283 39.1983 301.45 39.1982C302.613 39.1982 303.609 39.6498 304.397 40.5176C305.245 41.3395 305.675 42.3674 305.675 43.5576V75.2344C305.675 78.4181 306.366 81.0359 307.705 83.126C309.12 85.2003 310.917 86.7601 313.102 87.8184H313.101C315.307 88.8345 317.606 89.3408 320.005 89.3408C322.403 89.3408 324.702 88.8342 326.908 87.8184L327.312 87.6143C329.312 86.5634 330.947 85.0716 332.226 83.1289L332.228 83.126C333.618 81.0358 334.335 78.4183 334.335 75.2344V17.3291C333.656 18.0124 332.73 18.9438 331.672 20.0059C329.454 22.232 326.655 25.0349 324.336 27.3389L324.326 27.3486L324.315 27.3584C320.384 30.9544 315.024 25.7542 318.168 21.7617L318.193 21.7285L318.224 21.6982C321.362 18.5764 323.629 16.2939 326.017 13.8896C328.405 11.4851 330.915 8.95892 334.54 5.35254C335.811 4.08795 337.1 3.31376 338.498 3.30273Z" fill="#4154C0" stroke="#4154C0" stroke-width="1.39574"/>
<path d="M377.073 39.2316C381.146 39.2316 384.597 39.7797 387.4 40.9054H387.399C390.214 41.961 392.474 43.418 394.146 45.295C395.846 47.0923 397.064 49.0974 397.785 51.3077L397.924 51.7179C398.597 53.7677 398.935 55.8467 398.935 57.9523C398.935 60.1981 398.55 62.4136 397.785 64.5958C397.109 66.6659 395.999 68.5781 394.466 70.3322L394.154 70.6818C392.481 72.5093 390.216 73.9697 387.395 75.0812L387.388 75.0841C384.589 76.152 381.143 76.672 377.073 76.672H363.345V93.3468C363.345 94.5647 362.897 95.6139 362.018 96.4503C361.2 97.2792 360.179 97.6974 359 97.6974C357.813 97.6973 356.786 97.2729 355.965 96.4318C355.145 95.5914 354.736 94.548 354.736 93.3468V43.6642C354.736 42.463 355.145 41.4196 355.965 40.5792C356.779 39.6913 357.804 39.2317 359 39.2316H377.073ZM363.345 68.295H376.36C380.271 68.295 383.177 67.7578 385.147 66.7521C387.166 65.6658 388.491 64.3569 389.203 62.8497C389.956 61.2025 390.325 59.5717 390.326 57.9523C390.326 56.2735 389.954 54.643 389.203 53.0548C388.493 51.5512 387.172 50.2695 385.157 49.2374L385.145 49.2306C383.179 48.1733 380.274 47.6095 376.36 47.6095H363.345V68.295Z" fill="#4154C0" stroke="#4154C0" stroke-width="1.39574"/>
<rect x="7.14288" y="39.2857" width="75" height="53.5714" fill="#E69D11"/>
<path d="M3.57144 15.6832C3.57144 14.9114 4.19713 14.2857 4.96896 14.2857H84.3168C85.0886 14.2857 85.7143 14.9114 85.7143 15.6832V32.1428H3.57144V15.6832Z" fill="#4154C0"/>
<rect x="2.09627" y="12.8106" width="85.0932" height="85.0932" rx="2.09627" stroke="black" stroke-width="4.19255"/>
<line y1="35.0155" x2="89.2857" y2="35.0155" stroke="black" stroke-width="1.39752"/>
<rect x="19.2546" y="1.39752" width="9.53118" height="20.1191" rx="2.79503" fill="#E69D11" stroke="black" stroke-width="2.79503"/>
<rect x="58.5403" y="1.39752" width="9.53118" height="20.1191" rx="2.79503" fill="#E69D11" stroke="black" stroke-width="2.79503"/>
<path d="M84.6845 32.1428C85.9796 32.1428 87.0703 32.5641 87.9565 33.4066C88.8426 34.2492 89.2857 35.2862 89.2857 36.5176V95.528C89.2857 96.7594 88.8426 97.7964 87.9565 98.6389C87.0703 99.5463 85.9796 100 84.6845 100H43.6824C42.4554 100 41.4329 99.5787 40.6149 98.7362C39.7288 97.9584 39.2857 96.9863 39.2857 95.8197C39.2857 94.6531 39.7288 93.6809 40.6149 92.9032C41.4329 92.1254 42.4554 91.7366 43.6824 91.7366H79.981V70.2517H58.7396C57.5126 70.2517 56.4901 69.8304 55.6721 68.9879C54.786 68.2102 54.3429 67.238 54.3429 66.0714C54.3429 64.9048 54.786 63.9326 55.6721 63.1549C56.4901 62.3772 57.5126 61.9883 58.7396 61.9883H79.981V40.4062L43.6824 40.4062C42.4554 40.4062 41.4329 39.985 40.6149 39.1424C39.7288 38.3647 39.2857 37.3925 39.2857 36.2259C39.2857 35.0593 39.7288 34.0872 40.6149 33.3094C41.4329 32.5317 42.4554 32.1428 43.6824 32.1428H84.6845Z" fill="black"/>
<path d="M4.60123 100C3.30607 100 2.21541 99.5788 1.32924 98.7362C0.443082 97.8937 0 96.8567 0 95.6253V36.6148C0 35.3834 0.443082 34.3465 1.32924 33.5039C2.21541 32.5966 3.30607 32.1429 4.60123 32.1429H45.6033C46.8303 32.1429 47.8528 32.5642 48.6708 33.4067C49.5569 34.1844 50 35.1566 50 36.3232C50 37.4898 49.5569 38.462 48.6708 39.2397C47.8528 40.0174 46.8303 40.4063 45.6033 40.4063H9.3047V61.8911H30.5461C31.7731 61.8911 32.7956 62.3124 33.6136 63.155C34.4997 63.9327 34.9428 64.9049 34.9428 66.0715C34.9428 67.2381 34.4997 68.2102 33.6136 68.988C32.7956 69.7657 31.7731 70.1546 30.5461 70.1546H9.3047V91.7366H45.6033C46.8303 91.7366 47.8528 92.1579 48.6708 93.0004C49.5569 93.7782 50 94.7503 50 95.9169C50 97.0835 49.5569 98.0557 48.6708 98.8334C47.8528 99.6112 46.8303 100 45.6033 100H4.60123Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 8.3 KiB

View file

@ -0,0 +1,10 @@
<svg width="90" height="100" viewBox="0 0 90 100" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="7.14285" y="39.2857" width="75" height="53.5714" fill="#C1830D"/>
<path d="M3.57141 15.6832C3.57141 14.9114 4.1971 14.2857 4.96893 14.2857H84.3168C85.0886 14.2857 85.7143 14.9114 85.7143 15.6832V32.1429H3.57141V15.6832Z" fill="#5770FF"/>
<rect x="2.09627" y="12.8106" width="85.0932" height="85.0932" rx="2.09627" stroke="white" stroke-width="4.19255"/>
<line y1="35.0156" x2="89.2857" y2="35.0156" stroke="white" stroke-width="1.39752"/>
<rect x="19.2546" y="1.39752" width="9.53118" height="20.1191" rx="2.79503" fill="#C1830D" stroke="white" stroke-width="2.79503"/>
<rect x="58.5403" y="1.39752" width="9.53118" height="20.1191" rx="2.79503" fill="#C1830D" stroke="white" stroke-width="2.79503"/>
<path d="M84.6844 32.1429C85.9796 32.1429 87.0702 32.5642 87.9564 33.4067C88.8426 34.2492 89.2856 35.2862 89.2856 36.5176V95.5281C89.2856 96.7595 88.8426 97.7965 87.9564 98.639C87.0702 99.5464 85.9796 100 84.6844 100H43.6824C42.4554 100 41.4329 99.5788 40.6149 98.7362C39.7287 97.9585 39.2856 96.9863 39.2856 95.8197C39.2856 94.6531 39.7287 93.681 40.6149 92.9032C41.4329 92.1255 42.4554 91.7366 43.6824 91.7366H79.9809V70.2518H58.7396C57.5126 70.2518 56.4901 69.8305 55.6721 68.988C54.7859 68.2102 54.3428 67.2381 54.3428 66.0715C54.3428 64.9049 54.7859 63.9327 55.6721 63.155C56.4901 62.3772 57.5126 61.9884 58.7396 61.9884H79.9809V40.4063L43.6824 40.4063C42.4554 40.4063 41.4329 39.985 40.6149 39.1425C39.7287 38.3647 39.2856 37.3926 39.2856 36.226C39.2856 35.0594 39.7287 34.0872 40.6149 33.3095C41.4329 32.5318 42.4554 32.1429 43.6824 32.1429H84.6844Z" fill="white"/>
<path d="M4.60123 100C3.30607 100 2.21541 99.5787 1.32924 98.7362C0.443082 97.8936 0 96.8567 0 95.6252V36.6148C0 35.3834 0.443082 34.3464 1.32924 33.5039C2.21541 32.5965 3.30607 32.1429 4.60123 32.1429H45.6033C46.8303 32.1429 47.8528 32.5641 48.6708 33.4067C49.5569 34.1844 50 35.1566 50 36.3232C50 37.4898 49.5569 38.4619 48.6708 39.2397C47.8528 40.0174 46.8303 40.4063 45.6033 40.4063H9.3047V61.8911H30.5461C31.7731 61.8911 32.7956 62.3124 33.6136 63.1549C34.4997 63.9327 34.9428 64.9048 34.9428 66.0714C34.9428 67.238 34.4997 68.2102 33.6136 68.9879C32.7956 69.7657 31.7731 70.1545 30.5461 70.1545H9.3047V91.7366H45.6033C46.8303 91.7366 47.8528 92.1579 48.6708 93.0004C49.5569 93.7781 50 94.7503 50 95.9169C50 97.0835 49.5569 98.0557 48.6708 98.8334C47.8528 99.6111 46.8303 100 45.6033 100H4.60123Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

View file

@ -0,0 +1,10 @@
<svg width="90" height="100" viewBox="0 0 90 100" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="7.14285" y="39.2857" width="75" height="53.5714" fill="#E69D11"/>
<path d="M3.57141 15.6832C3.57141 14.9114 4.1971 14.2857 4.96893 14.2857H84.3168C85.0886 14.2857 85.7143 14.9114 85.7143 15.6832V32.1429H3.57141V15.6832Z" fill="#4154C0"/>
<rect x="2.09627" y="12.8106" width="85.0932" height="85.0932" rx="2.09627" stroke="black" stroke-width="4.19255"/>
<line y1="35.0156" x2="89.2857" y2="35.0156" stroke="black" stroke-width="1.39752"/>
<rect x="19.2546" y="1.39752" width="9.53118" height="20.1191" rx="2.79503" fill="#E69D11" stroke="black" stroke-width="2.79503"/>
<rect x="58.5403" y="1.39752" width="9.53118" height="20.1191" rx="2.79503" fill="#E69D11" stroke="black" stroke-width="2.79503"/>
<path d="M84.6844 32.1429C85.9796 32.1429 87.0702 32.5642 87.9564 33.4067C88.8426 34.2492 89.2856 35.2862 89.2856 36.5176V95.5281C89.2856 96.7595 88.8426 97.7965 87.9564 98.639C87.0702 99.5464 85.9796 100 84.6844 100H43.6824C42.4554 100 41.4329 99.5788 40.6149 98.7362C39.7287 97.9585 39.2856 96.9863 39.2856 95.8197C39.2856 94.6531 39.7287 93.681 40.6149 92.9032C41.4329 92.1255 42.4554 91.7366 43.6824 91.7366H79.9809V70.2518H58.7396C57.5126 70.2518 56.4901 69.8305 55.6721 68.988C54.7859 68.2102 54.3428 67.2381 54.3428 66.0715C54.3428 64.9049 54.7859 63.9327 55.6721 63.155C56.4901 62.3772 57.5126 61.9884 58.7396 61.9884H79.9809V40.4063L43.6824 40.4063C42.4554 40.4063 41.4329 39.985 40.6149 39.1425C39.7287 38.3647 39.2856 37.3926 39.2856 36.226C39.2856 35.0594 39.7287 34.0872 40.6149 33.3095C41.4329 32.5318 42.4554 32.1429 43.6824 32.1429H84.6844Z" fill="black"/>
<path d="M4.60123 100C3.30607 100 2.21541 99.5787 1.32924 98.7362C0.443082 97.8936 0 96.8567 0 95.6252V36.6148C0 35.3834 0.443082 34.3464 1.32924 33.5039C2.21541 32.5965 3.30607 32.1429 4.60123 32.1429H45.6033C46.8303 32.1429 47.8528 32.5641 48.6708 33.4067C49.5569 34.1844 50 35.1566 50 36.3232C50 37.4898 49.5569 38.4619 48.6708 39.2397C47.8528 40.0174 46.8303 40.4063 45.6033 40.4063H9.3047V61.8911H30.5461C31.7731 61.8911 32.7956 62.3124 33.6136 63.1549C34.4997 63.9327 34.9428 64.9048 34.9428 66.0714C34.9428 67.238 34.4997 68.2102 33.6136 68.9879C32.7956 69.7657 31.7731 70.1545 30.5461 70.1545H9.3047V91.7366H45.6033C46.8303 91.7366 47.8528 92.1579 48.6708 93.0004C49.5569 93.7781 50 94.7503 50 95.9169C50 97.0835 49.5569 98.0557 48.6708 98.8334C47.8528 99.6111 46.8303 100 45.6033 100H4.60123Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

View file

@ -0,0 +1,31 @@
import { Button } from '@/components/ui/button';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import { NDot, NotificationDot } from '@/components/misc/notification-dot';
export function NotificationButton({
dotVariant,
children,
...props
}: {
dotVariant?: NDot;
children: React.ReactNode;
} & React.ComponentProps<typeof Button>) {
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button type='button' variant='outline_primary' {...props}>
{children}
<NotificationDot
dotVariant={dotVariant}
className='absolute ml-[30px] mt-[30px]'
/>
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align='end'></DropdownMenuContent>
</DropdownMenu>
);
}

View file

@ -0,0 +1,131 @@
'use client';
import React from 'react';
import {
Sidebar,
SidebarContent,
SidebarFooter,
SidebarGroup,
SidebarGroupContent,
SidebarGroupLabel,
SidebarHeader,
SidebarMenu,
SidebarMenuButton,
SidebarMenuItem,
} from '@/components/custom-ui/sidebar';
import { ChevronDown } from 'lucide-react';
import {
Collapsible,
CollapsibleContent,
CollapsibleTrigger,
} from '@/components/ui/collapsible';
import Logo from '@/components/misc/logo';
import Link from 'next/link';
import {
Star,
CalendarDays,
User,
Users,
CalendarClock,
CalendarPlus,
} from 'lucide-react';
const items = [
{
title: 'Calendar',
url: '#',
icon: CalendarDays,
},
{
title: 'Friends',
url: '#',
icon: User,
},
{
title: 'Groups',
url: '#',
icon: Users,
},
{
title: 'Events',
url: '#',
icon: CalendarClock,
},
];
export function AppSidebar() {
return (
<>
<Sidebar collapsible='icon' variant='sidebar'>
<SidebarHeader className='overflow-hidden'>
<Logo
colorType='colored'
logoType='combo'
height={50}
className='group-data-[collapsible=icon]:hidden min-w-[203px]'
></Logo>
<Logo
colorType='colored'
logoType='submark'
height={50}
className='group-data-[collapsible=]:hidden group-data-[mobile=true]/mobile:hidden'
></Logo>
</SidebarHeader>
<SidebarContent className='grid grid-rows-[auto_1fr_auto]'>
<Collapsible defaultOpen className='group/collapsible'>
<SidebarGroup>
<SidebarGroupLabel asChild>
<CollapsibleTrigger>
<span className='flex items-center gap-2 text-xl font-label text-neutral-100'>
<Star className='size-8' />{' '}
<span className='group-data-[collapsible=icon]:hidden'>
Favorites
</span>
</span>
<ChevronDown className='ml-auto transition-transform group-data-[state=open]/collapsible:rotate-180 group-data-[collapsible=icon]:hidden text-nowrap whitespace-nowrap' />
</CollapsibleTrigger>
</SidebarGroupLabel>
<CollapsibleContent>
<SidebarGroupContent />
</CollapsibleContent>
</SidebarGroup>
</Collapsible>
<SidebarGroupContent>
<SidebarMenu>
{items.map((item) => (
<SidebarMenuItem key={item.title} className='pt-2'>
<SidebarMenuButton asChild>
<Link href={item.url}>
<item.icon className='size-8' />
<span className='text-xl font-label group-data-[collapsible=icon]:hidden text-nowrap whitespace-nowrap'>
{item.title}
</span>
</Link>
</SidebarMenuButton>
</SidebarMenuItem>
))}
</SidebarMenu>
</SidebarGroupContent>
<SidebarFooter>
<SidebarMenuItem className='pl-[8px]'>
<Link
href='/event/new'
className='flex items-center gap-2 text-xl font-label'
>
<CalendarPlus className='size-8' />
<span className='group-data-[collapsible=icon]:hidden text-nowrap whitespace-nowrap'>
New Event
</span>
</Link>
</SidebarMenuItem>
</SidebarFooter>
</SidebarContent>
</Sidebar>
</>
);
}

View file

@ -0,0 +1,725 @@
'use client';
import * as React from 'react';
import { Slot } from '@radix-ui/react-slot';
import { cva, VariantProps } from 'class-variance-authority';
import { PanelLeftIcon } from 'lucide-react';
import { useIsMobile } from '@/hooks/use-mobile';
import { cn } from '@/lib/utils';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Separator } from '@/components/ui/separator';
import {
Sheet,
SheetContent,
SheetDescription,
SheetHeader,
SheetTitle,
} from '@/components/ui/sheet';
import { Skeleton } from '@/components/ui/skeleton';
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from '@/components/ui/tooltip';
const SIDEBAR_COOKIE_NAME = 'sidebar_state';
const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7;
const SIDEBAR_WIDTH = '16rem';
const SIDEBAR_WIDTH_MOBILE = '18rem';
const SIDEBAR_WIDTH_ICON = '4rem';
const SIDEBAR_KEYBOARD_SHORTCUT = 'b';
type SidebarContextProps = {
state: 'expanded' | 'collapsed';
open: boolean;
setOpen: (open: boolean) => void;
openMobile: boolean;
setOpenMobile: (open: boolean) => void;
isMobile: boolean;
toggleSidebar: () => void;
};
const SidebarContext = React.createContext<SidebarContextProps | null>(null);
function useSidebar() {
const context = React.useContext(SidebarContext);
if (!context) {
throw new Error('useSidebar must be used within a SidebarProvider.');
}
return context;
}
function SidebarProvider({
defaultOpen = true,
open: openProp,
onOpenChange: setOpenProp,
className,
style,
children,
...props
}: React.ComponentProps<'div'> & {
defaultOpen?: boolean;
open?: boolean;
onOpenChange?: (open: boolean) => void;
}) {
const isMobile = useIsMobile();
const [openMobile, setOpenMobile] = React.useState(false);
// This is the internal state of the sidebar.
// We use openProp and setOpenProp for control from outside the component.
const [_open, _setOpen] = React.useState(defaultOpen);
const open = openProp ?? _open;
const setOpen = React.useCallback(
(value: boolean | ((value: boolean) => boolean)) => {
const openState = typeof value === 'function' ? value(open) : value;
if (setOpenProp) {
setOpenProp(openState);
} else {
_setOpen(openState);
}
// This sets the cookie to keep the sidebar state.
document.cookie = `${SIDEBAR_COOKIE_NAME}=${openState}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`;
},
[setOpenProp, open],
);
// Helper to toggle the sidebar.
const toggleSidebar = React.useCallback(() => {
return isMobile ? setOpenMobile((open) => !open) : setOpen((open) => !open);
}, [isMobile, setOpen, setOpenMobile]);
// Adds a keyboard shortcut to toggle the sidebar.
React.useEffect(() => {
const handleKeyDown = (event: KeyboardEvent) => {
if (
event.key === SIDEBAR_KEYBOARD_SHORTCUT &&
(event.metaKey || event.ctrlKey)
) {
event.preventDefault();
toggleSidebar();
}
};
window.addEventListener('keydown', handleKeyDown);
return () => window.removeEventListener('keydown', handleKeyDown);
}, [toggleSidebar]);
// We add a state so that we can do data-state="expanded" or "collapsed".
// This makes it easier to style the sidebar with Tailwind classes.
const state = open ? 'expanded' : 'collapsed';
const contextValue = React.useMemo<SidebarContextProps>(
() => ({
state,
open,
setOpen,
isMobile,
openMobile,
setOpenMobile,
toggleSidebar,
}),
[state, open, setOpen, isMobile, openMobile, setOpenMobile, toggleSidebar],
);
return (
<SidebarContext.Provider value={contextValue}>
<TooltipProvider delayDuration={0}>
<div
data-slot='sidebar-wrapper'
style={
{
'--sidebar-width': SIDEBAR_WIDTH,
'--sidebar-width-icon': SIDEBAR_WIDTH_ICON,
...style,
} as React.CSSProperties
}
className={cn(
'group/sidebar-wrapper has-data-[variant=inset]:bg-sidebar flex min-h-svh w-full',
className,
)}
{...props}
>
{children}
</div>
</TooltipProvider>
</SidebarContext.Provider>
);
}
function Sidebar({
side = 'left',
variant = 'sidebar',
collapsible = 'offcanvas',
className,
children,
...props
}: React.ComponentProps<'div'> & {
side?: 'left' | 'right';
variant?: 'sidebar' | 'floating' | 'inset';
collapsible?: 'offcanvas' | 'icon' | 'none';
}) {
const { isMobile, state, openMobile, setOpenMobile } = useSidebar();
if (collapsible === 'none') {
return (
<div
data-slot='sidebar'
className={cn(
'bg-sidebar text-sidebar-foreground flex h-full w-(--sidebar-width) flex-col',
className,
)}
{...props}
>
{children}
</div>
);
}
if (isMobile) {
return (
<Sheet open={openMobile} onOpenChange={setOpenMobile} {...props}>
<SheetContent
data-sidebar='sidebar'
data-slot='sidebar'
data-mobile='true'
className='bg-sidebar text-sidebar-foreground w-(--sidebar-width) p-0 [&>button]:hidden group/mobile'
style={
{
'--sidebar-width': SIDEBAR_WIDTH_MOBILE,
} as React.CSSProperties
}
side={side}
>
<SheetHeader className='sr-only'>
<SheetTitle>Sidebar</SheetTitle>
<SheetDescription>Displays the mobile sidebar.</SheetDescription>
</SheetHeader>
<div className='flex h-full w-full flex-col'>{children}</div>
</SheetContent>
</Sheet>
);
}
return (
<div
className='group peer text-sidebar-foreground hidden md:block'
data-state={state}
data-collapsible={state === 'collapsed' ? collapsible : ''}
data-variant={variant}
data-side={side}
data-slot='sidebar'
>
{/* This is what handles the sidebar gap on desktop */}
<div
data-slot='sidebar-gap'
className={cn(
'relative w-(--sidebar-width) bg-transparent transition-[width] duration-200 ease-linear',
'group-data-[collapsible=offcanvas]:w-0',
'group-data-[side=right]:rotate-180',
variant === 'floating' || variant === 'inset'
? 'group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]'
: 'group-data-[collapsible=icon]:w-(--sidebar-width-icon)',
)}
/>
<div
data-slot='sidebar-container'
className={cn(
'fixed inset-y-0 z-10 hidden h-svh w-(--sidebar-width) transition-[left,right,width] duration-200 ease-linear md:flex',
side === 'left'
? 'left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]'
: 'right-0 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]',
// Adjust the padding for floating and inset variants.
variant === 'floating' || variant === 'inset'
? 'p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]'
: 'group-data-[collapsible=icon]:w-(--sidebar-width-icon) group-data-[side=left]:border-r group-data-[side=right]:border-l',
className,
)}
{...props}
>
<div
data-sidebar='sidebar'
data-slot='sidebar-inner'
className='bg-sidebar group-data-[variant=floating]:border-sidebar-border flex h-full w-full flex-col group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:shadow-sm'
>
{children}
</div>
</div>
</div>
);
}
function SidebarTrigger({
className,
onClick,
...props
}: React.ComponentProps<typeof Button>) {
const { toggleSidebar } = useSidebar();
return (
<Button
data-sidebar='trigger'
data-slot='sidebar-trigger'
variant='muted'
size='icon'
className={cn('', className)}
onClick={(event) => {
onClick?.(event);
toggleSidebar();
}}
{...props}
>
<PanelLeftIcon />
<span className='sr-only'>Toggle Sidebar</span>
</Button>
);
}
function SidebarRail({ className, ...props }: React.ComponentProps<'button'>) {
const { toggleSidebar } = useSidebar();
return (
<button
data-sidebar='rail'
data-slot='sidebar-rail'
aria-label='Toggle Sidebar'
tabIndex={-1}
onClick={toggleSidebar}
title='Toggle Sidebar'
className={cn(
'hover:after:bg-sidebar-border absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-all ease-linear group-data-[side=left]:-right-4 group-data-[side=right]:left-0 after:absolute after:inset-y-0 after:left-1/2 after:w-[2px] sm:flex',
'in-data-[side=left]:cursor-w-resize in-data-[side=right]:cursor-e-resize',
'[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize',
'hover:group-data-[collapsible=offcanvas]:bg-sidebar group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full',
'[[data-side=left][data-collapsible=offcanvas]_&]:-right-2',
'[[data-side=right][data-collapsible=offcanvas]_&]:-left-2',
className,
)}
{...props}
/>
);
}
function SidebarInset({ className, ...props }: React.ComponentProps<'main'>) {
return (
<main
data-slot='sidebar-inset'
className={cn(
'bg-background relative flex w-full flex-1 flex-col',
'md:peer-data-[variant=inset]:m-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow-sm md:peer-data-[variant=inset]:peer-data-[state=collapsed]:ml-2',
className,
)}
{...props}
/>
);
}
function SidebarInput({
className,
...props
}: React.ComponentProps<typeof Input>) {
return (
<Input
data-slot='sidebar-input'
data-sidebar='input'
className={cn('bg-background h-8 w-full shadow-none', className)}
{...props}
/>
);
}
function SidebarHeader({ className, ...props }: React.ComponentProps<'div'>) {
return (
<div
data-slot='sidebar-header'
data-sidebar='header'
className={cn('flex flex-col gap-2 p-2', className)}
{...props}
/>
);
}
function SidebarFooter({ className, ...props }: React.ComponentProps<'div'>) {
return (
<div
data-slot='sidebar-footer'
data-sidebar='footer'
className={cn('flex flex-col gap-2 p-2', className)}
{...props}
/>
);
}
function SidebarSeparator({
className,
...props
}: React.ComponentProps<typeof Separator>) {
return (
<Separator
data-slot='sidebar-separator'
data-sidebar='separator'
className={cn('bg-sidebar-border mx-2 w-auto', className)}
{...props}
/>
);
}
function SidebarContent({ className, ...props }: React.ComponentProps<'div'>) {
return (
<div
data-slot='sidebar-content'
data-sidebar='content'
className={cn(
'flex min-h-0 flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden',
className,
)}
{...props}
/>
);
}
function SidebarGroup({ className, ...props }: React.ComponentProps<'div'>) {
return (
<div
data-slot='sidebar-group'
data-sidebar='group'
className={cn('relative flex w-full min-w-0 flex-col p-2', className)}
{...props}
/>
);
}
function SidebarGroupLabel({
className,
asChild = false,
...props
}: React.ComponentProps<'div'> & { asChild?: boolean }) {
const Comp = asChild ? Slot : 'div';
return (
<Comp
data-slot='sidebar-group-label'
data-sidebar='group-label'
className={cn(
'text-sidebar-foreground/70 ring-sidebar-ring flex h-8 shrink-0 items-center rounded-md text-xs font-medium outline-hidden transition-[margin,opacity] duration-200 ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0 ml-[7.5px]',
className,
)}
{...props}
/>
);
}
function SidebarGroupAction({
className,
asChild = false,
...props
}: React.ComponentProps<'button'> & { asChild?: boolean }) {
const Comp = asChild ? Slot : 'button';
return (
<Comp
data-slot='sidebar-group-action'
data-sidebar='group-action'
className={cn(
'text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground absolute top-3.5 right-3 flex aspect-square w-5 items-center justify-center rounded-md p-0 outline-hidden transition-transform focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0',
// Increases the hit area of the button on mobile.
'after:absolute after:-inset-2 md:after:hidden',
'group-data-[collapsible=icon]:hidden',
className,
)}
{...props}
/>
);
}
function SidebarGroupContent({
className,
...props
}: React.ComponentProps<'div'>) {
return (
<div
data-slot='sidebar-group-content'
data-sidebar='group-content'
className={cn('w-full text-sm', className)}
{...props}
/>
);
}
function SidebarMenu({ className, ...props }: React.ComponentProps<'ul'>) {
return (
<ul
data-slot='sidebar-menu'
data-sidebar='menu'
className={cn('flex w-full min-w-0 flex-col gap-1', className)}
{...props}
/>
);
}
function SidebarMenuItem({ className, ...props }: React.ComponentProps<'li'>) {
return (
<li
data-slot='sidebar-menu-item'
data-sidebar='menu-item'
className={cn('group/menu-item relative list-none', className)}
{...props}
/>
);
}
const sidebarMenuButtonVariants = cva(
'peer/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm outline-hidden ring-sidebar-ring transition-[width,height,padding] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 group-has-data-[sidebar=menu-action]/menu-item:pr-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium data-[active=true]:text-sidebar-accent-foreground data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground group-data-[collapsible=icon]:size-8! p-0 ml-[15.5px] [&>span:last-child]:truncate [&>svg]:shrink-0',
{
variants: {
variant: {
default: 'hover:bg-sidebar-accent hover:text-sidebar-accent-foreground',
outline:
'bg-background shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))]',
},
size: {
default: 'h-8 text-sm',
sm: 'h-7 text-xs',
lg: 'h-12 text-sm group-data-[collapsible=icon]:p-0!',
},
},
defaultVariants: {
variant: 'default',
size: 'default',
},
},
);
function SidebarMenuButton({
asChild = false,
isActive = false,
variant = 'default',
size = 'default',
tooltip,
className,
...props
}: React.ComponentProps<'button'> & {
asChild?: boolean;
isActive?: boolean;
tooltip?: string | React.ComponentProps<typeof TooltipContent>;
} & VariantProps<typeof sidebarMenuButtonVariants>) {
const Comp = asChild ? Slot : 'button';
const { isMobile, state } = useSidebar();
const button = (
<Comp
data-slot='sidebar-menu-button'
data-sidebar='menu-button'
data-size={size}
data-active={isActive}
className={cn(sidebarMenuButtonVariants({ variant, size }), className)}
{...props}
/>
);
if (!tooltip) {
return button;
}
if (typeof tooltip === 'string') {
tooltip = {
children: tooltip,
};
}
return (
<Tooltip>
<TooltipTrigger asChild>{button}</TooltipTrigger>
<TooltipContent
side='right'
align='center'
hidden={state !== 'collapsed' || isMobile}
{...tooltip}
/>
</Tooltip>
);
}
function SidebarMenuAction({
className,
asChild = false,
showOnHover = false,
...props
}: React.ComponentProps<'button'> & {
asChild?: boolean;
showOnHover?: boolean;
}) {
const Comp = asChild ? Slot : 'button';
return (
<Comp
data-slot='sidebar-menu-action'
data-sidebar='menu-action'
className={cn(
'text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground peer-hover/menu-button:text-sidebar-accent-foreground absolute top-1.5 right-1 flex aspect-square w-5 items-center justify-center rounded-md p-0 outline-hidden transition-transform focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0',
// Increases the hit area of the button on mobile.
'after:absolute after:-inset-2 md:after:hidden',
'peer-data-[size=sm]/menu-button:top-1',
'peer-data-[size=default]/menu-button:top-1.5',
'peer-data-[size=lg]/menu-button:top-2.5',
'group-data-[collapsible=icon]:hidden',
showOnHover &&
'peer-data-[active=true]/menu-button:text-sidebar-accent-foreground group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 data-[state=open]:opacity-100 md:opacity-0',
className,
)}
{...props}
/>
);
}
function SidebarMenuBadge({
className,
...props
}: React.ComponentProps<'div'>) {
return (
<div
data-slot='sidebar-menu-badge'
data-sidebar='menu-badge'
className={cn(
'text-sidebar-foreground pointer-events-none absolute right-1 flex h-5 min-w-5 items-center justify-center rounded-md px-1 text-xs font-medium tabular-nums select-none',
'peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[active=true]/menu-button:text-sidebar-accent-foreground',
'peer-data-[size=sm]/menu-button:top-1',
'peer-data-[size=default]/menu-button:top-1.5',
'peer-data-[size=lg]/menu-button:top-2.5',
'group-data-[collapsible=icon]:hidden',
className,
)}
{...props}
/>
);
}
function SidebarMenuSkeleton({
className,
showIcon = false,
...props
}: React.ComponentProps<'div'> & {
showIcon?: boolean;
}) {
// Random width between 50 to 90%.
const width = React.useMemo(() => {
return `${Math.floor(Math.random() * 40) + 50}%`;
}, []);
return (
<div
data-slot='sidebar-menu-skeleton'
data-sidebar='menu-skeleton'
className={cn('flex h-8 items-center gap-2 rounded-md px-2', className)}
{...props}
>
{showIcon && (
<Skeleton
className='size-4 rounded-md'
data-sidebar='menu-skeleton-icon'
/>
)}
<Skeleton
className='h-4 max-w-(--skeleton-width) flex-1'
data-sidebar='menu-skeleton-text'
style={
{
'--skeleton-width': width,
} as React.CSSProperties
}
/>
</div>
);
}
function SidebarMenuSub({ className, ...props }: React.ComponentProps<'ul'>) {
return (
<ul
data-slot='sidebar-menu-sub'
data-sidebar='menu-sub'
className={cn(
'border-sidebar-border mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-l px-2.5 py-0.5',
'group-data-[collapsible=icon]:hidden',
className,
)}
{...props}
/>
);
}
function SidebarMenuSubItem({
className,
...props
}: React.ComponentProps<'li'>) {
return (
<li
data-slot='sidebar-menu-sub-item'
data-sidebar='menu-sub-item'
className={cn('group/menu-sub-item relative', className)}
{...props}
/>
);
}
function SidebarMenuSubButton({
asChild = false,
size = 'md',
isActive = false,
className,
...props
}: React.ComponentProps<'a'> & {
asChild?: boolean;
size?: 'sm' | 'md';
isActive?: boolean;
}) {
const Comp = asChild ? Slot : 'a';
return (
<Comp
data-slot='sidebar-menu-sub-button'
data-sidebar='menu-sub-button'
data-size={size}
data-active={isActive}
className={cn(
'text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground active:bg-sidebar-accent active:text-sidebar-accent-foreground [&>svg]:text-sidebar-accent-foreground flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 outline-hidden focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0',
'data-[active=true]:bg-sidebar-accent data-[active=true]:text-sidebar-accent-foreground',
size === 'sm' && 'text-xs',
size === 'md' && 'text-sm',
'group-data-[collapsible=icon]:hidden',
className,
)}
{...props}
/>
);
}
export {
Sidebar,
SidebarContent,
SidebarFooter,
SidebarGroup,
SidebarGroupAction,
SidebarGroupContent,
SidebarGroupLabel,
SidebarHeader,
SidebarInput,
SidebarInset,
SidebarMenu,
SidebarMenuAction,
SidebarMenuBadge,
SidebarMenuButton,
SidebarMenuItem,
SidebarMenuSkeleton,
SidebarMenuSub,
SidebarMenuSubButton,
SidebarMenuSubItem,
SidebarProvider,
SidebarRail,
SidebarSeparator,
SidebarTrigger,
useSidebar,
};

View file

@ -0,0 +1,51 @@
import { SidebarTrigger } from '@/components/custom-ui/sidebar';
import { ThemePicker } from '@/components/misc/theme-picker';
import { NotificationButton } from '@/components/buttons/notification-button';
import { BellRing, Inbox } from 'lucide-react';
import UserDropdown from '@/components/misc/user-dropdown';
const items = [
{
title: 'Calendar',
url: '#',
icon: Inbox,
},
{
title: 'Friends',
url: '#',
icon: BellRing,
},
];
export default function Header({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<div className='w-full grid grid-rows-[50px_1fr] h-screen'>
<header className='border-b-1 grid-cols-[1fr_3fr_1fr] grid items-center px-2 shadow-md'>
<span className='flex justify-start'>
<SidebarTrigger variant='outline_primary' size='icon' />
</span>
<span className='flex justify-center'>Search</span>
<span className='flex gap-1 justify-end'>
<ThemePicker />
{items.map((item) => (
<NotificationButton
key={item.title}
variant='outline_primary'
dotVariant='hidden'
size='icon'
>
<item.icon />
</NotificationButton>
))}
<UserDropdown />
</span>
</header>
<main>{children}</main>
</div>
);
}

View file

@ -90,6 +90,7 @@ export default function Logo({
return (
<Image
unoptimized
src={logoVar}
alt={alt || defaultAltText}
className={className}

View file

@ -0,0 +1,110 @@
'use client';
import {
BadgeCheck,
Bell,
ChevronsUpDown,
CreditCard,
LogOut,
Sparkles,
} from 'lucide-react';
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import {
SidebarMenu,
SidebarMenuButton,
SidebarMenuItem,
useSidebar,
} from '@/components/custom-ui/sidebar';
export function NavUser({
user,
}: {
user: {
name: string;
email: string;
avatar: string;
};
}) {
const { isMobile } = useSidebar();
return (
<SidebarMenu>
<SidebarMenuItem>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<SidebarMenuButton
size='lg'
className='data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground'
>
<Avatar className='h-8 w-8 rounded-lg'>
<AvatarImage src={user.avatar} alt={user.name} />
<AvatarFallback className='rounded-lg'>CN</AvatarFallback>
</Avatar>
<div className='grid flex-1 text-left text-sm leading-tight'>
<span className='truncate font-medium'>{user.name}</span>
<span className='truncate text-xs'>{user.email}</span>
</div>
<ChevronsUpDown className='ml-auto size-4' />
</SidebarMenuButton>
</DropdownMenuTrigger>
<DropdownMenuContent
className='w-(--radix-dropdown-menu-trigger-width) min-w-56 rounded-lg'
side={isMobile ? 'bottom' : 'right'}
align='end'
sideOffset={4}
>
<DropdownMenuLabel className='p-0 font-normal'>
<div className='flex items-center gap-2 px-1 py-1.5 text-left text-sm'>
<Avatar className='h-8 w-8 rounded-lg'>
<AvatarImage src={user.avatar} alt={user.name} />
<AvatarFallback className='rounded-lg'>CN</AvatarFallback>
</Avatar>
<div className='grid flex-1 text-left text-sm leading-tight'>
<span className='truncate font-medium'>{user.name}</span>
<span className='truncate text-xs'>{user.email}</span>
</div>
</div>
</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuGroup>
<DropdownMenuItem>
<Sparkles />
Upgrade to Pro
</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuGroup>
<DropdownMenuItem>
<BadgeCheck />
Account
</DropdownMenuItem>
<DropdownMenuItem>
<CreditCard />
Billing
</DropdownMenuItem>
<DropdownMenuItem>
<Bell />
Notifications
</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuItem>
<LogOut />
Log out
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</SidebarMenuItem>
</SidebarMenu>
);
}

View file

@ -0,0 +1,35 @@
import { cn } from '@/lib/utils';
import { cva, type VariantProps } from 'class-variance-authority';
import { CircleSmall } from 'lucide-react';
const dotVariants = cva('', {
variants: {
variant: {
neutral: 'fill-neutral-900',
active: 'fill-red-600 stroke-red-600',
hidden: 'hidden',
},
},
defaultVariants: {
variant: 'hidden',
},
});
function NotificationDot({
className,
dotVariant,
...props
}: {
className: string;
dotVariant: VariantProps<typeof dotVariants>['variant'];
}) {
return (
<CircleSmall
className={cn(dotVariants({ variant: dotVariant }), className)}
{...props}
/>
);
}
export type NDot = VariantProps<typeof dotVariants>['variant'];
export { NotificationDot, dotVariants };

View file

@ -0,0 +1,29 @@
import { useGetApiUserMe } from '@/generated/api/user/user';
import { Avatar } from '@/components/ui/avatar';
import Image from 'next/image';
import { User } from 'lucide-react';
export default function UserCard() {
const { data } = useGetApiUserMe();
return (
<div className='w-full'>
<Avatar className='flex justify-center items-center'>
{data?.data.user.image ? (
<Image
className='border-2 rounded-md'
src={data?.data.user.image}
alt='Avatar'
width='50'
height='50'
/>
) : (
<User />
)}
</Avatar>
<div className='flex justify-center'>{data?.data.user.name}</div>
<div className='flex justify-center text-text-muted'>
{data?.data.user.email}
</div>
</div>
);
}

View file

@ -0,0 +1,52 @@
'use client';
import { Avatar } from '@/components/ui/avatar';
import { Button } from '@/components/ui/button';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import { useGetApiUserMe } from '@/generated/api/user/user';
import { ChevronDown, User } from 'lucide-react';
import Image from 'next/image';
import Link from 'next/link';
import UserCard from '@/components/misc/user-card';
export default function UserDropdown() {
const { data } = useGetApiUserMe();
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant='outline_primary'>
<Avatar className='flex justify-center items-center'>
{data?.data.user.image ? (
<Image
src={data?.data.user.image}
alt='Avatar'
width='20'
height='20'
/>
) : (
<User />
)}
</Avatar>
<ChevronDown />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align='end'>
<DropdownMenuItem>
<UserCard />
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem>Settings</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem>
<Link href='/logout'>Logout</Link>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
}

View file

@ -0,0 +1,53 @@
'use client';
import * as React from 'react';
import * as AvatarPrimitive from '@radix-ui/react-avatar';
import { cn } from '@/lib/utils';
function Avatar({
className,
...props
}: React.ComponentProps<typeof AvatarPrimitive.Root>) {
return (
<AvatarPrimitive.Root
data-slot='avatar'
className={cn(
'relative flex shrink-0 overflow-hidden rounded-md',
className,
)}
{...props}
/>
);
}
function AvatarImage({
className,
...props
}: React.ComponentProps<typeof AvatarPrimitive.Image>) {
return (
<AvatarPrimitive.Image
data-slot='avatar-image'
className={cn('aspect-square size-full', className)}
{...props}
/>
);
}
function AvatarFallback({
className,
...props
}: React.ComponentProps<typeof AvatarPrimitive.Fallback>) {
return (
<AvatarPrimitive.Fallback
data-slot='avatar-fallback'
className={cn(
'bg-muted flex size-full items-center justify-center rounded-full',
className,
)}
{...props}
/>
);
}
export { Avatar, AvatarImage, AvatarFallback };

View file

@ -0,0 +1,33 @@
'use client';
import * as CollapsiblePrimitive from '@radix-ui/react-collapsible';
function Collapsible({
...props
}: React.ComponentProps<typeof CollapsiblePrimitive.Root>) {
return <CollapsiblePrimitive.Root data-slot='collapsible' {...props} />;
}
function CollapsibleTrigger({
...props
}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleTrigger>) {
return (
<CollapsiblePrimitive.CollapsibleTrigger
data-slot='collapsible-trigger'
{...props}
/>
);
}
function CollapsibleContent({
...props
}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleContent>) {
return (
<CollapsiblePrimitive.CollapsibleContent
data-slot='collapsible-content'
{...props}
/>
);
}
export { Collapsible, CollapsibleTrigger, CollapsibleContent };

View file

@ -13,10 +13,13 @@ function Separator({
}: React.ComponentProps<typeof SeparatorPrimitive.Root>) {
return (
<SeparatorPrimitive.Root
data-slot='separator-root'
data-slot='separator'
decorative={decorative}
orientation={orientation}
className={cn('shrink-0', className)}
className={cn(
'bg-border shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px',
className,
)}
{...props}
/>
);

139
src/components/ui/sheet.tsx Normal file
View file

@ -0,0 +1,139 @@
'use client';
import * as React from 'react';
import * as SheetPrimitive from '@radix-ui/react-dialog';
import { XIcon } from 'lucide-react';
import { cn } from '@/lib/utils';
function Sheet({ ...props }: React.ComponentProps<typeof SheetPrimitive.Root>) {
return <SheetPrimitive.Root data-slot='sheet' {...props} />;
}
function SheetTrigger({
...props
}: React.ComponentProps<typeof SheetPrimitive.Trigger>) {
return <SheetPrimitive.Trigger data-slot='sheet-trigger' {...props} />;
}
function SheetClose({
...props
}: React.ComponentProps<typeof SheetPrimitive.Close>) {
return <SheetPrimitive.Close data-slot='sheet-close' {...props} />;
}
function SheetPortal({
...props
}: React.ComponentProps<typeof SheetPrimitive.Portal>) {
return <SheetPrimitive.Portal data-slot='sheet-portal' {...props} />;
}
function SheetOverlay({
className,
...props
}: React.ComponentProps<typeof SheetPrimitive.Overlay>) {
return (
<SheetPrimitive.Overlay
data-slot='sheet-overlay'
className={cn(
'data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50',
className,
)}
{...props}
/>
);
}
function SheetContent({
className,
children,
side = 'right',
...props
}: React.ComponentProps<typeof SheetPrimitive.Content> & {
side?: 'top' | 'right' | 'bottom' | 'left';
}) {
return (
<SheetPortal>
<SheetOverlay />
<SheetPrimitive.Content
data-slot='sheet-content'
className={cn(
'bg-background data-[state=open]:animate-in data-[state=closed]:animate-out fixed z-50 flex flex-col gap-4 shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500',
side === 'right' &&
'data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm',
side === 'left' &&
'data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left inset-y-0 left-0 h-full w-3/4 border-r sm:max-w-sm',
side === 'top' &&
'data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top inset-x-0 top-0 h-auto border-b',
side === 'bottom' &&
'data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom inset-x-0 bottom-0 h-auto border-t',
className,
)}
{...props}
>
{children}
<SheetPrimitive.Close className='ring-offset-background focus:ring-ring data-[state=open]:bg-secondary absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none'>
<XIcon className='size-4' />
<span className='sr-only'>Close</span>
</SheetPrimitive.Close>
</SheetPrimitive.Content>
</SheetPortal>
);
}
function SheetHeader({ className, ...props }: React.ComponentProps<'div'>) {
return (
<div
data-slot='sheet-header'
className={cn('flex flex-col gap-1.5 p-4', className)}
{...props}
/>
);
}
function SheetFooter({ className, ...props }: React.ComponentProps<'div'>) {
return (
<div
data-slot='sheet-footer'
className={cn('mt-auto flex flex-col gap-2 p-4', className)}
{...props}
/>
);
}
function SheetTitle({
className,
...props
}: React.ComponentProps<typeof SheetPrimitive.Title>) {
return (
<SheetPrimitive.Title
data-slot='sheet-title'
className={cn('text-foreground font-semibold', className)}
{...props}
/>
);
}
function SheetDescription({
className,
...props
}: React.ComponentProps<typeof SheetPrimitive.Description>) {
return (
<SheetPrimitive.Description
data-slot='sheet-description'
className={cn('text-muted-foreground text-sm', className)}
{...props}
/>
);
}
export {
Sheet,
SheetTrigger,
SheetClose,
SheetContent,
SheetHeader,
SheetFooter,
SheetTitle,
SheetDescription,
};

View file

@ -0,0 +1,13 @@
import { cn } from '@/lib/utils';
function Skeleton({ className, ...props }: React.ComponentProps<'div'>) {
return (
<div
data-slot='skeleton'
className={cn('bg-accent animate-pulse rounded-md', className)}
{...props}
/>
);
}
export { Skeleton };

View file

@ -0,0 +1,61 @@
'use client';
import * as React from 'react';
import * as TooltipPrimitive from '@radix-ui/react-tooltip';
import { cn } from '@/lib/utils';
function TooltipProvider({
delayDuration = 0,
...props
}: React.ComponentProps<typeof TooltipPrimitive.Provider>) {
return (
<TooltipPrimitive.Provider
data-slot='tooltip-provider'
delayDuration={delayDuration}
{...props}
/>
);
}
function Tooltip({
...props
}: React.ComponentProps<typeof TooltipPrimitive.Root>) {
return (
<TooltipProvider>
<TooltipPrimitive.Root data-slot='tooltip' {...props} />
</TooltipProvider>
);
}
function TooltipTrigger({
...props
}: React.ComponentProps<typeof TooltipPrimitive.Trigger>) {
return <TooltipPrimitive.Trigger data-slot='tooltip-trigger' {...props} />;
}
function TooltipContent({
className,
sideOffset = 0,
children,
...props
}: React.ComponentProps<typeof TooltipPrimitive.Content>) {
return (
<TooltipPrimitive.Portal>
<TooltipPrimitive.Content
data-slot='tooltip-content'
sideOffset={sideOffset}
className={cn(
'bg-primary 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 z-50 w-fit origin-(--radix-tooltip-content-transform-origin) rounded-md px-3 py-1.5 text-xs text-balance',
className,
)}
{...props}
>
{children}
<TooltipPrimitive.Arrow className='bg-primary fill-primary z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]' />
</TooltipPrimitive.Content>
</TooltipPrimitive.Portal>
);
}
export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };

View file

@ -0,0 +1,23 @@
'use client';
import React from 'react';
import { SidebarProvider } from '../custom-ui/sidebar';
export default function SidebarProviderWrapper({
defaultOpen,
children,
}: {
defaultOpen: boolean;
children: React.ReactNode;
}) {
const [open, setOpen] = React.useState(defaultOpen);
return (
<SidebarProvider
defaultOpen={defaultOpen}
open={open}
onOpenChange={setOpen}
>
{children}
</SidebarProvider>
);
}

21
src/hooks/use-mobile.ts Normal file
View file

@ -0,0 +1,21 @@
import * as React from 'react';
const MOBILE_BREAKPOINT = 768;
export function useIsMobile() {
const [isMobile, setIsMobile] = React.useState<boolean | undefined>(
undefined,
);
React.useEffect(() => {
const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
const onChange = () => {
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
};
mql.addEventListener('change', onChange);
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
return () => mql.removeEventListener('change', onChange);
}, []);
return !!isMobile;
}

527
yarn.lock
View file

@ -543,15 +543,15 @@ __metadata:
linkType: hard
"@gerrit0/mini-shiki@npm:^3.2.2":
version: 3.6.0
resolution: "@gerrit0/mini-shiki@npm:3.6.0"
version: 3.7.0
resolution: "@gerrit0/mini-shiki@npm:3.7.0"
dependencies:
"@shikijs/engine-oniguruma": "npm:^3.6.0"
"@shikijs/langs": "npm:^3.6.0"
"@shikijs/themes": "npm:^3.6.0"
"@shikijs/types": "npm:^3.6.0"
"@shikijs/engine-oniguruma": "npm:^3.7.0"
"@shikijs/langs": "npm:^3.7.0"
"@shikijs/themes": "npm:^3.7.0"
"@shikijs/types": "npm:^3.7.0"
"@shikijs/vscode-textmate": "npm:^10.0.2"
checksum: 10c0/347456c9da8a1fadd3c1f63097da459a5f930ef4bca6431cce913a379012c551e061d0a94ff7a0f307215b87f2418b7c198a55fba888fc97fb02ab36247adf6b
checksum: 10c0/eb3f4900d841338077d839ebbc7f8722b13876a586cff7abc73295e956683724dd3371a9f990900184a2d069461965951b2604d677991badf3474262e7811384
languageName: node
linkType: hard
@ -1299,6 +1299,55 @@ __metadata:
languageName: node
linkType: hard
"@radix-ui/react-avatar@npm:^1.1.10":
version: 1.1.10
resolution: "@radix-ui/react-avatar@npm:1.1.10"
dependencies:
"@radix-ui/react-context": "npm:1.1.2"
"@radix-ui/react-primitive": "npm:2.1.3"
"@radix-ui/react-use-callback-ref": "npm:1.1.1"
"@radix-ui/react-use-is-hydrated": "npm:0.1.0"
"@radix-ui/react-use-layout-effect": "npm:1.1.1"
peerDependencies:
"@types/react": "*"
"@types/react-dom": "*"
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
peerDependenciesMeta:
"@types/react":
optional: true
"@types/react-dom":
optional: true
checksum: 10c0/9fb0cf9a9d0fdbeaa2efda476402fc09db2e6ff9cd9aa3ea1d315d9c9579840722a4833725cb196c455e0bd775dfe04221a4f6855685ce89d2133c42e2b07e5f
languageName: node
linkType: hard
"@radix-ui/react-collapsible@npm:^1.1.11":
version: 1.1.11
resolution: "@radix-ui/react-collapsible@npm:1.1.11"
dependencies:
"@radix-ui/primitive": "npm:1.1.2"
"@radix-ui/react-compose-refs": "npm:1.1.2"
"@radix-ui/react-context": "npm:1.1.2"
"@radix-ui/react-id": "npm:1.1.1"
"@radix-ui/react-presence": "npm:1.1.4"
"@radix-ui/react-primitive": "npm:2.1.3"
"@radix-ui/react-use-controllable-state": "npm:1.2.2"
"@radix-ui/react-use-layout-effect": "npm:1.1.1"
peerDependencies:
"@types/react": "*"
"@types/react-dom": "*"
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
peerDependenciesMeta:
"@types/react":
optional: true
"@types/react-dom":
optional: true
checksum: 10c0/fa2de539ef06e2b2d18acebb12a34ce1534ca88bd484b7359aac05534d1e551fe83eaafbf60915c00161bb370f0dc9fc303903133510dea0a59fd018155b7db5
languageName: node
linkType: hard
"@radix-ui/react-collection@npm:1.1.7":
version: 1.1.7
resolution: "@radix-ui/react-collection@npm:1.1.7"
@ -1347,6 +1396,38 @@ __metadata:
languageName: node
linkType: hard
"@radix-ui/react-dialog@npm:^1.1.14":
version: 1.1.14
resolution: "@radix-ui/react-dialog@npm:1.1.14"
dependencies:
"@radix-ui/primitive": "npm:1.1.2"
"@radix-ui/react-compose-refs": "npm:1.1.2"
"@radix-ui/react-context": "npm:1.1.2"
"@radix-ui/react-dismissable-layer": "npm:1.1.10"
"@radix-ui/react-focus-guards": "npm:1.1.2"
"@radix-ui/react-focus-scope": "npm:1.1.7"
"@radix-ui/react-id": "npm:1.1.1"
"@radix-ui/react-portal": "npm:1.1.9"
"@radix-ui/react-presence": "npm:1.1.4"
"@radix-ui/react-primitive": "npm:2.1.3"
"@radix-ui/react-slot": "npm:1.2.3"
"@radix-ui/react-use-controllable-state": "npm:1.2.2"
aria-hidden: "npm:^1.2.4"
react-remove-scroll: "npm:^2.6.3"
peerDependencies:
"@types/react": "*"
"@types/react-dom": "*"
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
peerDependenciesMeta:
"@types/react":
optional: true
"@types/react-dom":
optional: true
checksum: 10c0/ab7bc783510ed8fccfe91020b214f4a571d5a1d46d398faa33f4c151bc9f586c47483b307e72b67687b06694c194b3aa80dd1de728460fa765db9f3057690ba3
languageName: node
linkType: hard
"@radix-ui/react-direction@npm:1.1.1":
version: 1.1.1
resolution: "@radix-ui/react-direction@npm:1.1.1"
@ -1383,7 +1464,7 @@ __metadata:
languageName: node
linkType: hard
"@radix-ui/react-dropdown-menu@npm:^2.1.14":
"@radix-ui/react-dropdown-menu@npm:^2.1.15":
version: 2.1.15
resolution: "@radix-ui/react-dropdown-menu@npm:2.1.15"
dependencies:
@ -1719,7 +1800,7 @@ __metadata:
languageName: node
linkType: hard
"@radix-ui/react-separator@npm:^1.1.6":
"@radix-ui/react-separator@npm:^1.1.7":
version: 1.1.7
resolution: "@radix-ui/react-separator@npm:1.1.7"
dependencies:
@ -1738,7 +1819,7 @@ __metadata:
languageName: node
linkType: hard
"@radix-ui/react-slot@npm:1.2.3, @radix-ui/react-slot@npm:^1.2.2":
"@radix-ui/react-slot@npm:1.2.3, @radix-ui/react-slot@npm:^1.2.3":
version: 1.2.3
resolution: "@radix-ui/react-slot@npm:1.2.3"
dependencies:
@ -1804,6 +1885,36 @@ __metadata:
languageName: node
linkType: hard
"@radix-ui/react-tooltip@npm:^1.2.7":
version: 1.2.7
resolution: "@radix-ui/react-tooltip@npm:1.2.7"
dependencies:
"@radix-ui/primitive": "npm:1.1.2"
"@radix-ui/react-compose-refs": "npm:1.1.2"
"@radix-ui/react-context": "npm:1.1.2"
"@radix-ui/react-dismissable-layer": "npm:1.1.10"
"@radix-ui/react-id": "npm:1.1.1"
"@radix-ui/react-popper": "npm:1.2.7"
"@radix-ui/react-portal": "npm:1.1.9"
"@radix-ui/react-presence": "npm:1.1.4"
"@radix-ui/react-primitive": "npm:2.1.3"
"@radix-ui/react-slot": "npm:1.2.3"
"@radix-ui/react-use-controllable-state": "npm:1.2.2"
"@radix-ui/react-visually-hidden": "npm:1.2.3"
peerDependencies:
"@types/react": "*"
"@types/react-dom": "*"
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
peerDependenciesMeta:
"@types/react":
optional: true
"@types/react-dom":
optional: true
checksum: 10c0/28798d576c6ffec4f11120cd563aa9d5ab9afb9a37dc18778176442756d026c8c46eec1ddc647b2b5914045495fcb89f82530106e91acb55776b7d6b1a10fb57
languageName: node
linkType: hard
"@radix-ui/react-use-callback-ref@npm:1.1.1":
version: 1.1.1
resolution: "@radix-ui/react-use-callback-ref@npm:1.1.1"
@ -1863,6 +1974,21 @@ __metadata:
languageName: node
linkType: hard
"@radix-ui/react-use-is-hydrated@npm:0.1.0":
version: 0.1.0
resolution: "@radix-ui/react-use-is-hydrated@npm:0.1.0"
dependencies:
use-sync-external-store: "npm:^1.5.0"
peerDependencies:
"@types/react": "*"
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
peerDependenciesMeta:
"@types/react":
optional: true
checksum: 10c0/635079bafe32829fc7405895154568ea94a22689b170489fd6d77668e4885e72ff71ed6d0ea3d602852841ef0f1927aa400fee2178d5dfbeb8bc9297da7d6498
languageName: node
linkType: hard
"@radix-ui/react-use-layout-effect@npm:1.1.1":
version: 1.1.1
resolution: "@radix-ui/react-use-layout-effect@npm:1.1.1"
@ -1966,7 +2092,7 @@ __metadata:
languageName: node
linkType: hard
"@shikijs/engine-oniguruma@npm:^3.6.0":
"@shikijs/engine-oniguruma@npm:^3.7.0":
version: 3.7.0
resolution: "@shikijs/engine-oniguruma@npm:3.7.0"
dependencies:
@ -1976,7 +2102,7 @@ __metadata:
languageName: node
linkType: hard
"@shikijs/langs@npm:^3.6.0":
"@shikijs/langs@npm:^3.7.0":
version: 3.7.0
resolution: "@shikijs/langs@npm:3.7.0"
dependencies:
@ -1985,7 +2111,7 @@ __metadata:
languageName: node
linkType: hard
"@shikijs/themes@npm:^3.6.0":
"@shikijs/themes@npm:^3.7.0":
version: 3.7.0
resolution: "@shikijs/themes@npm:3.7.0"
dependencies:
@ -1994,7 +2120,7 @@ __metadata:
languageName: node
linkType: hard
"@shikijs/types@npm:3.7.0, @shikijs/types@npm:^3.6.0":
"@shikijs/types@npm:3.7.0, @shikijs/types@npm:^3.7.0":
version: 3.7.0
resolution: "@shikijs/types@npm:3.7.0"
dependencies:
@ -3094,11 +3220,11 @@ __metadata:
linkType: hard
"@types/node@npm:*":
version: 24.0.3
resolution: "@types/node@npm:24.0.3"
version: 24.0.4
resolution: "@types/node@npm:24.0.4"
dependencies:
undici-types: "npm:~7.8.0"
checksum: 10c0/9c3c4e87600d1cf11e291c2fd4bfd806a615455463c30a0ef6dc9c801b3423344d9b82b8084e3ccabce485a7421ebb61a66e9676181bd7d9aea4759998a120d5
checksum: 10c0/590e8cb0ec59fb9cd566402120e690d87ecbdf57f1ee2b8493266121ed33aa4b25949a0c6156b84a6ffb9250baaf1f80e9af142da542ed603e6ee73fc4d1115f
languageName: node
linkType: hard
@ -3190,104 +3316,104 @@ __metadata:
linkType: hard
"@typescript-eslint/eslint-plugin@npm:^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0":
version: 8.34.1
resolution: "@typescript-eslint/eslint-plugin@npm:8.34.1"
version: 8.35.0
resolution: "@typescript-eslint/eslint-plugin@npm:8.35.0"
dependencies:
"@eslint-community/regexpp": "npm:^4.10.0"
"@typescript-eslint/scope-manager": "npm:8.34.1"
"@typescript-eslint/type-utils": "npm:8.34.1"
"@typescript-eslint/utils": "npm:8.34.1"
"@typescript-eslint/visitor-keys": "npm:8.34.1"
"@typescript-eslint/scope-manager": "npm:8.35.0"
"@typescript-eslint/type-utils": "npm:8.35.0"
"@typescript-eslint/utils": "npm:8.35.0"
"@typescript-eslint/visitor-keys": "npm:8.35.0"
graphemer: "npm:^1.4.0"
ignore: "npm:^7.0.0"
natural-compare: "npm:^1.4.0"
ts-api-utils: "npm:^2.1.0"
peerDependencies:
"@typescript-eslint/parser": ^8.34.1
"@typescript-eslint/parser": ^8.35.0
eslint: ^8.57.0 || ^9.0.0
typescript: ">=4.8.4 <5.9.0"
checksum: 10c0/f1c9f25e4fe4b59622312dfa0ca1e80fa7945296ba5c04362a5fda084a17e23a6b98dac331f5a13bcb1ba34a2b598a3f5c41aa288f0c51fe60196e912954e56a
checksum: 10c0/27391f1b168a175fdc62370e5afe51317d4433115abbbff8ee0aea8ecd7bf6dd541a76f8e0cc94119750ae3146863204862640acb45394f0b92809e88d39f881
languageName: node
linkType: hard
"@typescript-eslint/parser@npm:^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0":
version: 8.34.1
resolution: "@typescript-eslint/parser@npm:8.34.1"
version: 8.35.0
resolution: "@typescript-eslint/parser@npm:8.35.0"
dependencies:
"@typescript-eslint/scope-manager": "npm:8.34.1"
"@typescript-eslint/types": "npm:8.34.1"
"@typescript-eslint/typescript-estree": "npm:8.34.1"
"@typescript-eslint/visitor-keys": "npm:8.34.1"
"@typescript-eslint/scope-manager": "npm:8.35.0"
"@typescript-eslint/types": "npm:8.35.0"
"@typescript-eslint/typescript-estree": "npm:8.35.0"
"@typescript-eslint/visitor-keys": "npm:8.35.0"
debug: "npm:^4.3.4"
peerDependencies:
eslint: ^8.57.0 || ^9.0.0
typescript: ">=4.8.4 <5.9.0"
checksum: 10c0/bf8070245d53ef6926ff6630bb72f245923f545304e2a61508fb944802a83fed8eab961d9010956d07999d51afdfbbec82aea9d6185295551a7c17c00d759183
checksum: 10c0/8f1cda98f8bee3d79266974e5e5c831a0ca473e928fb16f1dc1c85ee24f2cb9c0fcf3c1bcbbef9d6044cf063f6e59d3198b766a27000776830fe591043e11625
languageName: node
linkType: hard
"@typescript-eslint/project-service@npm:8.34.1":
version: 8.34.1
resolution: "@typescript-eslint/project-service@npm:8.34.1"
"@typescript-eslint/project-service@npm:8.35.0":
version: 8.35.0
resolution: "@typescript-eslint/project-service@npm:8.35.0"
dependencies:
"@typescript-eslint/tsconfig-utils": "npm:^8.34.1"
"@typescript-eslint/types": "npm:^8.34.1"
"@typescript-eslint/tsconfig-utils": "npm:^8.35.0"
"@typescript-eslint/types": "npm:^8.35.0"
debug: "npm:^4.3.4"
peerDependencies:
typescript: ">=4.8.4 <5.9.0"
checksum: 10c0/9333a890625f6777054db17a6b299281ae7502bb7615261d15b885a75b8cf65fc91591389c93b37ecd14b651d8e94851dac8718e5dcc8ed0600533535dae855c
checksum: 10c0/c2d6d44b6b2ff3ecabec8ade824163196799060ac457661eb94049487d770ce68d128b33a2f24090adf1ebcb66ff6c9a05fc6659349b9a0784a5a080ecf8ff81
languageName: node
linkType: hard
"@typescript-eslint/scope-manager@npm:8.34.1":
version: 8.34.1
resolution: "@typescript-eslint/scope-manager@npm:8.34.1"
"@typescript-eslint/scope-manager@npm:8.35.0":
version: 8.35.0
resolution: "@typescript-eslint/scope-manager@npm:8.35.0"
dependencies:
"@typescript-eslint/types": "npm:8.34.1"
"@typescript-eslint/visitor-keys": "npm:8.34.1"
checksum: 10c0/2af608fa3900f4726322e33bf4f3a376fdace3ac0f310cf7d9256bbc2905c3896138176a47dd195d2c2229f27fe43f5deb4bc7729db2eb18389926dedea78077
"@typescript-eslint/types": "npm:8.35.0"
"@typescript-eslint/visitor-keys": "npm:8.35.0"
checksum: 10c0/a27cf27a1852bb0d6ea08f475fcc79557f1977be96ef563d92127e8011e4065566441c32c40eb7a530111ffd3a8489919da7f8a2b7466a610cfc9c07670a9601
languageName: node
linkType: hard
"@typescript-eslint/tsconfig-utils@npm:8.34.1, @typescript-eslint/tsconfig-utils@npm:^8.34.1":
version: 8.34.1
resolution: "@typescript-eslint/tsconfig-utils@npm:8.34.1"
"@typescript-eslint/tsconfig-utils@npm:8.35.0, @typescript-eslint/tsconfig-utils@npm:^8.35.0":
version: 8.35.0
resolution: "@typescript-eslint/tsconfig-utils@npm:8.35.0"
peerDependencies:
typescript: ">=4.8.4 <5.9.0"
checksum: 10c0/8d1ead8b7c279b48e2ed96f083ec119a9aeea1ca9cdd40576ec271b996b9fd8cfa0ddb0aafbb4e14bc27fc62c69c5be66d39b1de68eab9ddd7f1861da267423d
checksum: 10c0/baa18e7137ba72f7d138f50d1168e8f334198a36499f954821e2369027e5b3d53ca93c354943e7782ba5caab604b050af10f353ccca34fbc0b23c48d6174832f
languageName: node
linkType: hard
"@typescript-eslint/type-utils@npm:8.34.1":
version: 8.34.1
resolution: "@typescript-eslint/type-utils@npm:8.34.1"
"@typescript-eslint/type-utils@npm:8.35.0":
version: 8.35.0
resolution: "@typescript-eslint/type-utils@npm:8.35.0"
dependencies:
"@typescript-eslint/typescript-estree": "npm:8.34.1"
"@typescript-eslint/utils": "npm:8.34.1"
"@typescript-eslint/typescript-estree": "npm:8.35.0"
"@typescript-eslint/utils": "npm:8.35.0"
debug: "npm:^4.3.4"
ts-api-utils: "npm:^2.1.0"
peerDependencies:
eslint: ^8.57.0 || ^9.0.0
typescript: ">=4.8.4 <5.9.0"
checksum: 10c0/502a2cdfe47f1f34206c747b5a70e0242dd99f570511db3dda9c5f999d9abadfbbb1dfa82a1fa437a1689d232715412e61c97d95f19c9314ba5ad23196b4096d
checksum: 10c0/9e23a332484a055eb73ba8918f95a981e0cec8fa623ba9ee0b57328af052628d630a415e32e0dbe95318574e62d4066f8aecc994728b3cedd906f36c616ec362
languageName: node
linkType: hard
"@typescript-eslint/types@npm:8.34.1, @typescript-eslint/types@npm:^8.34.1":
version: 8.34.1
resolution: "@typescript-eslint/types@npm:8.34.1"
checksum: 10c0/db1b3dce6a70b28ddb13c76fbb5983240d9395656df5f7cbd99bfd9905e39c0dab2132870f01dbc406b48739c437f7d344a879a824cedaba81b91a53110dc23a
"@typescript-eslint/types@npm:8.35.0, @typescript-eslint/types@npm:^8.35.0":
version: 8.35.0
resolution: "@typescript-eslint/types@npm:8.35.0"
checksum: 10c0/a2711a932680805e83252b5d7c55ac30437bdc4d40c444606cf6ccb6ba23a682da015ec03c64635e77bf733f84d9bb76810bf4f7177fd3a660db8a2c8a05e845
languageName: node
linkType: hard
"@typescript-eslint/typescript-estree@npm:8.34.1":
version: 8.34.1
resolution: "@typescript-eslint/typescript-estree@npm:8.34.1"
"@typescript-eslint/typescript-estree@npm:8.35.0":
version: 8.35.0
resolution: "@typescript-eslint/typescript-estree@npm:8.35.0"
dependencies:
"@typescript-eslint/project-service": "npm:8.34.1"
"@typescript-eslint/tsconfig-utils": "npm:8.34.1"
"@typescript-eslint/types": "npm:8.34.1"
"@typescript-eslint/visitor-keys": "npm:8.34.1"
"@typescript-eslint/project-service": "npm:8.35.0"
"@typescript-eslint/tsconfig-utils": "npm:8.35.0"
"@typescript-eslint/types": "npm:8.35.0"
"@typescript-eslint/visitor-keys": "npm:8.35.0"
debug: "npm:^4.3.4"
fast-glob: "npm:^3.3.2"
is-glob: "npm:^4.0.3"
@ -3296,166 +3422,166 @@ __metadata:
ts-api-utils: "npm:^2.1.0"
peerDependencies:
typescript: ">=4.8.4 <5.9.0"
checksum: 10c0/4ee7249db91b9840361f34f80b7b6d646a3af159c7298d79a33d8a11c98792fd3a395343e5e17e0fa29529e8f0113bac8baadcef90d1e140bd736a48f0485042
checksum: 10c0/7e94f6a92efc5832289e8bfd0b61209aa501224c935359253c29aeef8e0b981b370ee2a43e2909991c3c3cf709fcccb6380474e0e9a863e8f89e2fbd213aed59
languageName: node
linkType: hard
"@typescript-eslint/utils@npm:8.34.1":
version: 8.34.1
resolution: "@typescript-eslint/utils@npm:8.34.1"
"@typescript-eslint/utils@npm:8.35.0":
version: 8.35.0
resolution: "@typescript-eslint/utils@npm:8.35.0"
dependencies:
"@eslint-community/eslint-utils": "npm:^4.7.0"
"@typescript-eslint/scope-manager": "npm:8.34.1"
"@typescript-eslint/types": "npm:8.34.1"
"@typescript-eslint/typescript-estree": "npm:8.34.1"
"@typescript-eslint/scope-manager": "npm:8.35.0"
"@typescript-eslint/types": "npm:8.35.0"
"@typescript-eslint/typescript-estree": "npm:8.35.0"
peerDependencies:
eslint: ^8.57.0 || ^9.0.0
typescript: ">=4.8.4 <5.9.0"
checksum: 10c0/e3085877f7940c02a37653e6bc52ac6cde115e755b1f788fe4331202f371b3421cc4d0878c7d3eb054e14e9b3a064496a707a73eac471cb2b73593b9e9d4b998
checksum: 10c0/e3317df7875305bee16edd573e4bfdafc099f26f9c284d8adb351333683aacd5b668320870653dff7ec7e0da1982bbf89dc06197bc193a3be65362f21452dbea
languageName: node
linkType: hard
"@typescript-eslint/visitor-keys@npm:8.34.1":
version: 8.34.1
resolution: "@typescript-eslint/visitor-keys@npm:8.34.1"
"@typescript-eslint/visitor-keys@npm:8.35.0":
version: 8.35.0
resolution: "@typescript-eslint/visitor-keys@npm:8.35.0"
dependencies:
"@typescript-eslint/types": "npm:8.34.1"
"@typescript-eslint/types": "npm:8.35.0"
eslint-visitor-keys: "npm:^4.2.1"
checksum: 10c0/0e5a9b3d93905d16d3cf8cb5fb346dcc6f760482eb7d0ac209aefc09a32f78ef28a687634df6ad08e81fb3e1083e8805f34472de6bbc501c0105ad654d518f40
checksum: 10c0/df18ca9b6931cb58f5dc404fcc94f9e0cc1c22f3053c7013ab588bb8ccccd3d58a70c577c01267845d57fa124a8cf8371260d284dad97505c56b2abcf70a3dce
languageName: node
linkType: hard
"@unrs/resolver-binding-android-arm-eabi@npm:1.9.1":
version: 1.9.1
resolution: "@unrs/resolver-binding-android-arm-eabi@npm:1.9.1"
"@unrs/resolver-binding-android-arm-eabi@npm:1.9.2":
version: 1.9.2
resolution: "@unrs/resolver-binding-android-arm-eabi@npm:1.9.2"
conditions: os=android & cpu=arm
languageName: node
linkType: hard
"@unrs/resolver-binding-android-arm64@npm:1.9.1":
version: 1.9.1
resolution: "@unrs/resolver-binding-android-arm64@npm:1.9.1"
"@unrs/resolver-binding-android-arm64@npm:1.9.2":
version: 1.9.2
resolution: "@unrs/resolver-binding-android-arm64@npm:1.9.2"
conditions: os=android & cpu=arm64
languageName: node
linkType: hard
"@unrs/resolver-binding-darwin-arm64@npm:1.9.1":
version: 1.9.1
resolution: "@unrs/resolver-binding-darwin-arm64@npm:1.9.1"
"@unrs/resolver-binding-darwin-arm64@npm:1.9.2":
version: 1.9.2
resolution: "@unrs/resolver-binding-darwin-arm64@npm:1.9.2"
conditions: os=darwin & cpu=arm64
languageName: node
linkType: hard
"@unrs/resolver-binding-darwin-x64@npm:1.9.1":
version: 1.9.1
resolution: "@unrs/resolver-binding-darwin-x64@npm:1.9.1"
"@unrs/resolver-binding-darwin-x64@npm:1.9.2":
version: 1.9.2
resolution: "@unrs/resolver-binding-darwin-x64@npm:1.9.2"
conditions: os=darwin & cpu=x64
languageName: node
linkType: hard
"@unrs/resolver-binding-freebsd-x64@npm:1.9.1":
version: 1.9.1
resolution: "@unrs/resolver-binding-freebsd-x64@npm:1.9.1"
"@unrs/resolver-binding-freebsd-x64@npm:1.9.2":
version: 1.9.2
resolution: "@unrs/resolver-binding-freebsd-x64@npm:1.9.2"
conditions: os=freebsd & cpu=x64
languageName: node
linkType: hard
"@unrs/resolver-binding-linux-arm-gnueabihf@npm:1.9.1":
version: 1.9.1
resolution: "@unrs/resolver-binding-linux-arm-gnueabihf@npm:1.9.1"
"@unrs/resolver-binding-linux-arm-gnueabihf@npm:1.9.2":
version: 1.9.2
resolution: "@unrs/resolver-binding-linux-arm-gnueabihf@npm:1.9.2"
conditions: os=linux & cpu=arm
languageName: node
linkType: hard
"@unrs/resolver-binding-linux-arm-musleabihf@npm:1.9.1":
version: 1.9.1
resolution: "@unrs/resolver-binding-linux-arm-musleabihf@npm:1.9.1"
"@unrs/resolver-binding-linux-arm-musleabihf@npm:1.9.2":
version: 1.9.2
resolution: "@unrs/resolver-binding-linux-arm-musleabihf@npm:1.9.2"
conditions: os=linux & cpu=arm
languageName: node
linkType: hard
"@unrs/resolver-binding-linux-arm64-gnu@npm:1.9.1":
version: 1.9.1
resolution: "@unrs/resolver-binding-linux-arm64-gnu@npm:1.9.1"
"@unrs/resolver-binding-linux-arm64-gnu@npm:1.9.2":
version: 1.9.2
resolution: "@unrs/resolver-binding-linux-arm64-gnu@npm:1.9.2"
conditions: os=linux & cpu=arm64 & libc=glibc
languageName: node
linkType: hard
"@unrs/resolver-binding-linux-arm64-musl@npm:1.9.1":
version: 1.9.1
resolution: "@unrs/resolver-binding-linux-arm64-musl@npm:1.9.1"
"@unrs/resolver-binding-linux-arm64-musl@npm:1.9.2":
version: 1.9.2
resolution: "@unrs/resolver-binding-linux-arm64-musl@npm:1.9.2"
conditions: os=linux & cpu=arm64 & libc=musl
languageName: node
linkType: hard
"@unrs/resolver-binding-linux-ppc64-gnu@npm:1.9.1":
version: 1.9.1
resolution: "@unrs/resolver-binding-linux-ppc64-gnu@npm:1.9.1"
"@unrs/resolver-binding-linux-ppc64-gnu@npm:1.9.2":
version: 1.9.2
resolution: "@unrs/resolver-binding-linux-ppc64-gnu@npm:1.9.2"
conditions: os=linux & cpu=ppc64 & libc=glibc
languageName: node
linkType: hard
"@unrs/resolver-binding-linux-riscv64-gnu@npm:1.9.1":
version: 1.9.1
resolution: "@unrs/resolver-binding-linux-riscv64-gnu@npm:1.9.1"
"@unrs/resolver-binding-linux-riscv64-gnu@npm:1.9.2":
version: 1.9.2
resolution: "@unrs/resolver-binding-linux-riscv64-gnu@npm:1.9.2"
conditions: os=linux & cpu=riscv64 & libc=glibc
languageName: node
linkType: hard
"@unrs/resolver-binding-linux-riscv64-musl@npm:1.9.1":
version: 1.9.1
resolution: "@unrs/resolver-binding-linux-riscv64-musl@npm:1.9.1"
"@unrs/resolver-binding-linux-riscv64-musl@npm:1.9.2":
version: 1.9.2
resolution: "@unrs/resolver-binding-linux-riscv64-musl@npm:1.9.2"
conditions: os=linux & cpu=riscv64 & libc=musl
languageName: node
linkType: hard
"@unrs/resolver-binding-linux-s390x-gnu@npm:1.9.1":
version: 1.9.1
resolution: "@unrs/resolver-binding-linux-s390x-gnu@npm:1.9.1"
"@unrs/resolver-binding-linux-s390x-gnu@npm:1.9.2":
version: 1.9.2
resolution: "@unrs/resolver-binding-linux-s390x-gnu@npm:1.9.2"
conditions: os=linux & cpu=s390x & libc=glibc
languageName: node
linkType: hard
"@unrs/resolver-binding-linux-x64-gnu@npm:1.9.1":
version: 1.9.1
resolution: "@unrs/resolver-binding-linux-x64-gnu@npm:1.9.1"
"@unrs/resolver-binding-linux-x64-gnu@npm:1.9.2":
version: 1.9.2
resolution: "@unrs/resolver-binding-linux-x64-gnu@npm:1.9.2"
conditions: os=linux & cpu=x64 & libc=glibc
languageName: node
linkType: hard
"@unrs/resolver-binding-linux-x64-musl@npm:1.9.1":
version: 1.9.1
resolution: "@unrs/resolver-binding-linux-x64-musl@npm:1.9.1"
"@unrs/resolver-binding-linux-x64-musl@npm:1.9.2":
version: 1.9.2
resolution: "@unrs/resolver-binding-linux-x64-musl@npm:1.9.2"
conditions: os=linux & cpu=x64 & libc=musl
languageName: node
linkType: hard
"@unrs/resolver-binding-wasm32-wasi@npm:1.9.1":
version: 1.9.1
resolution: "@unrs/resolver-binding-wasm32-wasi@npm:1.9.1"
"@unrs/resolver-binding-wasm32-wasi@npm:1.9.2":
version: 1.9.2
resolution: "@unrs/resolver-binding-wasm32-wasi@npm:1.9.2"
dependencies:
"@napi-rs/wasm-runtime": "npm:^0.2.11"
conditions: cpu=wasm32
languageName: node
linkType: hard
"@unrs/resolver-binding-win32-arm64-msvc@npm:1.9.1":
version: 1.9.1
resolution: "@unrs/resolver-binding-win32-arm64-msvc@npm:1.9.1"
"@unrs/resolver-binding-win32-arm64-msvc@npm:1.9.2":
version: 1.9.2
resolution: "@unrs/resolver-binding-win32-arm64-msvc@npm:1.9.2"
conditions: os=win32 & cpu=arm64
languageName: node
linkType: hard
"@unrs/resolver-binding-win32-ia32-msvc@npm:1.9.1":
version: 1.9.1
resolution: "@unrs/resolver-binding-win32-ia32-msvc@npm:1.9.1"
"@unrs/resolver-binding-win32-ia32-msvc@npm:1.9.2":
version: 1.9.2
resolution: "@unrs/resolver-binding-win32-ia32-msvc@npm:1.9.2"
conditions: os=win32 & cpu=ia32
languageName: node
linkType: hard
"@unrs/resolver-binding-win32-x64-msvc@npm:1.9.1":
version: 1.9.1
resolution: "@unrs/resolver-binding-win32-x64-msvc@npm:1.9.1"
"@unrs/resolver-binding-win32-x64-msvc@npm:1.9.2":
version: 1.9.2
resolution: "@unrs/resolver-binding-win32-x64-msvc@npm:1.9.2"
conditions: os=win32 & cpu=x64
languageName: node
linkType: hard
@ -3662,7 +3788,7 @@ __metadata:
languageName: node
linkType: hard
"array-includes@npm:^3.1.6, array-includes@npm:^3.1.8":
"array-includes@npm:^3.1.6, array-includes@npm:^3.1.8, array-includes@npm:^3.1.9":
version: 3.1.9
resolution: "array-includes@npm:3.1.9"
dependencies:
@ -3699,7 +3825,7 @@ __metadata:
languageName: node
linkType: hard
"array.prototype.findlastindex@npm:^1.2.5":
"array.prototype.findlastindex@npm:^1.2.6":
version: 1.2.6
resolution: "array.prototype.findlastindex@npm:1.2.6"
dependencies:
@ -3714,7 +3840,7 @@ __metadata:
languageName: node
linkType: hard
"array.prototype.flat@npm:^1.3.1, array.prototype.flat@npm:^1.3.2":
"array.prototype.flat@npm:^1.3.1, array.prototype.flat@npm:^1.3.3":
version: 1.3.3
resolution: "array.prototype.flat@npm:1.3.3"
dependencies:
@ -3964,9 +4090,9 @@ __metadata:
linkType: hard
"caniuse-lite@npm:^1.0.30001579":
version: 1.0.30001724
resolution: "caniuse-lite@npm:1.0.30001724"
checksum: 10c0/ed9ec0bcf619f0e7ef2d33aac74d2346d1faf52060dfded1fb9c32d87854de5c2988b3ba338c281034c88bf797d6b55468a804ce8396a7e16a48cb0d481d4bfe
version: 1.0.30001726
resolution: "caniuse-lite@npm:1.0.30001726"
checksum: 10c0/2c5f91da7fd9ebf8c6b432818b1498ea28aca8de22b30dafabe2a2a6da1e014f10e67e14f8e68e872a0867b6b4cd6001558dde04e3ab9770c9252ca5c8849d0e
languageName: node
linkType: hard
@ -4418,12 +4544,12 @@ __metadata:
linkType: hard
"enhanced-resolve@npm:^5.18.1":
version: 5.18.1
resolution: "enhanced-resolve@npm:5.18.1"
version: 5.18.2
resolution: "enhanced-resolve@npm:5.18.2"
dependencies:
graceful-fs: "npm:^4.2.4"
tapable: "npm:^2.2.0"
checksum: 10c0/4cffd9b125225184e2abed9fdf0ed3dbd2224c873b165d0838fd066cde32e0918626cba2f1f4bf6860762f13a7e2364fd89a82b99566be2873d813573ac71846
checksum: 10c0/2a45105daded694304b0298d1c0351a981842249a9867513d55e41321a4ccf37dfd35b0c1e9ceae290eab73654b09aa7a910d618ea6f9441e97c52bc424a2372
languageName: node
linkType: hard
@ -4792,7 +4918,7 @@ __metadata:
languageName: node
linkType: hard
"eslint-module-utils@npm:^2.12.0":
"eslint-module-utils@npm:^2.12.1":
version: 2.12.1
resolution: "eslint-module-utils@npm:2.12.1"
dependencies:
@ -4805,31 +4931,31 @@ __metadata:
linkType: hard
"eslint-plugin-import@npm:^2.31.0":
version: 2.31.0
resolution: "eslint-plugin-import@npm:2.31.0"
version: 2.32.0
resolution: "eslint-plugin-import@npm:2.32.0"
dependencies:
"@rtsao/scc": "npm:^1.1.0"
array-includes: "npm:^3.1.8"
array.prototype.findlastindex: "npm:^1.2.5"
array.prototype.flat: "npm:^1.3.2"
array.prototype.flatmap: "npm:^1.3.2"
array-includes: "npm:^3.1.9"
array.prototype.findlastindex: "npm:^1.2.6"
array.prototype.flat: "npm:^1.3.3"
array.prototype.flatmap: "npm:^1.3.3"
debug: "npm:^3.2.7"
doctrine: "npm:^2.1.0"
eslint-import-resolver-node: "npm:^0.3.9"
eslint-module-utils: "npm:^2.12.0"
eslint-module-utils: "npm:^2.12.1"
hasown: "npm:^2.0.2"
is-core-module: "npm:^2.15.1"
is-core-module: "npm:^2.16.1"
is-glob: "npm:^4.0.3"
minimatch: "npm:^3.1.2"
object.fromentries: "npm:^2.0.8"
object.groupby: "npm:^1.0.3"
object.values: "npm:^1.2.0"
object.values: "npm:^1.2.1"
semver: "npm:^6.3.1"
string.prototype.trimend: "npm:^1.0.8"
string.prototype.trimend: "npm:^1.0.9"
tsconfig-paths: "npm:^3.15.0"
peerDependencies:
eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9
checksum: 10c0/e21d116ddd1900e091ad120b3eb68c5dd5437fe2c930f1211781cd38b246f090a6b74d5f3800b8255a0ed29782591521ad44eb21c5534960a8f1fb4040fd913a
checksum: 10c0/bfb1b8fc8800398e62ddfefbf3638d185286edfed26dfe00875cc2846d954491b4f5112457831588b757fa789384e1ae585f812614c4797f0499fa234fd4a48b
languageName: node
linkType: hard
@ -5758,7 +5884,7 @@ __metadata:
languageName: node
linkType: hard
"is-core-module@npm:^2.13.0, is-core-module@npm:^2.15.1, is-core-module@npm:^2.16.0":
"is-core-module@npm:^2.13.0, is-core-module@npm:^2.16.0, is-core-module@npm:^2.16.1":
version: 2.16.1
resolution: "is-core-module@npm:2.16.1"
dependencies:
@ -6454,12 +6580,12 @@ __metadata:
languageName: node
linkType: hard
"lucide-react@npm:^0.511.0":
version: 0.511.0
resolution: "lucide-react@npm:0.511.0"
"lucide-react@npm:^0.515.0":
version: 0.515.0
resolution: "lucide-react@npm:0.515.0"
peerDependencies:
react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0
checksum: 10c0/bf09dd73cf2233abea90506ad31a91739555d761062722acbe045cb73e274f035b196472de0971a8a8f0645b2b54e3f21b8c1980fe87c909ca93171a9c28428a
checksum: 10c0/00485e09ab3d0bbb34797b1f368c269e8708522b6e2f46fd84dd5bd99741546487be9a65a260f274e8049b81cc37687566e26132f5752352c8d9bc8e5d0b3dea
languageName: node
linkType: hard
@ -6549,15 +6675,19 @@ __metadata:
"@fortawesome/react-fontawesome": "npm:^0.2.2"
"@hookform/resolvers": "npm:^5.0.1"
"@prisma/client": "npm:^6.9.0"
"@radix-ui/react-dropdown-menu": "npm:^2.1.14"
"@radix-ui/react-avatar": "npm:^1.1.10"
"@radix-ui/react-collapsible": "npm:^1.1.11"
"@radix-ui/react-dialog": "npm:^1.1.14"
"@radix-ui/react-dropdown-menu": "npm:^2.1.15"
"@radix-ui/react-hover-card": "npm:^1.1.13"
"@radix-ui/react-label": "npm:^2.1.6"
"@radix-ui/react-scroll-area": "npm:^1.2.8"
"@radix-ui/react-select": "npm:^2.2.4"
"@radix-ui/react-separator": "npm:^1.1.6"
"@radix-ui/react-slot": "npm:^1.2.2"
"@radix-ui/react-separator": "npm:^1.1.7"
"@radix-ui/react-slot": "npm:^1.2.3"
"@radix-ui/react-switch": "npm:^1.2.4"
"@radix-ui/react-tabs": "npm:^1.1.11"
"@radix-ui/react-tooltip": "npm:^1.2.7"
"@tailwindcss/postcss": "npm:4.1.10"
"@tanstack/react-query": "npm:^5.80.7"
"@types/node": "npm:22.15.33"
@ -6572,7 +6702,7 @@ __metadata:
eslint: "npm:9.29.0"
eslint-config-next: "npm:15.3.4"
eslint-config-prettier: "npm:10.1.5"
lucide-react: "npm:^0.511.0"
lucide-react: "npm:^0.515.0"
next: "npm:15.4.0-canary.95"
next-auth: "npm:^5.0.0-beta.25"
next-themes: "npm:^0.4.6"
@ -6794,7 +6924,7 @@ __metadata:
languageName: node
linkType: hard
"napi-postinstall@npm:^0.2.2":
"napi-postinstall@npm:^0.2.4":
version: 0.2.4
resolution: "napi-postinstall@npm:0.2.4"
bin:
@ -7185,7 +7315,7 @@ __metadata:
languageName: node
linkType: hard
"object.values@npm:^1.1.6, object.values@npm:^1.2.0, object.values@npm:^1.2.1":
"object.values@npm:^1.1.6, object.values@npm:^1.2.1":
version: 1.2.1
resolution: "object.values@npm:1.2.1"
dependencies:
@ -7233,7 +7363,7 @@ __metadata:
languageName: node
linkType: hard
"openapi3-ts@npm:4.4.0, openapi3-ts@npm:^4.1.2, openapi3-ts@npm:^4.2.2":
"openapi3-ts@npm:4.4.0":
version: 4.4.0
resolution: "openapi3-ts@npm:4.4.0"
dependencies:
@ -7242,6 +7372,15 @@ __metadata:
languageName: node
linkType: hard
"openapi3-ts@npm:^4.1.2, openapi3-ts@npm:^4.2.2":
version: 4.5.0
resolution: "openapi3-ts@npm:4.5.0"
dependencies:
yaml: "npm:^2.8.0"
checksum: 10c0/97de2d24e9ceffb89e1388e137e4a6e17ee57a02dce0c938a5e98b1338ac72b31e8b2ce8dd28945ad43fae8bee2a145892cb548ba5ae60b0930f1b6b79b0747d
languageName: node
linkType: hard
"optionator@npm:^0.9.3":
version: 0.9.4
resolution: "optionator@npm:0.9.4"
@ -8569,7 +8708,7 @@ __metadata:
languageName: node
linkType: hard
"string.prototype.trimend@npm:^1.0.8, string.prototype.trimend@npm:^1.0.9":
"string.prototype.trimend@npm:^1.0.9":
version: 1.0.9
resolution: "string.prototype.trimend@npm:1.0.9"
dependencies:
@ -9171,29 +9310,29 @@ __metadata:
linkType: hard
"unrs-resolver@npm:^1.6.2":
version: 1.9.1
resolution: "unrs-resolver@npm:1.9.1"
version: 1.9.2
resolution: "unrs-resolver@npm:1.9.2"
dependencies:
"@unrs/resolver-binding-android-arm-eabi": "npm:1.9.1"
"@unrs/resolver-binding-android-arm64": "npm:1.9.1"
"@unrs/resolver-binding-darwin-arm64": "npm:1.9.1"
"@unrs/resolver-binding-darwin-x64": "npm:1.9.1"
"@unrs/resolver-binding-freebsd-x64": "npm:1.9.1"
"@unrs/resolver-binding-linux-arm-gnueabihf": "npm:1.9.1"
"@unrs/resolver-binding-linux-arm-musleabihf": "npm:1.9.1"
"@unrs/resolver-binding-linux-arm64-gnu": "npm:1.9.1"
"@unrs/resolver-binding-linux-arm64-musl": "npm:1.9.1"
"@unrs/resolver-binding-linux-ppc64-gnu": "npm:1.9.1"
"@unrs/resolver-binding-linux-riscv64-gnu": "npm:1.9.1"
"@unrs/resolver-binding-linux-riscv64-musl": "npm:1.9.1"
"@unrs/resolver-binding-linux-s390x-gnu": "npm:1.9.1"
"@unrs/resolver-binding-linux-x64-gnu": "npm:1.9.1"
"@unrs/resolver-binding-linux-x64-musl": "npm:1.9.1"
"@unrs/resolver-binding-wasm32-wasi": "npm:1.9.1"
"@unrs/resolver-binding-win32-arm64-msvc": "npm:1.9.1"
"@unrs/resolver-binding-win32-ia32-msvc": "npm:1.9.1"
"@unrs/resolver-binding-win32-x64-msvc": "npm:1.9.1"
napi-postinstall: "npm:^0.2.2"
"@unrs/resolver-binding-android-arm-eabi": "npm:1.9.2"
"@unrs/resolver-binding-android-arm64": "npm:1.9.2"
"@unrs/resolver-binding-darwin-arm64": "npm:1.9.2"
"@unrs/resolver-binding-darwin-x64": "npm:1.9.2"
"@unrs/resolver-binding-freebsd-x64": "npm:1.9.2"
"@unrs/resolver-binding-linux-arm-gnueabihf": "npm:1.9.2"
"@unrs/resolver-binding-linux-arm-musleabihf": "npm:1.9.2"
"@unrs/resolver-binding-linux-arm64-gnu": "npm:1.9.2"
"@unrs/resolver-binding-linux-arm64-musl": "npm:1.9.2"
"@unrs/resolver-binding-linux-ppc64-gnu": "npm:1.9.2"
"@unrs/resolver-binding-linux-riscv64-gnu": "npm:1.9.2"
"@unrs/resolver-binding-linux-riscv64-musl": "npm:1.9.2"
"@unrs/resolver-binding-linux-s390x-gnu": "npm:1.9.2"
"@unrs/resolver-binding-linux-x64-gnu": "npm:1.9.2"
"@unrs/resolver-binding-linux-x64-musl": "npm:1.9.2"
"@unrs/resolver-binding-wasm32-wasi": "npm:1.9.2"
"@unrs/resolver-binding-win32-arm64-msvc": "npm:1.9.2"
"@unrs/resolver-binding-win32-ia32-msvc": "npm:1.9.2"
"@unrs/resolver-binding-win32-x64-msvc": "npm:1.9.2"
napi-postinstall: "npm:^0.2.4"
dependenciesMeta:
"@unrs/resolver-binding-android-arm-eabi":
optional: true
@ -9233,7 +9372,7 @@ __metadata:
optional: true
"@unrs/resolver-binding-win32-x64-msvc":
optional: true
checksum: 10c0/fded9251b6c180c92c0510abe63e4fa9a5a4adcdcf3c9f7920507dc9f1ec756de5e71d1258f12bf4a32f7042e1fe142b6dc1003d8a6fb4d0bf1234226c879b01
checksum: 10c0/e3481cc19ea4b25f888e2412bbd80a729b13527a41b035e784b71d1a7d4e2109b58b174adce989085eb75c787435e80ffb385db2b1598288474f53beb01438c0
languageName: node
linkType: hard
@ -9294,7 +9433,7 @@ __metadata:
languageName: node
linkType: hard
"use-sync-external-store@npm:^1.4.0":
"use-sync-external-store@npm:^1.4.0, use-sync-external-store@npm:^1.5.0":
version: 1.5.0
resolution: "use-sync-external-store@npm:1.5.0"
peerDependencies:
@ -9518,7 +9657,7 @@ __metadata:
languageName: node
linkType: hard
"yaml@npm:^2.3.4, yaml@npm:^2.5.0, yaml@npm:^2.7.1":
"yaml@npm:^2.3.4, yaml@npm:^2.5.0, yaml@npm:^2.7.1, yaml@npm:^2.8.0":
version: 2.8.0
resolution: "yaml@npm:2.8.0"
bin: