From c39a6f417fc95b7d229de3821daee500bdb5c4fd Mon Sep 17 00:00:00 2001 From: Marco <38048104+Invy55@users.noreply.github.com> Date: Mon, 29 Jun 2026 23:02:41 +0200 Subject: [PATCH 01/10] fix accent color (#43) --- src/assets/svg/account_disabled.svg | 53 ++++++++++++++++++++++++++++- src/assets/svg/account_inactive.svg | 2 +- src/assets/svg/login-1.svg | 2 +- src/assets/svg/login-2.svg | 2 +- src/assets/svg/login-3.svg | 2 +- src/assets/svg/logo.svg | 2 +- src/index.css | 14 ++++---- 7 files changed, 64 insertions(+), 13 deletions(-) diff --git a/src/assets/svg/account_disabled.svg b/src/assets/svg/account_disabled.svg index 7eb36e0..e671b24 100644 --- a/src/assets/svg/account_disabled.svg +++ b/src/assets/svg/account_disabled.svg @@ -1 +1,52 @@ - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/svg/account_inactive.svg b/src/assets/svg/account_inactive.svg index 33b3046..4df3d97 100644 --- a/src/assets/svg/account_inactive.svg +++ b/src/assets/svg/account_inactive.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/assets/svg/login-1.svg b/src/assets/svg/login-1.svg index 7ec8e5b..47c1c18 100644 --- a/src/assets/svg/login-1.svg +++ b/src/assets/svg/login-1.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/assets/svg/login-2.svg b/src/assets/svg/login-2.svg index 052f4fa..4be8d70 100644 --- a/src/assets/svg/login-2.svg +++ b/src/assets/svg/login-2.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/assets/svg/login-3.svg b/src/assets/svg/login-3.svg index 954c86a..f2e900e 100644 --- a/src/assets/svg/login-3.svg +++ b/src/assets/svg/login-3.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/assets/svg/logo.svg b/src/assets/svg/logo.svg index 25463b0..fe4f0fb 100644 --- a/src/assets/svg/logo.svg +++ b/src/assets/svg/logo.svg @@ -1 +1 @@ - + diff --git a/src/index.css b/src/index.css index d09261d..40bce93 100644 --- a/src/index.css +++ b/src/index.css @@ -25,7 +25,7 @@ --card-foreground: oklch(0.31 0.06 255.87); --popover: oklch(1 0 0); --popover-foreground: oklch(0.36 0.08 255.16); - --primary: oklch(0.47 0.16 257.42); + --primary: oklch(0.4659 0.1551 257.42); --primary-foreground: oklch(1 0 0); --secondary: oklch(0.88 0.04 259.29); --secondary-foreground: oklch(0.35 0.07 255.46); @@ -45,13 +45,13 @@ --chart-4: oklch(0.83 0.12 88.35); --chart-5: oklch(0.78 0.13 59); --sidebar: oklch(0.93 0.02 255.54); - --sidebar-foreground: oklch(0.47 0.16 257.42); + --sidebar-foreground: oklch(0.4659 0.1551 257.42); --sidebar-primary: oklch(0.4 0.03 285.2); --sidebar-primary-foreground: oklch(0.97 0.01 278.64); --sidebar-accent: oklch(0.95 0.02 255.53); --sidebar-accent-foreground: oklch(0.44 0.14 257.11); --sidebar-border: oklch(0.93 0 286.32); - --sidebar-ring: oklch(0.47 0.16 257.42); + --sidebar-ring: oklch(0.4659 0.1551 257.42); --font-sans: Poppins, sans-serif; --font-serif: Libre Baskerville, serif; --font-mono: Space Mono, monospace; @@ -73,7 +73,7 @@ --card-foreground: oklch(0.9 0.03 255.59); --popover: oklch(0.26 0.03 258.31); --popover-foreground: oklch(0.96 0.01 278.64); - --primary: oklch(0.47 0.16 257.42); + --primary: oklch(0.4659 0.1551 257.42); --primary-foreground: oklch(0.93 0.03 252.46); --secondary: oklch(0.34 0.07 255.44); --secondary-foreground: oklch(0.85 0.03 275.09); @@ -86,7 +86,7 @@ --destructive-foreground: oklch(1 0 0); --border: oklch(0.35 0.04 254.63); --input: oklch(0.3961 0.03 259.05); - --ring: oklch(0.47 0.16 257.42); + --ring: oklch(0.4659 0.1551 257.42); --chart-1: oklch(0.49 0.12 267.94); --chart-2: oklch(0.56 0.19 306.86); --chart-3: oklch(0.72 0.15 58.79); @@ -94,12 +94,12 @@ --chart-5: oklch(0.76 0.12 214.15); --sidebar: oklch(0.24 0.03 259.05); --sidebar-foreground: oklch(0.82 0.02 256.74); - --sidebar-primary: oklch(0.47 0.16 257.42); + --sidebar-primary: oklch(0.4659 0.1551 257.42); --sidebar-primary-foreground: oklch(0.96 0.01 278.64); --sidebar-accent: oklch(0.3 0.03 254.37); --sidebar-accent-foreground: oklch(0.96 0.01 292.8); --sidebar-border: oklch(0.35 0.04 254.63); - --sidebar-ring: oklch(0.47 0.16 257.42); + --sidebar-ring: oklch(0.4659 0.1551 257.42); --font-sans: Poppins, sans-serif; --font-serif: Libre Baskerville, serif; --font-mono: Space Mono, monospace; From ba09a88026caae2503da905b736e711f7db4188c Mon Sep 17 00:00:00 2001 From: Tommaso Morganti Date: Sun, 5 Jul 2026 20:26:56 +0200 Subject: [PATCH 02/10] fix: "Create" button will submit the form for new members (#44) --- .../dashboard/(active)/azure/members/create-assoc-member.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/app/dashboard/(active)/azure/members/create-assoc-member.tsx b/src/app/dashboard/(active)/azure/members/create-assoc-member.tsx index 834a927..3e741f4 100644 --- a/src/app/dashboard/(active)/azure/members/create-assoc-member.tsx +++ b/src/app/dashboard/(active)/azure/members/create-assoc-member.tsx @@ -129,7 +129,9 @@ export function CreateAssocUser() { Cancel - + From 79b68c9d28ba5e5274ccc1847934a2443c53add2 Mon Sep 17 00:00:00 2001 From: Bianca Roberta Ianosel Date: Mon, 13 Jul 2026 10:54:06 +0200 Subject: [PATCH 03/10] feat: Implement guide matricole (#45) --- next.config.ts | 13 +- package.json | 2 +- pnpm-lock.yaml | 10 +- .../(active)/azure/members/table.tsx | 6 +- .../dashboard/(active)/web/guide/columns.tsx | 35 ++++ .../(active)/web/guide/create-guide.tsx | 165 ++++++++++++++++++ .../(active)/web/guide/delete-guide.tsx | 79 +++++++++ src/app/dashboard/(active)/web/guide/page.tsx | 12 ++ .../dashboard/(active)/web/guide/table.tsx | 39 +++++ src/app/dashboard/(active)/web/guide/types.ts | 6 + src/components/dashboard-sidebar/data.tsx | 7 +- src/components/data-table.tsx | 7 +- src/server/actions/guides.ts | 31 ++++ 13 files changed, 396 insertions(+), 16 deletions(-) create mode 100644 src/app/dashboard/(active)/web/guide/columns.tsx create mode 100644 src/app/dashboard/(active)/web/guide/create-guide.tsx create mode 100644 src/app/dashboard/(active)/web/guide/delete-guide.tsx create mode 100644 src/app/dashboard/(active)/web/guide/page.tsx create mode 100644 src/app/dashboard/(active)/web/guide/table.tsx create mode 100644 src/app/dashboard/(active)/web/guide/types.ts create mode 100644 src/server/actions/guides.ts diff --git a/next.config.ts b/next.config.ts index 609ecca..3fa77a8 100644 --- a/next.config.ts +++ b/next.config.ts @@ -10,9 +10,20 @@ const config: NextConfig = { ignoreBuildErrors: true, }, output: "standalone", - transpilePackages: ["@t3-oss/env-nextjs", "@t3-oss/env-core"], + transpilePackages: ["@t3-oss/env-core", "@t3-oss/env-nextjs"], + images: { + remotePatterns: [ + { + protocol: "https", + hostname: "**.blob.core.windows.net", + }, + ], + }, experimental: { reactCompiler: true, + serverActions: { + bodySizeLimit: "2mb", + }, }, } diff --git a/package.json b/package.json index cc55384..68257da 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "@base-ui/react": "^1.3.0", "@better-auth/passkey": "^1.5.5", "@hookform/resolvers": "^3.9.1", - "@polinetwork/backend": "^0.16.0", + "@polinetwork/backend": "^0.16.4", "@radix-ui/react-dialog": "^1.1.15", "@t3-oss/env-nextjs": "^0.13.10", "@tanstack/react-table": "^8.21.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index eb0e106..02ffb24 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -18,8 +18,8 @@ importers: specifier: ^3.9.1 version: 3.10.0(react-hook-form@7.55.0(react@18.3.1)) '@polinetwork/backend': - specifier: ^0.16.0 - version: 0.16.0 + specifier: ^0.16.4 + version: 0.16.4 '@radix-ui/react-dialog': specifier: ^1.1.15 version: 1.1.15(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -841,8 +841,8 @@ packages: resolution: {integrity: sha512-C2Xj8FZ0uHWeCXXqX5B4/gVFQmtSkiuOolzAgutjTfseNOHT3pUjljDZsTSxXFGgio54bCzVFqmEOUrIVk8RDA==} engines: {node: '>=20.0.0'} - '@polinetwork/backend@0.16.0': - resolution: {integrity: sha512-z/xuzvQv9w8frEtKAw59NvfFEllJnx2lw9YVUwTsP9TXh9tfPu5jP1njVUhFGQe15UE+IxwXH1hV4rO0/9/MLg==} + '@polinetwork/backend@0.16.4': + resolution: {integrity: sha512-IspiFAA92uPfYHR2eKj3FCQxX8lVbvlL6lMmEFxEhJbIIaca3Fq1vduRlyDWSo7QC1bpXqzpjjVDUa/jrK+OtA==} '@radix-ui/number@1.1.1': resolution: {integrity: sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==} @@ -4172,7 +4172,7 @@ snapshots: tslib: 2.8.1 tsyringe: 4.10.0 - '@polinetwork/backend@0.16.0': {} + '@polinetwork/backend@0.16.4': {} '@radix-ui/number@1.1.1': {} diff --git a/src/app/dashboard/(active)/azure/members/table.tsx b/src/app/dashboard/(active)/azure/members/table.tsx index 2a5bf70..8209cf5 100644 --- a/src/app/dashboard/(active)/azure/members/table.tsx +++ b/src/app/dashboard/(active)/azure/members/table.tsx @@ -49,11 +49,7 @@ export function AssocTable({ members }: { members: AzureMember[] }) { - + ) } diff --git a/src/app/dashboard/(active)/web/guide/columns.tsx b/src/app/dashboard/(active)/web/guide/columns.tsx new file mode 100644 index 0000000..3e3ba00 --- /dev/null +++ b/src/app/dashboard/(active)/web/guide/columns.tsx @@ -0,0 +1,35 @@ +"use client" +import { createColumnHelper } from "@tanstack/react-table" +import { format } from "date-fns" +import { DeleteGuide } from "./delete-guide" +import type { Guide } from "./types" + +const ch = createColumnHelper() + +export const columns = (onDeleted: (id: number) => void) => [ + ch.accessor("version", { + id: "version", + header: "Version", + cell: ({ getValue }) => {getValue()}, + }), + ch.accessor("date", { + id: "date", + header: "Date", + cell: ({ getValue }) => format(new Date(getValue()), "dd/MM/yyyy"), + }), + ch.accessor("file", { + id: "file", + header: "File", + cell: ({ getValue }) => ( + + Download + + ), + }), + ch.group({ + id: "actions", + cell: (props) => ( + + ), + }), +] diff --git a/src/app/dashboard/(active)/web/guide/create-guide.tsx b/src/app/dashboard/(active)/web/guide/create-guide.tsx new file mode 100644 index 0000000..fa8322b --- /dev/null +++ b/src/app/dashboard/(active)/web/guide/create-guide.tsx @@ -0,0 +1,165 @@ +"use client" + +import { format } from "date-fns" +import { ChevronDownIcon, Plus, Upload } from "lucide-react" +import { useState } from "react" +import { toast } from "sonner" +import { Button } from "@/components/ui/button" +import { Calendar } from "@/components/ui/calendar" +import { + Dialog, + DialogClose, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, + DialogTrigger, +} from "@/components/ui/dialog" +import { Field, FieldLabel } from "@/components/ui/field" +import { Input } from "@/components/ui/input" +import { Label } from "@/components/ui/label" +import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover" +import { createGuide } from "@/server/actions/guides" +import type { Guide } from "./types" + +export function CreateGuide({ + existingVersions, + latestVersion, + onCreated, +}: { + existingVersions: string[] + latestVersion?: string + onCreated: (guide: Guide) => void +}) { + const [open, setOpen] = useState(false) + const [version, setVersion] = useState(latestVersion ?? "") + const [date, setDate] = useState(new Date()) + const [datePickerOpen, setDatePickerOpen] = useState(false) + const [file, setFile] = useState(null) + const [pending, setPending] = useState(false) + + const trimmedVersion = version.trim() + const isDuplicate = trimmedVersion.length > 0 && existingVersions.includes(trimmedVersion) + const disabled = !trimmedVersion || !date || !file || isDuplicate || pending + + function handleOpenChange(v: boolean) { + setOpen(v) + if (v) { + setVersion(latestVersion ?? "") + setDate(new Date()) + setFile(null) + } + } + + async function handleSubmit() { + if (!date || !file || isDuplicate) return + setPending(true) + + try { + const { guide, error } = await createGuide({ version: trimmedVersion, date: date.toISOString(), file }) + + if (error === "UNAUTHORIZED") toast.error("You don't have permission to add guides.") + else if (error === "DUPLICATE_VERSION") toast.error("This version already exists.") + else if (!guide) toast.error("There was an error creating the guide.") + else { + toast.success("Guide created successfully") + onCreated(guide) + handleOpenChange(false) + } + } catch (err) { + toast.error("There was an error") + console.error(err) + } finally { + setPending(false) + } + } + + return ( + + + Add Guide + + } + /> + + + Add Guide + Upload a new version of the Guida della Matricola. + + +
+
+ + setVersion(e.target.value)} + /> + {isDuplicate &&

This version already exists.

} +
+ + + Date + + + {date ? format(date, "dd/MM/yyyy") : "Select date"} + + + } + /> + + { + setDate(d) + setDatePickerOpen(false) + }} + /> + + + + +
+ + + setFile(e.target.files?.[0] ?? null)} + className="sr-only" + /> +
+
+ + + Cancel} /> + + +
+
+ ) +} diff --git a/src/app/dashboard/(active)/web/guide/delete-guide.tsx b/src/app/dashboard/(active)/web/guide/delete-guide.tsx new file mode 100644 index 0000000..9d88482 --- /dev/null +++ b/src/app/dashboard/(active)/web/guide/delete-guide.tsx @@ -0,0 +1,79 @@ +"use client" + +import { OctagonX, Trash } from "lucide-react" +import { useState } from "react" +import { toast } from "sonner" +import { + AlertDialog, + AlertDialogAction, + AlertDialogCancel, + AlertDialogContent, + AlertDialogDescription, + AlertDialogFooter, + AlertDialogHeader, + AlertDialogMedia, + AlertDialogTitle, + AlertDialogTrigger, +} from "@/components/ui/alert-dialog" +import { Button } from "@/components/ui/button" +import { deleteGuide } from "@/server/actions/guides" + +export function DeleteGuide({ + id, + version, + onDeleted, +}: { + id: number + version: string + onDeleted: (id: number) => void +}) { + const [open, setOpen] = useState(false) + + async function handleDelete() { + try { + const { error } = await deleteGuide(id) + + if (error === "UNAUTHORIZED") toast.error("You don't have permission to delete guides.") + else if (error === "NOT_FOUND") toast.info("This guide was already deleted.") + else { + toast.success("Guide deleted successfully") + onDeleted(id) + } + } catch (err) { + toast.error("There was an error") + console.error(err) + } finally { + setOpen(false) + } + } + + return ( + + + + + } + /> + + + + + + Delete Guide + + Are you sure you want to delete version {version}?
+ This action cannot be undone. +
+
+ + Cancel + + Confirm + + +
+
+ ) +} diff --git a/src/app/dashboard/(active)/web/guide/page.tsx b/src/app/dashboard/(active)/web/guide/page.tsx new file mode 100644 index 0000000..8746554 --- /dev/null +++ b/src/app/dashboard/(active)/web/guide/page.tsx @@ -0,0 +1,12 @@ +import { getAllGuides } from "@/server/actions/guides" +import { GuideTable } from "./table" + +export default async function GuideMatricolaPage() { + const guides = await getAllGuides() + + return ( +
+ +
+ ) +} diff --git a/src/app/dashboard/(active)/web/guide/table.tsx b/src/app/dashboard/(active)/web/guide/table.tsx new file mode 100644 index 0000000..860b9cc --- /dev/null +++ b/src/app/dashboard/(active)/web/guide/table.tsx @@ -0,0 +1,39 @@ +"use client" + +import { useRouter } from "next/navigation" +import { useState } from "react" +import { DataTable } from "@/components/data-table" +import { columns } from "./columns" +import { CreateGuide } from "./create-guide" +import type { Guide } from "./types" + +export function GuideTable({ guides }: { guides: Guide[] }) { + const router = useRouter() + const [items, setItems] = useState(guides) + + function handleCreated(guide: Guide) { + setItems((prev) => [guide, ...prev]) + router.refresh() + } + + function handleDeleted(id: number) { + setItems((prev) => prev.filter((g) => g.id !== id)) + router.refresh() + } + + return ( +
+
+

Guida della Matricola

+
+ g.version)} + latestVersion={items[0]?.version} + onCreated={handleCreated} + /> +
+ + +
+ ) +} diff --git a/src/app/dashboard/(active)/web/guide/types.ts b/src/app/dashboard/(active)/web/guide/types.ts new file mode 100644 index 0000000..fdc74b2 --- /dev/null +++ b/src/app/dashboard/(active)/web/guide/types.ts @@ -0,0 +1,6 @@ +export type Guide = { + id: number + version: string + date: string + file: string +} diff --git a/src/components/dashboard-sidebar/data.tsx b/src/components/dashboard-sidebar/data.tsx index 7401a0c..c2e862d 100644 --- a/src/components/dashboard-sidebar/data.tsx +++ b/src/components/dashboard-sidebar/data.tsx @@ -1,4 +1,4 @@ -import { MessageCircleMoreIcon, Sparkle, Users } from "lucide-react" +import { BookOpen, Globe, MessageCircleMoreIcon, Sparkle, Users } from "lucide-react" import Image from "next/image" import azureSvg from "@/assets/svg/azure.svg" import telegramSvg from "@/assets/svg/telegram.svg" @@ -19,6 +19,11 @@ export const DSData = { icon: azure logo, items: [{ title: "Members", url: "/dashboard/azure/members", icon: }], }, + { + title: "Web", + icon: , + items: [{ title: "Guide", url: "/dashboard/web/guide", icon: }], + }, ], } diff --git a/src/components/data-table.tsx b/src/components/data-table.tsx index acc07c7..c97f7bc 100644 --- a/src/components/data-table.tsx +++ b/src/components/data-table.tsx @@ -11,12 +11,13 @@ import { import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table" -interface DataTableProps { - columns: ColumnDef[] +interface DataTableProps { + // biome-ignore lint/suspicious/noExplicitAny: columns commonly mix accessor value types (string, number, group columns...) + columns: ColumnDef[] data: TData[] } -export function DataTable({ columns, data }: DataTableProps) { +export function DataTable({ columns, data }: DataTableProps) { const table = useReactTable({ data, columns, diff --git a/src/server/actions/guides.ts b/src/server/actions/guides.ts new file mode 100644 index 0000000..eb9c207 --- /dev/null +++ b/src/server/actions/guides.ts @@ -0,0 +1,31 @@ +"use server" + +import { requireRole } from "../auth" +import { trpc } from "../trpc" + +export async function getAllGuides() { + return await trpc.web.guides_matricole.getAllGuides.query() +} + +export async function createGuide(input: { version: string; date: string; file: File }) { + const { allowed, telegramId } = await requireRole(["owner", "direttivo", "president"]) + if (!allowed) return { guide: null, error: "UNAUTHORIZED" as const } + + const formData = new FormData() + formData.set("version", input.version) + formData.set("date", input.date) + formData.set("file", input.file) + formData.set("createdBy", String(telegramId)) + + const result = await trpc.web.guides_matricole.addGuide.mutate(formData) + if ("error" in result) return { guide: null, error: result.error } + + return { guide: result, error: null } +} + +export async function deleteGuide(id: number) { + const { allowed } = await requireRole(["owner", "direttivo", "president"]) + if (!allowed) return { error: "UNAUTHORIZED" as const } + + return await trpc.web.guides_matricole.deleteGuide.mutate({ id }) +} From 41ed41e598397f1995a1e3b801cd155fd62ae2c0 Mon Sep 17 00:00:00 2001 From: Lorenzo Corallo Date: Thu, 16 Jul 2026 19:35:03 +0200 Subject: [PATCH 04/10] fix: move FormData creation to frontend --- src/app/dashboard/(active)/web/guide/create-guide.tsx | 8 ++++++-- src/server/actions/guides.ts | 6 +----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/app/dashboard/(active)/web/guide/create-guide.tsx b/src/app/dashboard/(active)/web/guide/create-guide.tsx index fa8322b..6799ad0 100644 --- a/src/app/dashboard/(active)/web/guide/create-guide.tsx +++ b/src/app/dashboard/(active)/web/guide/create-guide.tsx @@ -57,7 +57,11 @@ export function CreateGuide({ setPending(true) try { - const { guide, error } = await createGuide({ version: trimmedVersion, date: date.toISOString(), file }) + const formData = new FormData() + formData.set("version", trimmedVersion) + formData.set("date", date.toISOString()) + formData.set("file", file) + const { guide, error } = await createGuide(formData) if (error === "UNAUTHORIZED") toast.error("You don't have permission to add guides.") else if (error === "DUPLICATE_VERSION") toast.error("This version already exists.") @@ -96,7 +100,7 @@ export function CreateGuide({ Date: Wed, 22 Jul 2026 13:48:22 +0200 Subject: [PATCH 05/10] feat: Azure groups (#48) * feat: azure groups, first implementation * feat: divide group list based on member count * feat: new api, some styling changes and fixes * fix: update backend pkg --- package.json | 2 +- pnpm-lock.yaml | 10 +- .../(active)/azure/groups/groups-list.tsx | 443 ++++++++++++++++++ .../(active)/azure/groups/loading.tsx | 44 ++ .../dashboard/(active)/azure/groups/page.tsx | 17 + src/components/dashboard-sidebar/data.tsx | 7 +- src/components/dashboard-sidebar/user-nav.tsx | 8 +- src/components/ui/avatar.tsx | 2 +- src/components/ui/tooltip.tsx | 2 +- src/server/actions/azure.ts | 20 + src/server/trpc/types.tsx | 1 + 11 files changed, 541 insertions(+), 15 deletions(-) create mode 100644 src/app/dashboard/(active)/azure/groups/groups-list.tsx create mode 100644 src/app/dashboard/(active)/azure/groups/loading.tsx create mode 100644 src/app/dashboard/(active)/azure/groups/page.tsx diff --git a/package.json b/package.json index 68257da..188d543 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "@base-ui/react": "^1.3.0", "@better-auth/passkey": "^1.5.5", "@hookform/resolvers": "^3.9.1", - "@polinetwork/backend": "^0.16.4", + "@polinetwork/backend": "^0.17.0", "@radix-ui/react-dialog": "^1.1.15", "@t3-oss/env-nextjs": "^0.13.10", "@tanstack/react-table": "^8.21.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 02ffb24..b2a7d41 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -18,8 +18,8 @@ importers: specifier: ^3.9.1 version: 3.10.0(react-hook-form@7.55.0(react@18.3.1)) '@polinetwork/backend': - specifier: ^0.16.4 - version: 0.16.4 + specifier: ^0.17.0 + version: 0.17.0 '@radix-ui/react-dialog': specifier: ^1.1.15 version: 1.1.15(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -841,8 +841,8 @@ packages: resolution: {integrity: sha512-C2Xj8FZ0uHWeCXXqX5B4/gVFQmtSkiuOolzAgutjTfseNOHT3pUjljDZsTSxXFGgio54bCzVFqmEOUrIVk8RDA==} engines: {node: '>=20.0.0'} - '@polinetwork/backend@0.16.4': - resolution: {integrity: sha512-IspiFAA92uPfYHR2eKj3FCQxX8lVbvlL6lMmEFxEhJbIIaca3Fq1vduRlyDWSo7QC1bpXqzpjjVDUa/jrK+OtA==} + '@polinetwork/backend@0.17.0': + resolution: {integrity: sha512-NfU0i4It86LOMsZ5xyOX8ccOcbazwsC8j/D/B4sBb9PaJjENAdyFS27l9I4i0ihM2MrcFBJixxDdmnPO7/D/Rg==} '@radix-ui/number@1.1.1': resolution: {integrity: sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==} @@ -4172,7 +4172,7 @@ snapshots: tslib: 2.8.1 tsyringe: 4.10.0 - '@polinetwork/backend@0.16.4': {} + '@polinetwork/backend@0.17.0': {} '@radix-ui/number@1.1.1': {} diff --git a/src/app/dashboard/(active)/azure/groups/groups-list.tsx b/src/app/dashboard/(active)/azure/groups/groups-list.tsx new file mode 100644 index 0000000..41909c7 --- /dev/null +++ b/src/app/dashboard/(active)/azure/groups/groups-list.tsx @@ -0,0 +1,443 @@ +"use client" + +import { ChevronDown, Info, LoaderCircle, Mail, UserMinus, UserPlus } from "lucide-react" +import { useRouter } from "next/navigation" +import { useMemo, useState } from "react" +import { toast } from "sonner" +import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert" +import { Avatar, AvatarFallback, AvatarGroup, AvatarGroupCount } from "@/components/ui/avatar" +import { Badge } from "@/components/ui/badge" +import { Button } from "@/components/ui/button" +import { Card, CardContent, CardHeader } from "@/components/ui/card" +import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/components/ui/collapsible" +import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from "@/components/ui/command" +import { + Dialog, + DialogClose, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, + DialogTrigger, +} from "@/components/ui/dialog" +import { Separator } from "@/components/ui/separator" +import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip" +import { addAzureGroupMember, removeAzureGroupMember } from "@/server/actions/azure" +import type { AzureGroup, AzureMember } from "@/server/trpc/types" + +const MAX_VISIBLE_MEMBERS = 7 + +function initials(name: string | null | undefined) { + const parts = name?.trim().split(/\s+/).filter(Boolean) ?? [] + if (parts.length === 0) return "?" + return parts + .slice(0, 2) + .map((part) => part[0]) + .join("") + .toUpperCase() +} + +function mutationErrorMessage(error: "UNAUTHORIZED" | "INTERNAL_SERVER_ERROR") { + if (error === "UNAUTHORIZED") return "You don't have permission to manage this group." + return "Microsoft 365 could not complete the change. Please try again." +} + +export function GroupsList({ groups, directoryMembers }: { groups: AzureGroup[]; directoryMembers: AzureMember[] }) { + const sortedGroups = useMemo(() => [...groups].sort((a, b) => a.displayName.localeCompare(b.displayName)), [groups]) + const multiMemberGroups = sortedGroups.filter((group) => group.members.length > 1) + const singleMemberGroups = sortedGroups.filter((group) => group.members.length <= 1) + const memberships = groups.reduce((count, group) => count + group.members.length, 0) + + return ( +
+
+

Azure directory

+
+
+
+

Microsoft 365 Groups

+
+ {groups.length} groups + {memberships} memberships +
+
+ + + Looking for groups with 0-1 member(s)? + + Groups with max one member are collected in a collapsed section at the bottom of the page. + + +
+
+
+ + {multiMemberGroups.length > 0 && ( + + + + + + Groups with 2+ members + + {multiMemberGroups.length} {singleMemberGroups.length === 1 ? "group" : "groups"} + + + + + } + /> + + }> + {multiMemberGroups.map((group) => ( +
+ + +
+ ))} +
+
+
+ )} + + {singleMemberGroups.length > 0 && ( + + + + + + Groups with 0-1 member + + {singleMemberGroups.length} {singleMemberGroups.length === 1 ? "group" : "groups"} + + + + + } + /> + + }> + {singleMemberGroups.map((group) => ( +
+ + +
+ ))} +
+
+
+ )} +
+ ) +} + +function GroupRow({ group, directoryMembers }: { group: AzureGroup; directoryMembers: AzureMember[] }) { + const sortedMembers = [...group.members].sort((a, b) => a.displayName.localeCompare(b.displayName)) + const visibleMembers = sortedMembers.slice(0, MAX_VISIBLE_MEMBERS) + const hiddenMembers = sortedMembers.slice(MAX_VISIBLE_MEMBERS) + + return ( +
+
+
+

{group.displayName}

+ {group.mailAddress && ( +
+ + {group.mailAddress} +
+ )} +
+ + {group.members.length} {group.members.length === 1 ? "member" : "members"} + +
+ +
+ {group.members.length > 0 ? ( + + {visibleMembers.map((member) => ( + + ))} + {hiddenMembers.length > 0 && } + + ) : ( +

No members yet

+ )} +
+ + +
+
+
+ ) +} + +function MemberAvatar({ member }: { member: AzureGroup["members"][number] }) { + return ( + + + + {initials(member.displayName)} + + + {member.displayName} + + ) +} + +function HiddenMembersCount({ members }: { members: AzureGroup["members"] }) { + return ( + + + +{members.length} + + + {members.map((member) => ( +
+ + {initials(member.displayName)} + + {member.displayName} +
+ ))} +
+
+ ) +} + +function AddMemberDialog({ group, directoryMembers }: { group: AzureGroup; directoryMembers: AzureMember[] }) { + const [open, setOpen] = useState(false) + const [pending, setPending] = useState(false) + const [selectedMember, setSelectedMember] = useState(null) + const router = useRouter() + + const availableMembers = useMemo(() => { + const currentIds = new Set(group.members.map((member) => member.id)) + return directoryMembers + .filter((member) => !currentIds.has(member.id)) + .sort((a, b) => (a.displayName ?? "").localeCompare(b.displayName ?? "")) + }, [directoryMembers, group.members]) + + function handleOpenChange(nextOpen: boolean) { + if (pending) return + setOpen(nextOpen) + if (!nextOpen) setSelectedMember(null) + } + + async function addMember() { + if (!selectedMember || pending) return + + setPending(true) + try { + const { error } = await addAzureGroupMember({ groupId: group.id, userId: selectedMember.id }) + if (error) { + toast.error(mutationErrorMessage(error)) + return + } + + toast.success(`${selectedMember.displayName ?? "Member"} added to ${group.displayName}.`) + setOpen(false) + setSelectedMember(null) + router.refresh() + } catch (error) { + console.error(error) + toast.error("There was an unexpected error while adding the member.") + } finally { + setPending(false) + } + } + + return ( + + + } + /> + } + > + + + Add member + + + + Add a group member + + Choose a directory user to add to {group.displayName}. + + + + + + + No available users found. + + {availableMembers.map((member) => ( + setSelectedMember(member)} + > + + {initials(member.displayName)} + +
+ {member.displayName ?? "Unnamed user"} + {member.mail && {member.mail}} +
+
+ ))} +
+
+
+ + + + Cancel + + } + /> + + +
+
+ ) +} + +function RemoveMemberDialog({ group, directoryMembers }: { group: AzureGroup; directoryMembers: AzureMember[] }) { + const [open, setOpen] = useState(false) + const [pending, setPending] = useState(false) + const [selectedMember, setSelectedMember] = useState(null) + const router = useRouter() + + const currentMembers = useMemo(() => { + const currentIds = new Set(group.members.map((member) => member.id)) + return directoryMembers + .filter((member) => currentIds.has(member.id)) + .sort((a, b) => (a.displayName ?? "").localeCompare(b.displayName ?? "")) + }, [directoryMembers, group.members]) + + function handleOpenChange(nextOpen: boolean) { + if (pending) return + setOpen(nextOpen) + if (!nextOpen) setSelectedMember(null) + } + + async function removeMember() { + if (!selectedMember || pending) return + + setPending(true) + try { + const { error } = await removeAzureGroupMember({ groupId: group.id, userId: selectedMember.id }) + if (error) { + toast.error(mutationErrorMessage(error)) + return + } + + toast.success(`${selectedMember.displayName ?? "Member"} removed from ${group.displayName}.`) + setOpen(false) + setSelectedMember(null) + router.refresh() + } catch (error) { + console.error(error) + toast.error("There was an unexpected error while removing the member.") + } finally { + setPending(false) + } + } + + return ( + + + + } + /> + } + > + + + Remove member + + + + + Remove a group member + + Choose a member to remove from {group.displayName}. + Their Microsoft 365 account will not be deleted. + + + + + + + No group members found. + + {currentMembers.map((member) => ( + setSelectedMember(member)} + > + + {initials(member.displayName)} + +
+ {member.displayName ?? "Unnamed user"} + {member.mail && {member.mail}} +
+
+ ))} +
+
+
+ + + + Cancel + + } + /> + + +
+
+ ) +} diff --git a/src/app/dashboard/(active)/azure/groups/loading.tsx b/src/app/dashboard/(active)/azure/groups/loading.tsx new file mode 100644 index 0000000..cb33360 --- /dev/null +++ b/src/app/dashboard/(active)/azure/groups/loading.tsx @@ -0,0 +1,44 @@ +import { Card, CardContent, CardHeader } from "@/components/ui/card" +import { Separator } from "@/components/ui/separator" +import { Skeleton } from "@/components/ui/skeleton" + +export default function Loading() { + return ( +
+
+
+ + + +
+ + + + + + + + {Array.from({ length: 4 }, (_, index) => ( +
+ {index > 0 && } +
+
+ + + +
+
+ {Array.from({ length: 5 }, (_, avatarIndex) => ( + + ))} + +
+
+
+ ))} +
+
+
+
+ ) +} diff --git a/src/app/dashboard/(active)/azure/groups/page.tsx b/src/app/dashboard/(active)/azure/groups/page.tsx new file mode 100644 index 0000000..ef7cfd2 --- /dev/null +++ b/src/app/dashboard/(active)/azure/groups/page.tsx @@ -0,0 +1,17 @@ +import type { Metadata } from "next" +import { getAzureGroups, getAzureMembers } from "@/server/actions/azure" +import { GroupsList } from "./groups-list" + +export const metadata: Metadata = { + title: "Microsoft 365 Groups", +} + +export default async function AzureGroupsPage() { + const [groups, directoryMembers] = await Promise.all([getAzureGroups(), getAzureMembers()]) + + return ( +
+ +
+ ) +} diff --git a/src/components/dashboard-sidebar/data.tsx b/src/components/dashboard-sidebar/data.tsx index c2e862d..a50c731 100644 --- a/src/components/dashboard-sidebar/data.tsx +++ b/src/components/dashboard-sidebar/data.tsx @@ -1,4 +1,4 @@ -import { BookOpen, Globe, MessageCircleMoreIcon, Sparkle, Users } from "lucide-react" +import { BookOpen, Globe, MessageCircleMoreIcon, Sparkle, Users, UsersRound } from "lucide-react" import Image from "next/image" import azureSvg from "@/assets/svg/azure.svg" import telegramSvg from "@/assets/svg/telegram.svg" @@ -17,7 +17,10 @@ export const DSData = { { title: "Azure", icon: azure logo, - items: [{ title: "Members", url: "/dashboard/azure/members", icon: }], + items: [ + { title: "Groups", url: "/dashboard/azure/groups", icon: }, + { title: "Members", url: "/dashboard/azure/members", icon: }, + ], }, { title: "Web", diff --git a/src/components/dashboard-sidebar/user-nav.tsx b/src/components/dashboard-sidebar/user-nav.tsx index 580c2cc..40ceabe 100644 --- a/src/components/dashboard-sidebar/user-nav.tsx +++ b/src/components/dashboard-sidebar/user-nav.tsx @@ -38,11 +38,9 @@ export function DSUserNav() { size="lg" className="data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground" > - + - - {user.name ? getInitials(user.name) : } - + {user.name ? getInitials(user.name) : }
{user.name} @@ -61,7 +59,7 @@ export function DSUserNav() {
- + {user.name ? getInitials(user.name) : } diff --git a/src/components/ui/avatar.tsx b/src/components/ui/avatar.tsx index 0de72e0..64ce76b 100644 --- a/src/components/ui/avatar.tsx +++ b/src/components/ui/avatar.tsx @@ -17,7 +17,7 @@ function Avatar({ data-slot="avatar" data-size={size} className={cn( - "group/avatar relative flex size-8 shrink-0 rounded-full select-none after:absolute after:inset-0 after:rounded-full after:border after:border-border after:mix-blend-darken data-[size=lg]:size-10 data-[size=sm]:size-6 dark:after:mix-blend-lighten", + "group/avatar relative flex size-8 shrink-0 rounded-full select-none after:absolute after:inset-0 after:rounded-full after:border after:border-input after:mix-blend-darken data-[size=lg]:size-10 data-[size=sm]:size-6 dark:after:mix-blend-lighten", className )} {...props} diff --git a/src/components/ui/tooltip.tsx b/src/components/ui/tooltip.tsx index b64148d..aac35fa 100644 --- a/src/components/ui/tooltip.tsx +++ b/src/components/ui/tooltip.tsx @@ -56,7 +56,7 @@ function TooltipContent({ {...props} > {children} - + {/* */} diff --git a/src/server/actions/azure.ts b/src/server/actions/azure.ts index 5c7594f..67d8a08 100644 --- a/src/server/actions/azure.ts +++ b/src/server/actions/azure.ts @@ -21,3 +21,23 @@ export async function setAzureMemberNumber(input: ApiInput["azure"]["members"][" return await trpc.azure.members.setAssocNumber.mutate(input) } + +export async function getAzureGroups() { + return await trpc.azure.groups.getAll.query() +} + +export async function addAzureGroupMember(input: ApiInput["azure"]["groups"]["addMember"]) { + const { allowed } = await requireRole(["owner", "direttivo", "president"]) + if (!allowed) return { error: "UNAUTHORIZED" as const } + + const success = await trpc.azure.groups.addMember.mutate(input) + return { error: success ? null : ("INTERNAL_SERVER_ERROR" as const) } +} + +export async function removeAzureGroupMember(input: ApiInput["azure"]["groups"]["removeMember"]) { + const { allowed } = await requireRole(["owner", "direttivo", "president"]) + if (!allowed) return { error: "UNAUTHORIZED" as const } + + const success = await trpc.azure.groups.removeMember.mutate(input) + return { error: success ? null : ("INTERNAL_SERVER_ERROR" as const) } +} diff --git a/src/server/trpc/types.tsx b/src/server/trpc/types.tsx index 7962e62..a81a172 100644 --- a/src/server/trpc/types.tsx +++ b/src/server/trpc/types.tsx @@ -11,3 +11,4 @@ export type TgGroup = NonNullable export type AzureMember = ApiOutput["azure"]["members"]["getAll"][number] +export type AzureGroup = ApiOutput["azure"]["groups"]["getAll"][number] From c6dd57f236b07e9fd403b0413e942a2b3e9d382a Mon Sep 17 00:00:00 2001 From: Alessandro Giuseppe Gioia Date: Thu, 23 Jul 2026 00:07:17 +0200 Subject: [PATCH 06/10] style: convert all lucide icons to react icons (#50) Co-authored-by: CodeRabbit Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- package.json | 2 +- pnpm-lock.yaml | 24 +++++----- src/app/(auth)/login/can-i-access.tsx | 14 +++--- src/app/(auth)/login/login-button.tsx | 4 +- src/app/(auth)/login/login-form.tsx | 12 ++--- src/app/(auth)/login/what-is.tsx | 46 +++++++++---------- src/app/(auth)/onboarding/link/telegram.tsx | 6 +-- .../(active)/account/delete-passkey.tsx | 4 +- src/app/dashboard/(active)/account/page.tsx | 8 ++-- .../(active)/account/profile-pic.tsx | 10 ++-- .../(active)/azure/groups/groups-list.tsx | 22 ++++----- .../dashboard/(active)/complete-profile.tsx | 4 +- src/app/dashboard/(active)/page.tsx | 4 +- .../(active)/telegram/grants/delete-grant.tsx | 6 +-- .../(active)/telegram/grants/new-grant.tsx | 6 +-- .../(active)/telegram/groups/group-row.tsx | 4 +- .../(active)/telegram/groups/leave-chat.tsx | 6 +-- .../(active)/telegram/users/[id]/add-role.tsx | 4 +- .../telegram/users/[id]/card-message.tsx | 6 +-- .../telegram/users/[id]/card-user-grant.tsx | 4 +- .../telegram/users/[id]/card-user-info.tsx | 4 +- .../users/[id]/delete-group-admin.tsx | 6 +-- .../telegram/users/[id]/new-group-admin.tsx | 8 ++-- .../(active)/telegram/users/[id]/page.tsx | 4 +- .../telegram/users/[id]/remove-role.tsx | 4 +- .../(active)/telegram/users/page.tsx | 4 +- .../(active)/web/guide/create-guide.tsx | 8 ++-- .../(active)/web/guide/delete-guide.tsx | 6 +-- src/components/dashboard-sidebar/data.tsx | 16 +++---- src/components/dashboard-sidebar/main-nav.tsx | 4 +- src/components/dashboard-sidebar/user-nav.tsx | 14 +++--- src/components/header-login-button.tsx | 6 +-- src/components/header.tsx | 4 +- src/components/logout-button.tsx | 4 +- src/components/navigate-back.tsx | 4 +- src/components/search-input.tsx | 6 +-- src/components/theme-button.tsx | 6 +-- src/components/ui/breadcrumb.tsx | 7 ++- src/components/ui/calendar.tsx | 8 ++-- src/components/ui/command.tsx | 6 +-- src/components/ui/dialog.tsx | 6 +-- src/components/ui/dropdown-menu.tsx | 10 ++-- src/components/ui/input-otp.tsx | 5 +- src/components/ui/select.tsx | 12 ++--- src/components/ui/sheet.tsx | 5 +- src/components/ui/sidebar.tsx | 4 +- src/components/ui/sonner.tsx | 12 ++--- src/components/user-select.tsx | 6 +-- 48 files changed, 188 insertions(+), 197 deletions(-) diff --git a/package.json b/package.json index 188d543..78b8ec7 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,6 @@ "date-fns": "^4.1.0", "geist": "^1.3.0", "input-otp": "^1.4.2", - "lucide-react": "^0.525.0", "next": "^15.5.18", "next-themes": "^0.4.4", "postgres": "^3.4.4", @@ -40,6 +39,7 @@ "react-dom": "^18.3.1", "react-error-boundary": "^6.1.0", "react-hook-form": "^7.55.0", + "react-icons": "^5.7.0", "server-only": "^0.0.1", "shadcn": "^4.2.0", "sonner": "^2.0.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b2a7d41..11dc93d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -59,9 +59,6 @@ importers: input-otp: specifier: ^1.4.2 version: 1.4.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - lucide-react: - specifier: ^0.525.0 - version: 0.525.0(react@18.3.1) next: specifier: ^15.5.18 version: 15.5.18(@babel/core@7.29.0)(babel-plugin-react-compiler@1.0.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -89,6 +86,9 @@ importers: react-hook-form: specifier: ^7.55.0 version: 7.55.0(react@18.3.1) + react-icons: + specifier: ^5.7.0 + version: 5.7.0(react@18.3.1) server-only: specifier: ^0.0.1 version: 0.0.1 @@ -2638,11 +2638,6 @@ packages: lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} - lucide-react@0.525.0: - resolution: {integrity: sha512-Tm1txJ2OkymCGkvwoHt33Y2JpN5xucVq1slHcgE6Lk0WjDfjgKWor5CdVER8U6DvcfMwh4M8XxmpTiyzfmfDYQ==} - peerDependencies: - react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 - math-intrinsics@1.1.0: resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} engines: {node: '>= 0.4'} @@ -2993,6 +2988,11 @@ packages: peerDependencies: react: ^16.8.0 || ^17 || ^18 || ^19 + react-icons@5.7.0: + resolution: {integrity: sha512-LBLy340Rzqy6+/yVhZKT3B/QpP1BZaesGqasf09HPOBzRarcDIFH0WwXlXQfE7q7ipxK4MSiC5DIBWURCny6fw==} + peerDependencies: + react: '*' + react-remove-scroll-bar@2.3.8: resolution: {integrity: sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==} engines: {node: '>=10'} @@ -5826,10 +5826,6 @@ snapshots: dependencies: yallist: 3.1.1 - lucide-react@0.525.0(react@18.3.1): - dependencies: - react: 18.3.1 - math-intrinsics@1.1.0: {} media-typer@1.1.0: {} @@ -6192,6 +6188,10 @@ snapshots: dependencies: react: 18.3.1 + react-icons@5.7.0(react@18.3.1): + dependencies: + react: 18.3.1 + react-remove-scroll-bar@2.3.8(@types/react@18.3.18)(react@18.3.1): dependencies: react: 18.3.1 diff --git a/src/app/(auth)/login/can-i-access.tsx b/src/app/(auth)/login/can-i-access.tsx index c95bc4c..00fd427 100644 --- a/src/app/(auth)/login/can-i-access.tsx +++ b/src/app/(auth)/login/can-i-access.tsx @@ -1,5 +1,5 @@ -import { Award, Building, Gem, Lock, ShieldUser, Star } from "lucide-react" import Image from "next/image" +import { FiAward, FiBriefcase, FiHexagon, FiLock, FiShield, FiStar } from "react-icons/fi" import loginSvg1 from "@/assets/svg/login-1.svg" import loginSvg2 from "@/assets/svg/login-2.svg" import loginSvg3 from "@/assets/svg/login-3.svg" @@ -10,16 +10,16 @@ export function CanIAccess() { return (
- +

How can I access?

You can access this dashboard if you have at least one of this role:

- - - - - + + + + +

When you have checked that you are eligible, these are the steps to access:

diff --git a/src/app/(auth)/login/login-button.tsx b/src/app/(auth)/login/login-button.tsx index 51c6226..748d318 100644 --- a/src/app/(auth)/login/login-button.tsx +++ b/src/app/(auth)/login/login-button.tsx @@ -1,6 +1,6 @@ "use client" -import { LogInIcon } from "lucide-react" import Link from "next/link" +import { FiLogIn } from "react-icons/fi" import { Card, CardContent } from "@/components/ui/card" export function LoginButton() { @@ -9,7 +9,7 @@ export function LoginButton() {
- +

Enter your reserved area

diff --git a/src/app/(auth)/login/login-form.tsx b/src/app/(auth)/login/login-form.tsx index e7ccd37..c810324 100644 --- a/src/app/(auth)/login/login-form.tsx +++ b/src/app/(auth)/login/login-form.tsx @@ -1,8 +1,8 @@ "use client" -import { Key, Loader2, Mail } from "lucide-react" import { useRouter } from "next/navigation" import { useState } from "react" +import { FiKey, FiLoader, FiMail } from "react-icons/fi" import { toast } from "sonner" import { Button } from "@/components/ui/button" import { FieldSeparator } from "@/components/ui/field" @@ -101,10 +101,10 @@ function EmailCard({
@@ -189,7 +189,7 @@ function OTPCard({ email }: { email: string }) {
) diff --git a/src/app/(auth)/login/what-is.tsx b/src/app/(auth)/login/what-is.tsx index c9f34e5..29344d8 100644 --- a/src/app/(auth)/login/what-is.tsx +++ b/src/app/(auth)/login/what-is.tsx @@ -1,23 +1,23 @@ +import type { IconType } from "react-icons" import { - BookOpen, - Bot, - CircleEllipsis, - ClipboardList, - Gavel, - HelpCircle, - LayoutTemplate, - type LucideIcon, - PencilLine, - ShieldCheck, - Users, -} from "lucide-react" + FiBookOpen, + FiCheckSquare, + FiClipboard, + FiCpu, + FiEdit3, + FiHelpCircle, + FiLayout, + FiMoreHorizontal, + FiShield, + FiUsers, +} from "react-icons/fi" import { Card } from "@/components/ui/card" export function WhatIs() { return (
- +

What is this?

@@ -26,15 +26,15 @@ export function WhatIs() {

What actions you can perform depends on your role, but some remarkable ones are:

- - - - - - - - - + + + + + + + + +

It's clear that you'll have access to different features depending on your role(s). @@ -43,7 +43,7 @@ export function WhatIs() { ) } -export function FeatureBox({ icon: Icon, feature }: { icon: LucideIcon; feature: string }) { +export function FeatureBox({ icon: Icon, feature }: { icon: IconType; feature: string }) { return (

diff --git a/src/app/(auth)/onboarding/link/telegram.tsx b/src/app/(auth)/onboarding/link/telegram.tsx index 86d5e0a..d6dd6bd 100644 --- a/src/app/(auth)/onboarding/link/telegram.tsx +++ b/src/app/(auth)/onboarding/link/telegram.tsx @@ -1,8 +1,8 @@ "use client" import { APIError } from "better-auth/api" -import { CircleCheckBig, ClockAlertIcon } from "lucide-react" import { useRouter } from "next/navigation" import { useCallback, useEffect, useState } from "react" +import { FiCheckCircle, FiClock } from "react-icons/fi" import { toast } from "sonner" import { Code } from "@/components/code" import { InputWithPrefix } from "@/components/input-prefix" @@ -104,7 +104,7 @@ export function TelegramLink({ botUsername }: { botUsername: string }) { if (success) return (
- +

Linked successfully!

Redirecting you in 5s...

@@ -113,7 +113,7 @@ export function TelegramLink({ botUsername }: { botUsername: string }) { if (expired) return (
- +

Code Expired!

diff --git a/src/app/dashboard/(active)/account/delete-passkey.tsx b/src/app/dashboard/(active)/account/delete-passkey.tsx index 0047e80..56a1435 100644 --- a/src/app/dashboard/(active)/account/delete-passkey.tsx +++ b/src/app/dashboard/(active)/account/delete-passkey.tsx @@ -1,7 +1,7 @@ "use client" -import { Trash2Icon } from "lucide-react" import { useRouter } from "next/navigation" +import { FiTrash2 } from "react-icons/fi" import { toast } from "sonner" import { AlertDialog, @@ -34,7 +34,7 @@ export function DeletePasskey({ id }: { id: string }) { - + Remove passkey Are you sure you want to delete this passkey? diff --git a/src/app/dashboard/(active)/account/page.tsx b/src/app/dashboard/(active)/account/page.tsx index 0ac592a..8267448 100644 --- a/src/app/dashboard/(active)/account/page.tsx +++ b/src/app/dashboard/(active)/account/page.tsx @@ -1,5 +1,5 @@ -import { Calendar, CircleAlert, KeyIcon } from "lucide-react" import { headers } from "next/headers" +import { FiAlertCircle, FiCalendar, FiKey } from "react-icons/fi" import { auth } from "@/lib/auth" import { getServerSession } from "@/server/auth" import { DeletePasskey } from "./delete-passkey" @@ -28,7 +28,7 @@ export default async function Account() {
- {!user.name && } + {!user.name && } Name: {user.name ?

{user.name}

: }
@@ -48,12 +48,12 @@ export default async function Account() { {passkeys?.map((p) => (
- +

{p.name}

- + Created on {p.createdAt.toLocaleDateString()}

diff --git a/src/app/dashboard/(active)/account/profile-pic.tsx b/src/app/dashboard/(active)/account/profile-pic.tsx index 43d17dc..bfdf238 100644 --- a/src/app/dashboard/(active)/account/profile-pic.tsx +++ b/src/app/dashboard/(active)/account/profile-pic.tsx @@ -1,9 +1,9 @@ "use client" import type { User } from "better-auth" -import { Pencil, Upload, UserIcon, X } from "lucide-react" import { useRouter } from "next/navigation" import { forwardRef, useRef } from "react" +import { FiEdit2, FiUpload, FiUser, FiX } from "react-icons/fi" import { toast } from "sonner" import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar" import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu" @@ -42,15 +42,15 @@ export function ProfilePic({ user }: Props) {
- +
uploadRef.current?.click()}> - Upload + Upload - Remove + Remove
@@ -59,7 +59,7 @@ export function ProfilePic({ user }: Props) { - {user.name ? getInitials(user.name) : } + {user.name ? getInitials(user.name) : }

Max 1MB

diff --git a/src/app/dashboard/(active)/azure/groups/groups-list.tsx b/src/app/dashboard/(active)/azure/groups/groups-list.tsx index 41909c7..2bf11d5 100644 --- a/src/app/dashboard/(active)/azure/groups/groups-list.tsx +++ b/src/app/dashboard/(active)/azure/groups/groups-list.tsx @@ -1,8 +1,8 @@ "use client" -import { ChevronDown, Info, LoaderCircle, Mail, UserMinus, UserPlus } from "lucide-react" import { useRouter } from "next/navigation" import { useMemo, useState } from "react" +import { FiChevronDown, FiInfo, FiLoader, FiMail, FiUserMinus, FiUserPlus } from "react-icons/fi" import { toast } from "sonner" import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert" import { Avatar, AvatarFallback, AvatarGroup, AvatarGroupCount } from "@/components/ui/avatar" @@ -63,7 +63,7 @@ export function GroupsList({ groups, directoryMembers }: { groups: AzureGroup[];
- + Looking for groups with 0-1 member(s)? Groups with max one member are collected in a collapsed section at the bottom of the page. @@ -86,7 +86,7 @@ export function GroupsList({ groups, directoryMembers }: { groups: AzureGroup[]; {multiMemberGroups.length} {singleMemberGroups.length === 1 ? "group" : "groups"} - + } /> @@ -116,7 +116,7 @@ export function GroupsList({ groups, directoryMembers }: { groups: AzureGroup[]; {singleMemberGroups.length} {singleMemberGroups.length === 1 ? "group" : "groups"} - + } /> @@ -148,7 +148,7 @@ function GroupRow({ group, directoryMembers }: { group: AzureGroup; directoryMem

{group.displayName}

{group.mailAddress && (
- + {group.mailAddress}
)} @@ -263,7 +263,7 @@ function AddMemberDialog({ group, directoryMembers }: { group: AzureGroup; direc /> } > - + Add member @@ -310,9 +310,9 @@ function AddMemberDialog({ group, directoryMembers }: { group: AzureGroup; direc /> @@ -381,7 +381,7 @@ function RemoveMemberDialog({ group, directoryMembers }: { group: AzureGroup; di /> } > - + Remove member @@ -430,9 +430,9 @@ function RemoveMemberDialog({ group, directoryMembers }: { group: AzureGroup; di /> diff --git a/src/app/dashboard/(active)/complete-profile.tsx b/src/app/dashboard/(active)/complete-profile.tsx index 89fc4ac..10c0eb4 100644 --- a/src/app/dashboard/(active)/complete-profile.tsx +++ b/src/app/dashboard/(active)/complete-profile.tsx @@ -1,7 +1,7 @@ "use client" -import { UserRoundPenIcon } from "lucide-react" import Link from "next/link" +import { FiEdit3 } from "react-icons/fi" import { Button } from "@/components/ui/button" import { useSession } from "@/lib/auth" @@ -13,7 +13,7 @@ export function CompleteProfile() { return ( !data.user.name && (
- +

Your profile is incomplete, please enter the missing information.

diff --git a/src/app/dashboard/(active)/page.tsx b/src/app/dashboard/(active)/page.tsx index a0cb34b..b22e159 100644 --- a/src/app/dashboard/(active)/page.tsx +++ b/src/app/dashboard/(active)/page.tsx @@ -1,4 +1,4 @@ -import { InfoIcon } from "lucide-react" +import { FiInfo } from "react-icons/fi" import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert" import { CompleteProfile } from "./complete-profile" @@ -7,7 +7,7 @@ export default function AdminHome() {
- + Page under construction Use the sidebar to access the sections diff --git a/src/app/dashboard/(active)/telegram/grants/delete-grant.tsx b/src/app/dashboard/(active)/telegram/grants/delete-grant.tsx index c12558b..2eb277b 100644 --- a/src/app/dashboard/(active)/telegram/grants/delete-grant.tsx +++ b/src/app/dashboard/(active)/telegram/grants/delete-grant.tsx @@ -1,8 +1,8 @@ "use client" -import { OctagonX } from "lucide-react" import { useRouter } from "next/navigation" import { useState } from "react" +import { FiAlertOctagon } from "react-icons/fi" import { toast } from "sonner" import { AlertDialog, @@ -58,7 +58,7 @@ export function DeleteGrant({ - + Interrupt } @@ -66,7 +66,7 @@ export function DeleteGrant({ - + Interrupt Grant Are you sure you want to interrupt the grant? diff --git a/src/app/dashboard/(active)/telegram/grants/new-grant.tsx b/src/app/dashboard/(active)/telegram/grants/new-grant.tsx index 3f839aa..7c709c1 100644 --- a/src/app/dashboard/(active)/telegram/grants/new-grant.tsx +++ b/src/app/dashboard/(active)/telegram/grants/new-grant.tsx @@ -1,9 +1,9 @@ "use client" import { format } from "date-fns" -import { ChevronDownIcon, Plus } from "lucide-react" import { useRouter } from "next/navigation" import { useCallback, useEffect, useState } from "react" +import { FiChevronDown, FiPlus } from "react-icons/fi" import { toast } from "sonner" import { Button } from "@/components/ui/button" import { Calendar } from "@/components/ui/calendar" @@ -99,7 +99,7 @@ export function NewGrant() { - New Grant + New Grant } /> @@ -184,7 +184,7 @@ function DatePicker({ onSelect }: { onSelect: (date: Date, startTime: number, du render={ } /> diff --git a/src/app/dashboard/(active)/telegram/groups/group-row.tsx b/src/app/dashboard/(active)/telegram/groups/group-row.tsx index bfb8006..e17328d 100644 --- a/src/app/dashboard/(active)/telegram/groups/group-row.tsx +++ b/src/app/dashboard/(active)/telegram/groups/group-row.tsx @@ -1,6 +1,6 @@ "use client" -import { Copy } from "lucide-react" import { useRouter } from "next/navigation" +import { FiCopy } from "react-icons/fi" import { toast } from "sonner" import { Badge } from "@/components/ui/badge" import { Button } from "@/components/ui/button" @@ -54,7 +54,7 @@ export function GroupRow({ row: r }: { row: TgGroup }) { } }} > - +
diff --git a/src/app/dashboard/(active)/telegram/groups/leave-chat.tsx b/src/app/dashboard/(active)/telegram/groups/leave-chat.tsx index 8a8a284..221564b 100644 --- a/src/app/dashboard/(active)/telegram/groups/leave-chat.tsx +++ b/src/app/dashboard/(active)/telegram/groups/leave-chat.tsx @@ -1,8 +1,8 @@ "use client" -import { OctagonX, Trash2 } from "lucide-react" import { useRouter } from "next/navigation" import { useState } from "react" +import { FiAlertOctagon, FiTrash2 } from "react-icons/fi" import { toast } from "sonner" import { Spinner } from "@/components/spinner" import { @@ -57,7 +57,7 @@ export function LeaveChat({ chatId }: { chatId: number }) { - + Leave } @@ -65,7 +65,7 @@ export function LeaveChat({ chatId }: { chatId: number }) { - + Leave chat diff --git a/src/app/dashboard/(active)/telegram/users/[id]/add-role.tsx b/src/app/dashboard/(active)/telegram/users/[id]/add-role.tsx index 361ddc1..c702ab1 100644 --- a/src/app/dashboard/(active)/telegram/users/[id]/add-role.tsx +++ b/src/app/dashboard/(active)/telegram/users/[id]/add-role.tsx @@ -1,8 +1,8 @@ "use client" import { USER_ROLE } from "@polinetwork/backend" -import { Plus } from "lucide-react" import { useRouter } from "next/navigation" import { useState } from "react" +import { FiPlus } from "react-icons/fi" import { toast } from "sonner" import { Spinner } from "@/components/spinner" import { Badge } from "@/components/ui/badge" @@ -89,7 +89,7 @@ export function AddRole({ - Add Role + Add Role } /> diff --git a/src/app/dashboard/(active)/telegram/users/[id]/card-message.tsx b/src/app/dashboard/(active)/telegram/users/[id]/card-message.tsx index 46603cc..4f60cda 100644 --- a/src/app/dashboard/(active)/telegram/users/[id]/card-message.tsx +++ b/src/app/dashboard/(active)/telegram/users/[id]/card-message.tsx @@ -1,4 +1,4 @@ -import { ExternalLinkIcon } from "lucide-react" +import { FiExternalLink } from "react-icons/fi" import { Button } from "@/components/ui/button" import { Card, CardContent, CardFooter } from "@/components/ui/card" import { stripChatId } from "@/lib/utils/telegram" @@ -30,7 +30,7 @@ export function MessageCard({ message: m }: { message: Message }) { {m.group?.inviteLink && ( )} @@ -41,7 +41,7 @@ export function MessageCard({ message: m }: { message: Message }) { aria-label="Open message in chat" > diff --git a/src/app/dashboard/(active)/telegram/users/[id]/card-user-grant.tsx b/src/app/dashboard/(active)/telegram/users/[id]/card-user-grant.tsx index 7dbeb37..8e8de0e 100644 --- a/src/app/dashboard/(active)/telegram/users/[id]/card-user-grant.tsx +++ b/src/app/dashboard/(active)/telegram/users/[id]/card-user-grant.tsx @@ -1,6 +1,6 @@ "use client" import { format } from "date-fns" -import { Sparkle } from "lucide-react" +import { FiZap } from "react-icons/fi" import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card" import type { TgGrant, TgUser } from "@/server/trpc/types" import { DeleteGrant } from "../../grants/delete-grant" @@ -18,7 +18,7 @@ export function UserGrantCard({ - Ongoing Grant + Ongoing Grant This user has an ongoing grant diff --git a/src/app/dashboard/(active)/telegram/users/[id]/card-user-info.tsx b/src/app/dashboard/(active)/telegram/users/[id]/card-user-info.tsx index 52741df..8a44e6b 100644 --- a/src/app/dashboard/(active)/telegram/users/[id]/card-user-info.tsx +++ b/src/app/dashboard/(active)/telegram/users/[id]/card-user-info.tsx @@ -1,5 +1,5 @@ "use client" -import { Star } from "lucide-react" +import { FiStar } from "react-icons/fi" import { Badge } from "@/components/ui/badge" import { Card, CardContent, CardFooter, CardHeader, CardTitle } from "@/components/ui/card" import { useSession } from "@/lib/auth" @@ -30,7 +30,7 @@ export function UserInfoCard({ # User ID: {user.id}{" "} {isSelf && ( - You + You )} diff --git a/src/app/dashboard/(active)/telegram/users/[id]/delete-group-admin.tsx b/src/app/dashboard/(active)/telegram/users/[id]/delete-group-admin.tsx index 25b0b36..cfcd50b 100644 --- a/src/app/dashboard/(active)/telegram/users/[id]/delete-group-admin.tsx +++ b/src/app/dashboard/(active)/telegram/users/[id]/delete-group-admin.tsx @@ -1,8 +1,8 @@ "use client" -import { Trash2, Trash2Icon } from "lucide-react" import { useRouter } from "next/navigation" import { useState } from "react" +import { FiTrash2 } from "react-icons/fi" import { toast } from "sonner" import { Spinner } from "@/components/spinner" import { @@ -63,7 +63,7 @@ export function DeleteGroupAdmin({ - + Delete } @@ -71,7 +71,7 @@ export function DeleteGroupAdmin({ - + Remove Group Admin Are you sure you want to remove the group admin? diff --git a/src/app/dashboard/(active)/telegram/users/[id]/new-group-admin.tsx b/src/app/dashboard/(active)/telegram/users/[id]/new-group-admin.tsx index 840e20d..fc7f5e5 100644 --- a/src/app/dashboard/(active)/telegram/users/[id]/new-group-admin.tsx +++ b/src/app/dashboard/(active)/telegram/users/[id]/new-group-admin.tsx @@ -1,7 +1,7 @@ "use client" -import { Plus, Search, X } from "lucide-react" import { useRouter } from "next/navigation" import { useState } from "react" +import { FiPlus, FiSearch, FiX } from "react-icons/fi" import { toast } from "sonner" import { Button } from "@/components/ui/button" import { @@ -84,7 +84,7 @@ export function NewGroupAdmin({ - New + New } /> @@ -119,12 +119,12 @@ export function NewGroupAdmin({ value={groupQuery} />
{groups.length > 0 && ( )} diff --git a/src/app/dashboard/(active)/telegram/users/[id]/page.tsx b/src/app/dashboard/(active)/telegram/users/[id]/page.tsx index bc83ede..ec6649e 100644 --- a/src/app/dashboard/(active)/telegram/users/[id]/page.tsx +++ b/src/app/dashboard/(active)/telegram/users/[id]/page.tsx @@ -10,8 +10,8 @@ import { NewGroupAdmin } from "./new-group-admin" export default async function TgUserDetails({ params }: { params: Promise<{ id: string }> }) { const { id } = await params - const parsedInt = parseInt(id, 10) - if (isNaN(parsedInt)) notFound() + const parsedInt = Number(id) + if (!Number.isInteger(parsedInt) || !Number.isSafeInteger(parsedInt)) notFound() const data = await getUserDetails(parsedInt) if (!data) notFound() diff --git a/src/app/dashboard/(active)/telegram/users/[id]/remove-role.tsx b/src/app/dashboard/(active)/telegram/users/[id]/remove-role.tsx index 82ddde0..261a6b4 100644 --- a/src/app/dashboard/(active)/telegram/users/[id]/remove-role.tsx +++ b/src/app/dashboard/(active)/telegram/users/[id]/remove-role.tsx @@ -1,8 +1,8 @@ "use client" import { USER_ROLE } from "@polinetwork/backend" -import { Minus } from "lucide-react" import { useRouter } from "next/navigation" import { useState } from "react" +import { FiMinus } from "react-icons/fi" import { toast } from "sonner" import { Spinner } from "@/components/spinner" import { Badge } from "@/components/ui/badge" @@ -93,7 +93,7 @@ export function RemoveRole({ - Remove Role + Remove Role } /> diff --git a/src/app/dashboard/(active)/telegram/users/page.tsx b/src/app/dashboard/(active)/telegram/users/page.tsx index 5a52f6d..79d7a71 100644 --- a/src/app/dashboard/(active)/telegram/users/page.tsx +++ b/src/app/dashboard/(active)/telegram/users/page.tsx @@ -1,5 +1,5 @@ -import { Eye } from "lucide-react" import Link from "next/link" +import { FiEye } from "react-icons/fi" import { SearchInput } from "@/components/search-input" import { Button } from "@/components/ui/button" import { trpc } from "@/server/trpc" @@ -47,7 +47,7 @@ function UserRow({ row: r }: { row: Users[number] }) {
diff --git a/src/app/dashboard/(active)/web/guide/create-guide.tsx b/src/app/dashboard/(active)/web/guide/create-guide.tsx index 6799ad0..5845298 100644 --- a/src/app/dashboard/(active)/web/guide/create-guide.tsx +++ b/src/app/dashboard/(active)/web/guide/create-guide.tsx @@ -1,8 +1,8 @@ "use client" import { format } from "date-fns" -import { ChevronDownIcon, Plus, Upload } from "lucide-react" import { useState } from "react" +import { FiChevronDown, FiPlus, FiUpload } from "react-icons/fi" import { toast } from "sonner" import { Button } from "@/components/ui/button" import { Calendar } from "@/components/ui/calendar" @@ -84,7 +84,7 @@ export function CreateGuide({ - Add Guide + Add Guide } /> @@ -116,7 +116,7 @@ export function CreateGuide({ render={ } /> @@ -142,7 +142,7 @@ export function CreateGuide({ htmlFor="file" className="flex h-8 w-full cursor-pointer items-center gap-2 rounded-lg border border-input bg-transparent px-2.5 text-sm transition-colors hover:bg-accent/50" > - + {file ? file.name : "Choose a PDF file..."} diff --git a/src/app/dashboard/(active)/web/guide/delete-guide.tsx b/src/app/dashboard/(active)/web/guide/delete-guide.tsx index 9d88482..9597629 100644 --- a/src/app/dashboard/(active)/web/guide/delete-guide.tsx +++ b/src/app/dashboard/(active)/web/guide/delete-guide.tsx @@ -1,7 +1,7 @@ "use client" -import { OctagonX, Trash } from "lucide-react" import { useState } from "react" +import { FiAlertOctagon, FiTrash } from "react-icons/fi" import { toast } from "sonner" import { AlertDialog, @@ -52,14 +52,14 @@ export function DeleteGuide({ - + } /> - + Delete Guide diff --git a/src/components/dashboard-sidebar/data.tsx b/src/components/dashboard-sidebar/data.tsx index a50c731..0fa52ae 100644 --- a/src/components/dashboard-sidebar/data.tsx +++ b/src/components/dashboard-sidebar/data.tsx @@ -1,5 +1,5 @@ -import { BookOpen, Globe, MessageCircleMoreIcon, Sparkle, Users, UsersRound } from "lucide-react" import Image from "next/image" +import { FiBookOpen, FiGlobe, FiMessageSquare, FiUsers, FiZap } from "react-icons/fi" import azureSvg from "@/assets/svg/azure.svg" import telegramSvg from "@/assets/svg/telegram.svg" @@ -9,23 +9,23 @@ export const DSData = { title: "Telegram", icon: telegram logo, items: [ - { title: "Grants", url: "/dashboard/telegram/grants", icon: }, - { title: "Groups", url: "/dashboard/telegram/groups", icon: }, - { title: "Users", url: "/dashboard/telegram/users", icon: }, + { title: "Grants", url: "/dashboard/telegram/grants", icon: }, + { title: "Groups", url: "/dashboard/telegram/groups", icon: }, + { title: "Users", url: "/dashboard/telegram/users", icon: }, ], }, { title: "Azure", icon: azure logo, items: [ - { title: "Groups", url: "/dashboard/azure/groups", icon: }, - { title: "Members", url: "/dashboard/azure/members", icon: }, + { title: "Groups", url: "/dashboard/azure/groups", icon: }, + { title: "Members", url: "/dashboard/azure/members", icon: }, ], }, { title: "Web", - icon: , - items: [{ title: "Guide", url: "/dashboard/web/guide", icon: }], + icon: , + items: [{ title: "Guide", url: "/dashboard/web/guide", icon: }], }, ], } diff --git a/src/components/dashboard-sidebar/main-nav.tsx b/src/components/dashboard-sidebar/main-nav.tsx index 7b7acf5..b61f719 100644 --- a/src/components/dashboard-sidebar/main-nav.tsx +++ b/src/components/dashboard-sidebar/main-nav.tsx @@ -1,8 +1,8 @@ "use client" -import { ChevronRight } from "lucide-react" import Link from "next/link" import { usePathname } from "next/navigation" import { useState } from "react" +import { FiChevronRight } from "react-icons/fi" import { COOKIES } from "@/constants" import { useCookieStorage } from "@/hooks/use-cookie-storage" import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "../ui/collapsible" @@ -67,7 +67,7 @@ function DSMenuCategory({ {category.icon} {category.title} - + } /> diff --git a/src/components/dashboard-sidebar/user-nav.tsx b/src/components/dashboard-sidebar/user-nav.tsx index 40ceabe..ca07cdc 100644 --- a/src/components/dashboard-sidebar/user-nav.tsx +++ b/src/components/dashboard-sidebar/user-nav.tsx @@ -1,8 +1,8 @@ "use client" -import { Bell, ChevronsUpDown, LogOut, UserIcon } from "lucide-react" import Link from "next/link" import { useRouter } from "next/navigation" +import { FiBell, FiChevronsDown, FiLogOut, FiUser } from "react-icons/fi" import { toast } from "sonner" import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar" import { @@ -40,13 +40,13 @@ export function DSUserNav() { > - {user.name ? getInitials(user.name) : } + {user.name ? getInitials(user.name) : }
{user.name} {user.email}
- + } /> @@ -61,7 +61,7 @@ export function DSUserNav() {
- {user.name ? getInitials(user.name) : } + {user.name ? getInitials(user.name) : }
{user.name} @@ -74,12 +74,12 @@ export function DSUserNav() { - + Account - + Notifications @@ -97,7 +97,7 @@ export function DSUserNav() { }) } > - + Log out diff --git a/src/components/header-login-button.tsx b/src/components/header-login-button.tsx index ed3dd14..62057da 100644 --- a/src/components/header-login-button.tsx +++ b/src/components/header-login-button.tsx @@ -1,7 +1,7 @@ "use client" -import { LogIn, LogOut } from "lucide-react" import Link from "next/link" import { usePathname, useRouter } from "next/navigation" +import { FiLogIn, FiLogOut } from "react-icons/fi" import { useIsMobile } from "@/hooks/use-mobile" import { auth, useSession } from "@/lib/auth" import { Button } from "./ui/button" @@ -24,7 +24,7 @@ export function HeaderLoginButton() { router.refresh() }} > - Logout + Logout ) @@ -36,7 +36,7 @@ export function HeaderLoginButton() { className="rounded-lg" size={isMobile ? "icon" : "default"} > - + Login diff --git a/src/components/header.tsx b/src/components/header.tsx index 55c341e..d007f74 100644 --- a/src/components/header.tsx +++ b/src/components/header.tsx @@ -1,5 +1,5 @@ -import { GlobeIcon } from "lucide-react" import Link from "next/link" +import { FiGlobe } from "react-icons/fi" import { ThemeButton } from "@/components/theme-button" import { HeaderLoginButton } from "./header-login-button" import { Logo } from "./logo" @@ -22,7 +22,7 @@ export async function Header() { diff --git a/src/components/logout-button.tsx b/src/components/logout-button.tsx index 1a6a958..de99534 100644 --- a/src/components/logout-button.tsx +++ b/src/components/logout-button.tsx @@ -1,5 +1,5 @@ -import { LogOut } from "lucide-react" import { redirect } from "next/navigation" +import { FiLogOut } from "react-icons/fi" import { Button } from "@/components/ui/button" import { signOut } from "@/lib/auth" @@ -13,7 +13,7 @@ export function LogoutButton() { variant="destructive" type="submit" > - + Logout ) diff --git a/src/components/navigate-back.tsx b/src/components/navigate-back.tsx index 463f442..febb551 100644 --- a/src/components/navigate-back.tsx +++ b/src/components/navigate-back.tsx @@ -1,7 +1,7 @@ "use client" -import { ArrowLeft } from "lucide-react" import { useRouter } from "next/navigation" +import { FiArrowLeft } from "react-icons/fi" import { Button } from "./ui/button" export function NavigateBack() { @@ -15,7 +15,7 @@ export function NavigateBack() { router.back() }} > - + ) } diff --git a/src/components/search-input.tsx b/src/components/search-input.tsx index e0e5a9e..43b9009 100644 --- a/src/components/search-input.tsx +++ b/src/components/search-input.tsx @@ -1,8 +1,8 @@ "use client" -import { RefreshCcw, Search } from "lucide-react" import { useRouter, useSearchParams } from "next/navigation" import { useEffect, useState } from "react" +import { FiRefreshCcw, FiSearch } from "react-icons/fi" import { Button } from "@/components/ui/button" import { Input } from "@/components/ui/input" @@ -35,11 +35,11 @@ export function SearchInput({ disabled }: { disabled?: boolean }) { placeholder="Search..." />
diff --git a/src/components/theme-button.tsx b/src/components/theme-button.tsx index cbaa0ad..2ddc817 100644 --- a/src/components/theme-button.tsx +++ b/src/components/theme-button.tsx @@ -1,6 +1,6 @@ "use client" -import { MoonIcon, SunIcon } from "lucide-react" import { useTheme } from "next-themes" +import { FiMoon, FiSun } from "react-icons/fi" import { Button } from "./ui/button" export function ThemeButton() { @@ -9,8 +9,8 @@ export function ThemeButton() { // TODO: remove disabled when light theme is ready return ( ) } diff --git a/src/components/ui/breadcrumb.tsx b/src/components/ui/breadcrumb.tsx index e0deed4..28b736e 100644 --- a/src/components/ui/breadcrumb.tsx +++ b/src/components/ui/breadcrumb.tsx @@ -3,7 +3,7 @@ import { mergeProps } from "@base-ui/react/merge-props" import { useRender } from "@base-ui/react/use-render" import { cn } from "@/lib/utils/shadcn" -import { ChevronRightIcon, MoreHorizontalIcon } from "lucide-react" +import { FiChevronRight, FiMoreHorizontal } from "react-icons/fi" function Breadcrumb({ className, ...props }: React.ComponentProps<"nav">) { return ( @@ -86,7 +86,7 @@ function BreadcrumbSeparator({ {...props} > {children ?? ( - + )} ) @@ -107,8 +107,7 @@ function BreadcrumbEllipsis({ )} {...props} > - + More ) diff --git a/src/components/ui/calendar.tsx b/src/components/ui/calendar.tsx index 686626b..a39b65e 100644 --- a/src/components/ui/calendar.tsx +++ b/src/components/ui/calendar.tsx @@ -10,7 +10,7 @@ import { import { cn } from "@/lib/utils/shadcn" import { Button, buttonVariants } from "@/components/ui/button" -import { ChevronLeftIcon, ChevronRightIcon, ChevronDownIcon } from "lucide-react" +import { FiChevronLeft, FiChevronRight, FiChevronDown } from "react-icons/fi" function Calendar({ className, @@ -147,18 +147,18 @@ function Calendar({ Chevron: ({ className, orientation, ...props }) => { if (orientation === "left") { return ( - + ) } if (orientation === "right") { return ( - + ) } return ( - + ) }, DayButton: ({ ...props }) => ( diff --git a/src/components/ui/command.tsx b/src/components/ui/command.tsx index b57a702..7b8b0ef 100644 --- a/src/components/ui/command.tsx +++ b/src/components/ui/command.tsx @@ -15,7 +15,7 @@ import { InputGroup, InputGroupAddon, } from "@/components/ui/input-group" -import { SearchIcon, CheckIcon } from "lucide-react" +import { FiSearch, FiCheck } from "react-icons/fi" function Command({ className, @@ -82,7 +82,7 @@ function CommandInput({ {...props} /> - +
@@ -162,7 +162,7 @@ function CommandItem({ {...props} > {children} - + ) } diff --git a/src/components/ui/dialog.tsx b/src/components/ui/dialog.tsx index 9bb1f25..c3f389e 100644 --- a/src/components/ui/dialog.tsx +++ b/src/components/ui/dialog.tsx @@ -5,7 +5,7 @@ import { Dialog as DialogPrimitive } from "@base-ui/react/dialog" import { cn } from "@/lib/utils/shadcn" import { Button } from "@/components/ui/button" -import { XIcon } from "lucide-react" +import { FiX } from "react-icons/fi" function Dialog({ ...props }: DialogPrimitive.Root.Props) { return @@ -61,7 +61,6 @@ function DialogContent({ {children} {showCloseButton && ( } > - + Close )} diff --git a/src/components/ui/dropdown-menu.tsx b/src/components/ui/dropdown-menu.tsx index d1c45d7..385ff9f 100644 --- a/src/components/ui/dropdown-menu.tsx +++ b/src/components/ui/dropdown-menu.tsx @@ -4,7 +4,7 @@ import * as React from "react" import { Menu as MenuPrimitive } from "@base-ui/react/menu" import { cn } from "@/lib/utils/shadcn" -import { ChevronRightIcon, CheckIcon } from "lucide-react" +import { FiChevronRight, FiCheck } from "react-icons/fi" function DropdownMenu({ ...props }: MenuPrimitive.Root.Props) { return @@ -119,7 +119,7 @@ function DropdownMenuSubTrigger({ {...props} > {children} - + ) } @@ -170,8 +170,7 @@ function DropdownMenuCheckboxItem({ data-slot="dropdown-menu-checkbox-item-indicator" > - + {children} @@ -211,8 +210,7 @@ function DropdownMenuRadioItem({ data-slot="dropdown-menu-radio-item-indicator" > - + {children} diff --git a/src/components/ui/input-otp.tsx b/src/components/ui/input-otp.tsx index dcbc966..baca16a 100644 --- a/src/components/ui/input-otp.tsx +++ b/src/components/ui/input-otp.tsx @@ -4,7 +4,7 @@ import * as React from "react" import { OTPInput, OTPInputContext } from "input-otp" import { cn } from "@/lib/utils/shadcn" -import { MinusIcon } from "lucide-react" +import { FiMinus } from "react-icons/fi" function InputOTP({ className, @@ -78,8 +78,7 @@ function InputOTPSeparator({ ...props }: React.ComponentProps<"div">) { role="separator" {...props} > - +
) } diff --git a/src/components/ui/select.tsx b/src/components/ui/select.tsx index bef549b..efd2cb8 100644 --- a/src/components/ui/select.tsx +++ b/src/components/ui/select.tsx @@ -4,7 +4,7 @@ import * as React from "react" import { Select as SelectPrimitive } from "@base-ui/react/select" import { cn } from "@/lib/utils/shadcn" -import { ChevronDownIcon, CheckIcon, ChevronUpIcon } from "lucide-react" +import { FiChevronDown, FiCheck, FiChevronUp } from "react-icons/fi" const Select = SelectPrimitive.Root @@ -49,7 +49,7 @@ function SelectTrigger({ {children} + } /> @@ -130,7 +130,7 @@ function SelectItem({ } > - + ) @@ -162,8 +162,7 @@ function SelectScrollUpButton({ )} {...props} > - + ) } @@ -181,8 +180,7 @@ function SelectScrollDownButton({ )} {...props} > - + ) } diff --git a/src/components/ui/sheet.tsx b/src/components/ui/sheet.tsx index 308776c..a3bf29e 100644 --- a/src/components/ui/sheet.tsx +++ b/src/components/ui/sheet.tsx @@ -5,7 +5,7 @@ import { Dialog as SheetPrimitive } from "@base-ui/react/dialog" import { cn } from "@/lib/utils/shadcn" import { Button } from "@/components/ui/button" -import { XIcon } from "lucide-react" +import { FiX } from "react-icons/fi" function Sheet({ ...props }: SheetPrimitive.Root.Props) { return @@ -70,8 +70,7 @@ function SheetContent({ /> } > - + Close )} diff --git a/src/components/ui/sidebar.tsx b/src/components/ui/sidebar.tsx index 3205f8a..a984eb5 100644 --- a/src/components/ui/sidebar.tsx +++ b/src/components/ui/sidebar.tsx @@ -23,7 +23,7 @@ import { TooltipContent, TooltipTrigger, } from "@/components/ui/tooltip" -import { PanelLeftIcon } from "lucide-react" +import { FiSidebar } from "react-icons/fi" import { useCookieStorage } from "@/hooks/use-cookie-storage" import { COOKIES } from "@/constants" @@ -275,7 +275,7 @@ function SidebarTrigger({ }} {...props} > - + Toggle Sidebar ) diff --git a/src/components/ui/sonner.tsx b/src/components/ui/sonner.tsx index 9280ee5..ddee39b 100644 --- a/src/components/ui/sonner.tsx +++ b/src/components/ui/sonner.tsx @@ -2,7 +2,7 @@ import { useTheme } from "next-themes" import { Toaster as Sonner, type ToasterProps } from "sonner" -import { CircleCheckIcon, InfoIcon, TriangleAlertIcon, OctagonXIcon, Loader2Icon } from "lucide-react" +import { FiCheckCircle, FiInfo, FiAlertTriangle, FiAlertOctagon, FiLoader } from "react-icons/fi" const Toaster = ({ ...props }: ToasterProps) => { const { theme = "system" } = useTheme() @@ -13,19 +13,19 @@ const Toaster = ({ ...props }: ToasterProps) => { className="toaster group" icons={{ success: ( - + ), info: ( - + ), warning: ( - + ), error: ( - + ), loading: ( - + ), }} style={ diff --git a/src/components/user-select.tsx b/src/components/user-select.tsx index 68b2a14..bcb03bd 100644 --- a/src/components/user-select.tsx +++ b/src/components/user-select.tsx @@ -1,7 +1,7 @@ "use client" -import { Search, X } from "lucide-react" import { useState } from "react" +import { FiSearch, FiX } from "react-icons/fi" import { toast } from "sonner" import { fmtUser } from "@/lib/utils/telegram" import { getUserInfo, searchUserInfo } from "@/server/actions/users" @@ -98,11 +98,11 @@ export function UserSelect({ onUser, onReset }: Props) { {user ? ( ) : ( )} From d5fb641e960f5ead3a337f593286d33aafcab218 Mon Sep 17 00:00:00 2001 From: Lorenzo Corallo <66379281+lorenzocorallo@users.noreply.github.com> Date: Tue, 11 Aug 2026 18:39:55 +0200 Subject: [PATCH 07/10] ci: publish arm64 image (#55) * ci: publish multi-arch container images * ci: build admin on native architecture runners * ci: publish images only after main updates * ci: serialize container publication --- .github/workflows/docker.yml | 59 ++++++++++++++++++++++++++++-------- 1 file changed, 46 insertions(+), 13 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index b1c7c89..b109860 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -1,32 +1,65 @@ name: Docker Image CI on: - workflow_dispatch: - workflow_run: - workflows: [Test] + push: branches: [main] - types: - - completed + +concurrency: + group: docker-publish-${{ github.ref }} + cancel-in-progress: true jobs: build: - name: Build - if: ${{ github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success' }} - runs-on: ubuntu-latest + name: Build ${{ matrix.platform }} + permissions: + contents: read + packages: write + strategy: + fail-fast: false + matrix: + include: + - platform: linux/amd64 + runner: ubuntu-latest + suffix: amd64 + - platform: linux/arm64 + runner: ubuntu-24.04-arm + suffix: arm64 + runs-on: ${{ matrix.runner }} steps: - uses: actions/checkout@v4 - - uses: docker/setup-qemu-action@v3 - uses: docker/setup-buildx-action@v3 - - uses: docker/login-action@v2 + - uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Build the Docker image - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6 with: context: . - platforms: linux/amd64 + platforms: ${{ matrix.platform }} push: true - tags: ghcr.io/polinetworkorg/admin:latest + tags: ghcr.io/polinetworkorg/admin:build-${{ github.sha }}-${{ matrix.suffix }} + + manifest: + name: Publish multi-arch manifest + needs: build + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + steps: + - uses: docker/setup-buildx-action@v3 + - uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Publish latest manifest + run: | + docker buildx imagetools create \ + --tag ghcr.io/polinetworkorg/admin:latest \ + ghcr.io/polinetworkorg/admin:build-${{ github.sha }}-amd64 \ + ghcr.io/polinetworkorg/admin:build-${{ github.sha }}-arm64 + docker buildx imagetools inspect ghcr.io/polinetworkorg/admin:latest From 5f3c8238e774037faaedefb800bbea426e9e62b5 Mon Sep 17 00:00:00 2001 From: Lorenzo Corallo Date: Tue, 18 Aug 2026 21:28:21 +0200 Subject: [PATCH 08/10] refactor: migrate admin dashboard to TanStack Start Replace the Next.js application with the audited TanStack Start rewrite. Preserve the dashboard workflows and stacked UI work while fixing authorization, request isolation, auth proxying, production safeguards, validation, and feature colocation. --- .dockerignore | 3 +- .env.example | 4 +- .gitignore | 10 +- AGENTS.md | 33 + CLAUDE.md | 1 + Dockerfile | 57 +- README.md | 30 +- biome.jsonc | 24 +- components.json | 17 +- next-env.d.ts | 6 - next.config.ts | 30 - package.json | 75 +- pnpm-lock.yaml | 4935 ++++++++--------- postcss.config.js | 5 - src/app/(auth)/layout.tsx | 15 - src/app/(auth)/login/can-i-access.tsx | 77 - src/app/(auth)/login/login-button.tsx | 18 - src/app/(auth)/login/login-form.tsx | 196 - src/app/(auth)/login/page.tsx | 25 - src/app/(auth)/login/what-is.tsx | 55 - src/app/(auth)/onboarding/_layout.tsx | 7 - src/app/(auth)/onboarding/link/logout.tsx | 32 - src/app/(auth)/onboarding/link/page.tsx | 38 - src/app/(auth)/onboarding/link/telegram.tsx | 225 - src/app/(auth)/onboarding/no-role/page.tsx | 38 - .../(active)/account/delete-passkey.tsx | 51 - .../dashboard/(active)/account/loading.tsx | 34 - src/app/dashboard/(active)/account/page.tsx | 67 - .../(active)/account/passkey-button.tsx | 35 - .../(active)/account/profile-pic.tsx | 108 - .../dashboard/(active)/account/set-name.tsx | 64 - .../dashboard/(active)/account/telegram.tsx | 17 - .../(active)/azure/groups/groups-list.tsx | 443 -- .../(active)/azure/groups/loading.tsx | 44 - .../dashboard/(active)/azure/groups/page.tsx | 17 - .../(active)/azure/members/columns.tsx | 50 - .../azure/members/create-assoc-member.tsx | 140 - .../(active)/azure/members/loading.tsx | 9 - .../dashboard/(active)/azure/members/page.tsx | 19 - .../azure/members/set-assoc-number-dialog.tsx | 97 - .../(active)/azure/members/table.tsx | 72 - src/app/dashboard/(active)/breadcrumb.tsx | 74 - .../dashboard/(active)/complete-profile.tsx | 24 - src/app/dashboard/(active)/layout.tsx | 50 - src/app/dashboard/(active)/not-found.tsx | 19 - src/app/dashboard/(active)/page.tsx | 16 - .../(active)/telegram/grants/delete-grant.tsx | 83 - .../(active)/telegram/grants/grant-list.tsx | 42 - .../(active)/telegram/grants/loading.tsx | 51 - .../(active)/telegram/grants/new-grant.tsx | 254 - .../(active)/telegram/grants/page.tsx | 37 - .../(active)/telegram/groups/group-row.tsx | 76 - .../(active)/telegram/groups/leave-chat.tsx | 84 - .../(active)/telegram/groups/loading.tsx | 26 - .../(active)/telegram/groups/page.tsx | 34 - .../(active)/telegram/users/[id]/add-role.tsx | 148 - .../telegram/users/[id]/card-audit-log.tsx | 40 - .../telegram/users/[id]/card-group-admin.tsx | 39 - .../telegram/users/[id]/card-message.tsx | 50 - .../telegram/users/[id]/card-user-grant.tsx | 34 - .../telegram/users/[id]/card-user-info.tsx | 58 - .../users/[id]/delete-group-admin.tsx | 88 - .../(active)/telegram/users/[id]/loading.tsx | 37 - .../telegram/users/[id]/new-group-admin.tsx | 163 - .../(active)/telegram/users/[id]/page.tsx | 83 - .../telegram/users/[id]/remove-role.tsx | 152 - .../(active)/telegram/users/loading.tsx | 25 - .../(active)/telegram/users/page.tsx | 56 - .../dashboard/(active)/web/guide/columns.tsx | 35 - .../(active)/web/guide/create-guide.tsx | 169 - .../(active)/web/guide/delete-guide.tsx | 79 - src/app/dashboard/(active)/web/guide/page.tsx | 12 - .../dashboard/(active)/web/guide/table.tsx | 39 - src/app/dashboard/(active)/web/guide/types.ts | 6 - src/app/dashboard/disabled/page.tsx | 44 - src/app/dashboard/inactive/logout.tsx | 0 src/app/dashboard/inactive/page.tsx | 53 - src/app/dashboard/layout.tsx | 24 - src/app/layout.tsx | 53 - src/app/page.tsx | 20 - src/app/testtrpc/page.tsx | 19 - src/assets/logo.svg | 9 - src/assets/svg/account_disabled.svg | 52 - src/assets/svg/account_inactive.svg | 1 - src/assets/svg/login-1.svg | 1 - src/assets/svg/login-2.svg | 1 - src/assets/svg/login-3.svg | 1 - src/assets/svg/logo.svg | 1 - src/assets/svg/shapes/big-blue.svg | 1 - src/assets/svg/shapes/big-teal.svg | 1 - src/assets/svg/shapes/looper.svg | 1 - src/assets/svg/shapes/small-blue.svg | 1 - src/components/app-mark.tsx | 44 + src/components/code.tsx | 77 - src/components/dashboard-breadcrumb.tsx | 78 + src/components/dashboard-frame.tsx | 61 + src/components/dashboard-navigation.ts | 84 + src/components/dashboard-sidebar.tsx | 264 + src/components/dashboard-sidebar/data.tsx | 49 - src/components/dashboard-sidebar/index.tsx | 45 - src/components/dashboard-sidebar/main-nav.tsx | 103 - src/components/dashboard-sidebar/user-nav.tsx | 108 - src/components/data-table.tsx | 64 - src/components/data-toolbar.tsx | 86 + src/components/empty-state.tsx | 28 + src/components/header-login-button.tsx | 44 - src/components/header.tsx | 31 - src/components/input-prefix.tsx | 24 - src/components/loading-skeleton.tsx | 93 + src/components/logo.tsx | 6 - src/components/logout-button.tsx | 20 - src/components/navigate-back.tsx | 21 - src/components/page-header.tsx | 26 + src/components/pagination.tsx | 131 + src/components/reui/stepper.tsx | 421 ++ src/components/route-error.tsx | 49 + src/components/search-input.tsx | 47 - src/components/shapes.tsx | 32 - src/components/spinner.tsx | 26 - .../telegram/create-grant-dialog.tsx | 462 ++ .../telegram/grant-date-time-fields.tsx | 373 ++ src/components/theme-button.tsx | 16 - src/components/theme-provider.tsx | 8 - src/components/theme-toggle.tsx | 41 + src/components/ui/alert-dialog.tsx | 56 +- src/components/ui/alert.tsx | 35 +- src/components/ui/avatar.tsx | 30 +- src/components/ui/badge.tsx | 13 +- src/components/ui/breadcrumb.tsx | 59 +- src/components/ui/button.tsx | 35 +- src/components/ui/calendar.tsx | 93 +- src/components/ui/card.tsx | 55 +- src/components/ui/collapsible.tsx | 10 +- src/components/ui/combobox.tsx | 111 + src/components/ui/command.tsx | 81 +- src/components/ui/dialog.tsx | 59 +- src/components/ui/dropdown-menu.tsx | 55 +- src/components/ui/empty.tsx | 87 + src/components/ui/field.tsx | 222 +- src/components/ui/form.tsx | 179 - src/components/ui/input-group.tsx | 72 +- src/components/ui/input-otp.tsx | 86 - src/components/ui/input.tsx | 17 +- src/components/ui/label.tsx | 10 +- src/components/ui/pagination.tsx | 92 + src/components/ui/popover.tsx | 41 +- src/components/ui/progress.tsx | 80 - src/components/ui/select.tsx | 199 - src/components/ui/separator.tsx | 10 +- src/components/ui/sheet.tsx | 58 +- src/components/ui/sidebar.tsx | 109 +- src/components/ui/skeleton.tsx | 10 +- src/components/ui/sonner.tsx | 44 +- src/components/ui/table.tsx | 77 +- src/components/ui/tabs.tsx | 82 - src/components/ui/textarea.tsx | 4 +- src/components/ui/toggle-group.tsx | 17 +- src/components/ui/toggle.tsx | 17 +- src/components/ui/tooltip.tsx | 23 +- src/components/ui/wheel-picker.tsx | 678 +++ src/components/user-select.tsx | 112 - src/constants.ts | 4 - src/env.ts | 48 +- src/features/account/account-page.tsx | 85 + src/features/account/account.functions.ts | 15 + src/features/account/account.validation.ts | 7 + src/features/account/confirmation-dialog.tsx | 52 + src/features/account/profile-sections.tsx | 179 + src/features/account/security-sections.tsx | 211 + src/features/account/types.ts | 16 + src/features/account/use-account.ts | 208 + src/features/auth/auth.functions.ts | 21 + src/features/auth/login-page.tsx | 191 + src/features/azure/azure.functions.ts | 58 + src/features/azure/group-membership.tsx | 275 + src/features/azure/groups-page.tsx | 190 + src/features/azure/member-dialog.tsx | 162 + src/features/azure/members-page.tsx | 282 + src/features/dashboard/overview-page.tsx | 119 + src/features/guides/guide-dialogs.tsx | 251 + src/features/guides/guides-page.tsx | 145 + src/features/guides/guides.functions.ts | 32 + src/features/guides/guides.validation.ts | 13 + src/features/guides/types.ts | 3 + .../onboarding/telegram-link-page.tsx | 131 + src/features/onboarding/use-telegram-link.ts | 231 + src/features/telegram/grants-page.tsx | 253 + src/features/telegram/grants.functions.ts | 44 + src/features/telegram/groups-page.tsx | 275 + src/features/telegram/groups.functions.ts | 23 + src/features/telegram/leave-group-dialog.tsx | 74 + .../telegram/user-detail/grant-dialogs.tsx | 83 + .../user-detail/group-admin-dialog.tsx | 206 + src/features/telegram/user-detail/profile.tsx | 283 + .../telegram/user-detail/role-dialog.tsx | 178 + .../telegram/user-detail/sections.tsx | 88 + src/features/telegram/user-detail/types.ts | 13 + src/features/telegram/users-page.tsx | 166 + src/features/telegram/users.functions.ts | 112 + src/hooks/use-cookie-storage.tsx | 49 - src/hooks/use-local-storage.tsx | 31 - src/hooks/use-mobile.tsx | 19 - src/hooks/use-session-storage.tsx | 39 - src/index.css | 181 - .../trpc/types.tsx => lib/api/types.ts} | 2 +- src/lib/auth-plugins.ts | 11 + src/lib/auth.ts | 22 +- src/lib/table.ts | 31 + src/lib/{utils/shadcn.ts => utils.ts} | 0 src/lib/utils/index.ts | 17 - src/lib/utils/telegram.ts | 18 - src/middleware.ts | 14 - src/routeTree.gen.ts | 376 ++ src/router.tsx | 17 + src/routes/__root.tsx | 40 + src/routes/api/auth/$.ts | 14 + src/routes/dashboard.tsx | 21 + src/routes/dashboard/account.tsx | 11 + src/routes/dashboard/azure/groups.tsx | 15 + src/routes/dashboard/azure/members.tsx | 15 + src/routes/dashboard/index.tsx | 4 + src/routes/dashboard/telegram/grants.tsx | 15 + src/routes/dashboard/telegram/groups.tsx | 15 + .../dashboard/telegram/users/$userId.tsx | 25 + src/routes/dashboard/telegram/users/index.tsx | 14 + src/routes/dashboard/web/guides.tsx | 14 + src/routes/index.tsx | 7 + src/routes/login.tsx | 11 + src/routes/onboarding/link.tsx | 19 + src/routes/onboarding/unauthorized.tsx | 74 + src/server/actions/azure.ts | 43 - src/server/actions/grants.ts | 27 - src/server/actions/groups.ts | 22 - src/server/actions/guides.ts | 27 - src/server/actions/test.ts | 6 - src/server/actions/users.ts | 77 - src/server/auth-proxy-core.ts | 14 + src/server/auth-proxy.server.ts | 13 + src/server/auth.middleware.ts | 66 + src/server/auth.server.ts | 82 + src/server/auth/index.ts | 23 - src/server/authorization.ts | 10 + src/server/backend.server.ts | 29 + src/server/request-headers.ts | 4 + src/server/runtime-env.ts | 13 + src/server/trpc/index.tsx | 28 - src/styles.css | 315 ++ src/utils/cookies.ts | 56 - src/vite-env.d.ts | 1 + tailwind.config.ts | 5 + tests/server-security.test.mjs | 160 + tsconfig.json | 49 +- tsr.config.json | 3 + vite.config.ts | 11 + 254 files changed, 12076 insertions(+), 10545 deletions(-) create mode 100644 AGENTS.md create mode 120000 CLAUDE.md delete mode 100644 next-env.d.ts delete mode 100644 next.config.ts delete mode 100644 postcss.config.js delete mode 100644 src/app/(auth)/layout.tsx delete mode 100644 src/app/(auth)/login/can-i-access.tsx delete mode 100644 src/app/(auth)/login/login-button.tsx delete mode 100644 src/app/(auth)/login/login-form.tsx delete mode 100644 src/app/(auth)/login/page.tsx delete mode 100644 src/app/(auth)/login/what-is.tsx delete mode 100644 src/app/(auth)/onboarding/_layout.tsx delete mode 100644 src/app/(auth)/onboarding/link/logout.tsx delete mode 100644 src/app/(auth)/onboarding/link/page.tsx delete mode 100644 src/app/(auth)/onboarding/link/telegram.tsx delete mode 100644 src/app/(auth)/onboarding/no-role/page.tsx delete mode 100644 src/app/dashboard/(active)/account/delete-passkey.tsx delete mode 100644 src/app/dashboard/(active)/account/loading.tsx delete mode 100644 src/app/dashboard/(active)/account/page.tsx delete mode 100644 src/app/dashboard/(active)/account/passkey-button.tsx delete mode 100644 src/app/dashboard/(active)/account/profile-pic.tsx delete mode 100644 src/app/dashboard/(active)/account/set-name.tsx delete mode 100644 src/app/dashboard/(active)/account/telegram.tsx delete mode 100644 src/app/dashboard/(active)/azure/groups/groups-list.tsx delete mode 100644 src/app/dashboard/(active)/azure/groups/loading.tsx delete mode 100644 src/app/dashboard/(active)/azure/groups/page.tsx delete mode 100644 src/app/dashboard/(active)/azure/members/columns.tsx delete mode 100644 src/app/dashboard/(active)/azure/members/create-assoc-member.tsx delete mode 100644 src/app/dashboard/(active)/azure/members/loading.tsx delete mode 100644 src/app/dashboard/(active)/azure/members/page.tsx delete mode 100644 src/app/dashboard/(active)/azure/members/set-assoc-number-dialog.tsx delete mode 100644 src/app/dashboard/(active)/azure/members/table.tsx delete mode 100644 src/app/dashboard/(active)/breadcrumb.tsx delete mode 100644 src/app/dashboard/(active)/complete-profile.tsx delete mode 100644 src/app/dashboard/(active)/layout.tsx delete mode 100644 src/app/dashboard/(active)/not-found.tsx delete mode 100644 src/app/dashboard/(active)/page.tsx delete mode 100644 src/app/dashboard/(active)/telegram/grants/delete-grant.tsx delete mode 100644 src/app/dashboard/(active)/telegram/grants/grant-list.tsx delete mode 100644 src/app/dashboard/(active)/telegram/grants/loading.tsx delete mode 100644 src/app/dashboard/(active)/telegram/grants/new-grant.tsx delete mode 100644 src/app/dashboard/(active)/telegram/grants/page.tsx delete mode 100644 src/app/dashboard/(active)/telegram/groups/group-row.tsx delete mode 100644 src/app/dashboard/(active)/telegram/groups/leave-chat.tsx delete mode 100644 src/app/dashboard/(active)/telegram/groups/loading.tsx delete mode 100644 src/app/dashboard/(active)/telegram/groups/page.tsx delete mode 100644 src/app/dashboard/(active)/telegram/users/[id]/add-role.tsx delete mode 100644 src/app/dashboard/(active)/telegram/users/[id]/card-audit-log.tsx delete mode 100644 src/app/dashboard/(active)/telegram/users/[id]/card-group-admin.tsx delete mode 100644 src/app/dashboard/(active)/telegram/users/[id]/card-message.tsx delete mode 100644 src/app/dashboard/(active)/telegram/users/[id]/card-user-grant.tsx delete mode 100644 src/app/dashboard/(active)/telegram/users/[id]/card-user-info.tsx delete mode 100644 src/app/dashboard/(active)/telegram/users/[id]/delete-group-admin.tsx delete mode 100644 src/app/dashboard/(active)/telegram/users/[id]/loading.tsx delete mode 100644 src/app/dashboard/(active)/telegram/users/[id]/new-group-admin.tsx delete mode 100644 src/app/dashboard/(active)/telegram/users/[id]/page.tsx delete mode 100644 src/app/dashboard/(active)/telegram/users/[id]/remove-role.tsx delete mode 100644 src/app/dashboard/(active)/telegram/users/loading.tsx delete mode 100644 src/app/dashboard/(active)/telegram/users/page.tsx delete mode 100644 src/app/dashboard/(active)/web/guide/columns.tsx delete mode 100644 src/app/dashboard/(active)/web/guide/create-guide.tsx delete mode 100644 src/app/dashboard/(active)/web/guide/delete-guide.tsx delete mode 100644 src/app/dashboard/(active)/web/guide/page.tsx delete mode 100644 src/app/dashboard/(active)/web/guide/table.tsx delete mode 100644 src/app/dashboard/(active)/web/guide/types.ts delete mode 100644 src/app/dashboard/disabled/page.tsx delete mode 100644 src/app/dashboard/inactive/logout.tsx delete mode 100644 src/app/dashboard/inactive/page.tsx delete mode 100644 src/app/dashboard/layout.tsx delete mode 100644 src/app/layout.tsx delete mode 100644 src/app/page.tsx delete mode 100644 src/app/testtrpc/page.tsx delete mode 100644 src/assets/logo.svg delete mode 100644 src/assets/svg/account_disabled.svg delete mode 100644 src/assets/svg/account_inactive.svg delete mode 100644 src/assets/svg/login-1.svg delete mode 100644 src/assets/svg/login-2.svg delete mode 100644 src/assets/svg/login-3.svg delete mode 100644 src/assets/svg/logo.svg delete mode 100644 src/assets/svg/shapes/big-blue.svg delete mode 100644 src/assets/svg/shapes/big-teal.svg delete mode 100644 src/assets/svg/shapes/looper.svg delete mode 100644 src/assets/svg/shapes/small-blue.svg create mode 100644 src/components/app-mark.tsx delete mode 100644 src/components/code.tsx create mode 100644 src/components/dashboard-breadcrumb.tsx create mode 100644 src/components/dashboard-frame.tsx create mode 100644 src/components/dashboard-navigation.ts create mode 100644 src/components/dashboard-sidebar.tsx delete mode 100644 src/components/dashboard-sidebar/data.tsx delete mode 100644 src/components/dashboard-sidebar/index.tsx delete mode 100644 src/components/dashboard-sidebar/main-nav.tsx delete mode 100644 src/components/dashboard-sidebar/user-nav.tsx delete mode 100644 src/components/data-table.tsx create mode 100644 src/components/data-toolbar.tsx create mode 100644 src/components/empty-state.tsx delete mode 100644 src/components/header-login-button.tsx delete mode 100644 src/components/header.tsx delete mode 100644 src/components/input-prefix.tsx create mode 100644 src/components/loading-skeleton.tsx delete mode 100644 src/components/logo.tsx delete mode 100644 src/components/logout-button.tsx delete mode 100644 src/components/navigate-back.tsx create mode 100644 src/components/page-header.tsx create mode 100644 src/components/pagination.tsx create mode 100644 src/components/reui/stepper.tsx create mode 100644 src/components/route-error.tsx delete mode 100644 src/components/search-input.tsx delete mode 100644 src/components/shapes.tsx delete mode 100644 src/components/spinner.tsx create mode 100644 src/components/telegram/create-grant-dialog.tsx create mode 100644 src/components/telegram/grant-date-time-fields.tsx delete mode 100644 src/components/theme-button.tsx delete mode 100644 src/components/theme-provider.tsx create mode 100644 src/components/theme-toggle.tsx create mode 100644 src/components/ui/combobox.tsx create mode 100644 src/components/ui/empty.tsx delete mode 100644 src/components/ui/form.tsx delete mode 100644 src/components/ui/input-otp.tsx create mode 100644 src/components/ui/pagination.tsx delete mode 100644 src/components/ui/progress.tsx delete mode 100644 src/components/ui/select.tsx delete mode 100644 src/components/ui/tabs.tsx create mode 100644 src/components/ui/wheel-picker.tsx delete mode 100644 src/components/user-select.tsx delete mode 100644 src/constants.ts create mode 100644 src/features/account/account-page.tsx create mode 100644 src/features/account/account.functions.ts create mode 100644 src/features/account/account.validation.ts create mode 100644 src/features/account/confirmation-dialog.tsx create mode 100644 src/features/account/profile-sections.tsx create mode 100644 src/features/account/security-sections.tsx create mode 100644 src/features/account/types.ts create mode 100644 src/features/account/use-account.ts create mode 100644 src/features/auth/auth.functions.ts create mode 100644 src/features/auth/login-page.tsx create mode 100644 src/features/azure/azure.functions.ts create mode 100644 src/features/azure/group-membership.tsx create mode 100644 src/features/azure/groups-page.tsx create mode 100644 src/features/azure/member-dialog.tsx create mode 100644 src/features/azure/members-page.tsx create mode 100644 src/features/dashboard/overview-page.tsx create mode 100644 src/features/guides/guide-dialogs.tsx create mode 100644 src/features/guides/guides-page.tsx create mode 100644 src/features/guides/guides.functions.ts create mode 100644 src/features/guides/guides.validation.ts create mode 100644 src/features/guides/types.ts create mode 100644 src/features/onboarding/telegram-link-page.tsx create mode 100644 src/features/onboarding/use-telegram-link.ts create mode 100644 src/features/telegram/grants-page.tsx create mode 100644 src/features/telegram/grants.functions.ts create mode 100644 src/features/telegram/groups-page.tsx create mode 100644 src/features/telegram/groups.functions.ts create mode 100644 src/features/telegram/leave-group-dialog.tsx create mode 100644 src/features/telegram/user-detail/grant-dialogs.tsx create mode 100644 src/features/telegram/user-detail/group-admin-dialog.tsx create mode 100644 src/features/telegram/user-detail/profile.tsx create mode 100644 src/features/telegram/user-detail/role-dialog.tsx create mode 100644 src/features/telegram/user-detail/sections.tsx create mode 100644 src/features/telegram/user-detail/types.ts create mode 100644 src/features/telegram/users-page.tsx create mode 100644 src/features/telegram/users.functions.ts delete mode 100644 src/hooks/use-cookie-storage.tsx delete mode 100644 src/hooks/use-local-storage.tsx delete mode 100644 src/hooks/use-mobile.tsx delete mode 100644 src/hooks/use-session-storage.tsx delete mode 100644 src/index.css rename src/{server/trpc/types.tsx => lib/api/types.ts} (88%) create mode 100644 src/lib/auth-plugins.ts create mode 100644 src/lib/table.ts rename src/lib/{utils/shadcn.ts => utils.ts} (100%) delete mode 100644 src/lib/utils/index.ts delete mode 100644 src/lib/utils/telegram.ts delete mode 100644 src/middleware.ts create mode 100644 src/routeTree.gen.ts create mode 100644 src/router.tsx create mode 100644 src/routes/__root.tsx create mode 100644 src/routes/api/auth/$.ts create mode 100644 src/routes/dashboard.tsx create mode 100644 src/routes/dashboard/account.tsx create mode 100644 src/routes/dashboard/azure/groups.tsx create mode 100644 src/routes/dashboard/azure/members.tsx create mode 100644 src/routes/dashboard/index.tsx create mode 100644 src/routes/dashboard/telegram/grants.tsx create mode 100644 src/routes/dashboard/telegram/groups.tsx create mode 100644 src/routes/dashboard/telegram/users/$userId.tsx create mode 100644 src/routes/dashboard/telegram/users/index.tsx create mode 100644 src/routes/dashboard/web/guides.tsx create mode 100644 src/routes/index.tsx create mode 100644 src/routes/login.tsx create mode 100644 src/routes/onboarding/link.tsx create mode 100644 src/routes/onboarding/unauthorized.tsx delete mode 100644 src/server/actions/azure.ts delete mode 100644 src/server/actions/grants.ts delete mode 100644 src/server/actions/groups.ts delete mode 100644 src/server/actions/guides.ts delete mode 100644 src/server/actions/test.ts delete mode 100644 src/server/actions/users.ts create mode 100644 src/server/auth-proxy-core.ts create mode 100644 src/server/auth-proxy.server.ts create mode 100644 src/server/auth.middleware.ts create mode 100644 src/server/auth.server.ts delete mode 100644 src/server/auth/index.ts create mode 100644 src/server/authorization.ts create mode 100644 src/server/backend.server.ts create mode 100644 src/server/request-headers.ts create mode 100644 src/server/runtime-env.ts delete mode 100644 src/server/trpc/index.tsx create mode 100644 src/styles.css delete mode 100644 src/utils/cookies.ts create mode 100644 src/vite-env.d.ts create mode 100644 tailwind.config.ts create mode 100644 tests/server-security.test.mjs create mode 100644 tsr.config.json create mode 100644 vite.config.ts diff --git a/.dockerignore b/.dockerignore index c550055..d6d1d07 100644 --- a/.dockerignore +++ b/.dockerignore @@ -3,5 +3,6 @@ Dockerfile node_modules npm-debug.log README.md -.next +.output +.tanstack .git diff --git a/.env.example b/.env.example index 877a2fc..06d7976 100644 --- a/.env.example +++ b/.env.example @@ -1,3 +1,3 @@ -# this file might be outdated, please check /src/env.js for required env BACKEND_URL="http://localhost:3000" -ADMIN_ORG_EMAIL="## Email address of admin Azure account ##"), +# Local preview bypass. This is ignored unless NODE_ENV is development. +AGENT_MODE="false" diff --git a/.gitignore b/.gitignore index b2de018..4ac50e3 100644 --- a/.gitignore +++ b/.gitignore @@ -13,12 +13,11 @@ /prisma/db.sqlite-journal db.sqlite -# next.js -/.next/ -/out/ - # production /build +/dist +/.output +/.tanstack # misc .DS_Store @@ -31,7 +30,6 @@ yarn-error.log* .pnpm-debug.log* # local env files -# do not commit any .env files to git, except for the .env.example file. https://create.t3.gg/en/usage/env-variables#using-environment-variables .env .env*.local @@ -44,4 +42,4 @@ yarn-error.log* # idea files .idea -certificates \ No newline at end of file +certificates diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..17a8a7d --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,33 @@ +# Agent instructions + +## Previewing the authenticated dashboard + +When checking UI changes through a preview or browser, start the app with agent mode enabled: + +```sh +PORT=xxxxx AGENT_MODE=true pnpm dev +``` + +Setting the `PORT=xxxxx` to an high enough port that is unlikely to hit +another service or conflict with another workflow in preview (min 10000). + +Then open `/dashboard` directly (if not working on a page outside dashboard). +`AGENT_MODE` bypasses session and role authorization and disables the auth-based +redirects between `/login` and `/dashboard`, so no real account or login flow is needed. +You can indipendently check /dashboard and /login for modifying those pages + +Use this flag only for local agent-driven development and previews. +Never enable it in a deployed environment. + +When modifing auth-related code or redirects between authed and non-authed contexts, +always verify that normal behavior still works with `AGENT_MODE=false`. + +> [!IMPORTANT] +> Do not run destructive actions across multiple rows, unless specific prompt indication or +> ask for user confirmation ALWAYS. + +## Git + +Always do commits with conventional commits. +Set description when a commit includes lot of changes that cannot +be divided into multiple commits, to specify the most important changes of the commit. diff --git a/CLAUDE.md b/CLAUDE.md new file mode 120000 index 0000000..47dc3e3 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1 @@ +AGENTS.md \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 7d3afaa..90268fa 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,52 +1,21 @@ -FROM node:22-alpine AS base - -FROM base AS deps -# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed. -RUN apk add --no-cache libc6-compat +FROM node:22-alpine AS deps WORKDIR /app +COPY package.json pnpm-lock.yaml ./ +RUN corepack enable && pnpm install --frozen-lockfile -# Install dependencies based on the preferred package manager -COPY package.json pnpm-lock.yaml* .npmrc* ./ -RUN corepack enable pnpm && pnpm i --frozen-lockfile - -# Rebuild the source code only when needed -FROM base AS builder +FROM node:22-alpine AS builder WORKDIR /app COPY --from=deps /app/node_modules ./node_modules COPY . . +RUN corepack enable && pnpm build -# Next.js collects completely anonymous telemetry data about general usage. -# Learn more here: https://nextjs.org/telemetry -# Uncomment the following line in case you want to disable telemetry during the build. -# ENV NEXT_TELEMETRY_DISABLED=1 -ENV SKIP_ENV_VALIDATION=true - -RUN corepack enable pnpm && pnpm run build - -# Production image, copy all the files and run next -FROM base AS runner +FROM node:22-alpine AS runner WORKDIR /app - ENV NODE_ENV=production -# Uncomment the following line in case you want to disable telemetry during runtime. -# ENV NEXT_TELEMETRY_DISABLED=1 - -RUN addgroup --system --gid 1001 nodejs -RUN adduser --system --uid 1001 nextjs - -COPY --from=builder /app/public ./public - -# Automatically leverage output traces to reduce image size -# https://nextjs.org/docs/advanced-features/output-file-tracing -COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ -COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static - -USER nextjs - -EXPOSE 3001 -ENV PORT=3001 - -# server.js is created by next build from the standalone output -# https://nextjs.org/docs/pages/api-reference/config/next-config-js/output -ENV HOSTNAME="0.0.0.0" -CMD ["node", "server.js"] +ENV PORT=3000 +ENV HOST=0.0.0.0 +COPY --from=builder /app/.output ./.output +COPY --from=builder /app/node_modules ./node_modules +COPY --from=builder /app/package.json ./package.json +EXPOSE 3000 +CMD ["node", ".output/server/index.mjs"] diff --git a/README.md b/README.md index 2d0a5d7..39fc7c7 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,29 @@ -# Admin +# PoliNetwork Admin -[WIP] Dashboard for admin and members of PoliNetwork APS +The PoliNetwork operations console, rebuilt with TanStack Start, React 19, Vite, Nitro, Tailwind CSS v4, and shadcn/ui. + +## Development + +```bash +pnpm install +pnpm dev +``` + +Open `http://localhost:3001`. The production server is generated with `pnpm build` and starts with `pnpm start`. + +The UI uses shadcn's base components with a custom semantic theme in `src/styles.css`. The theme preserves the console's paper canvas, dark navy shell, cobalt `#1156ae` primary, DM Sans body copy, Libre Baskerville headings, and DM Mono metadata while keeping page layout in Tailwind utilities. + +## Environment + +Set `BACKEND_URL` to the PoliNetwork backend origin. TanStack Start proxies Better Auth at `/api/auth/*`, and each server-function request creates its own tRPC client with that request's session cookie. Private dashboard functions also verify the linked Telegram identity and an administrator role before contacting the backend. + +`AGENT_MODE=true` provides a fake administrator only while the app runs in development. Production ignores the flag. + +## Checks + +```bash +pnpm typecheck +pnpm test +pnpm check +pnpm build +``` diff --git a/biome.jsonc b/biome.jsonc index 9e1c810..18a9891 100644 --- a/biome.jsonc +++ b/biome.jsonc @@ -7,15 +7,7 @@ }, "files": { "ignoreUnknown": true, - "includes": [ - "**", - "!node_modules", - "!.next", - "!dist", - "!build", - "!src/app/globals.css", // modified by shadcn - "!src/components/ui/*" // modified by shadcn - ] + "includes": ["**", "!node_modules", "!dist", "!build", "!.output", "!.tanstack", "!src/routeTree.gen.ts"] }, "formatter": { "enabled": true, @@ -36,29 +28,21 @@ "recommended": true, "suspicious": { "noVar": "error" - // "noUnknownAtRules": "off" // until fix for tailwind rules is released + // Project-specific suspicious rules live here. }, "nursery": { "noFloatingPromises": "error", "noMisusedPromises": "error", "noUnnecessaryConditions": "error", "noImportCycles": "warn", - "useSortedClasses": { - "options": { - "attributes": ["classList"], - "functions": ["cn"] - } - } + "useSortedClasses": "off" }, "correctness": { "useJsonImportAttributes": "warn", "noPrivateImports": "error" } }, - "domains": { - "project": "recommended", - "next": "recommended" - } + "domains": { "project": "recommended" } }, "javascript": { "formatter": { diff --git a/components.json b/components.json index 4a9d7a4..e02f8e2 100644 --- a/components.json +++ b/components.json @@ -1,25 +1,28 @@ { "$schema": "https://ui.shadcn.com/schema.json", "style": "base-nova", - "rsc": true, + "rsc": false, "tsx": true, "tailwind": { - "config": "", - "css": "src/index.css", + "config": "tailwind.config.ts", + "css": "src/styles.css", "baseColor": "neutral", "cssVariables": true, "prefix": "" }, "iconLibrary": "lucide", "rtl": false, + "menuColor": "default", + "menuAccent": "subtle", "aliases": { "components": "@/components", - "utils": "@/lib/utils/shadcn", + "utils": "@/lib/utils", "ui": "@/components/ui", "lib": "@/lib", "hooks": "@/hooks" }, - "menuColor": "default", - "menuAccent": "subtle", - "registries": {} + "registries": { + "@iconiq": "https://iconiqui.com/r/{name}.json", + "@reui": "https://reui.io/r/{style}/{name}.json" + } } diff --git a/next-env.d.ts b/next-env.d.ts deleted file mode 100644 index 830fb59..0000000 --- a/next-env.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -/// -/// -/// - -// NOTE: This file should not be edited -// see https://nextjs.org/docs/app/api-reference/config/typescript for more information. diff --git a/next.config.ts b/next.config.ts deleted file mode 100644 index 3fa77a8..0000000 --- a/next.config.ts +++ /dev/null @@ -1,30 +0,0 @@ -import type { NextConfig } from "next" -/** - * Run `build` or `dev` with `SKIP_ENV_VALIDATION` to skip env validation. This is especially useful - * for Docker builds. - */ -import "./src/env.ts" - -const config: NextConfig = { - typescript: { - ignoreBuildErrors: true, - }, - output: "standalone", - transpilePackages: ["@t3-oss/env-core", "@t3-oss/env-nextjs"], - images: { - remotePatterns: [ - { - protocol: "https", - hostname: "**.blob.core.windows.net", - }, - ], - }, - experimental: { - reactCompiler: true, - serverActions: { - bodySizeLimit: "2mb", - }, - }, -} - -export default config diff --git a/package.json b/package.json index 78b8ec7..e56a047 100644 --- a/package.json +++ b/package.json @@ -4,65 +4,54 @@ "private": true, "type": "module", "scripts": { - "build": "next build", - "dev": "PORT=3001 next dev --turbo", + "dev": "vite dev", + "build": "vite build", + "start": "NODE_ENV=production node .output/server/index.mjs", + "preview": "vite preview", + "test": "node --experimental-strip-types --test tests/*.test.mjs", + "typecheck": "tsc --noEmit", "check": "biome check", - "check:fix": "biome check --fix --unsafe", - "preview": "next build && next start", - "start": "next start", - "typecheck": "tsc --noEmit" + "check:fix": "biome check --write --unsafe" }, "dependencies": { - "@base-ui/react": "^1.3.0", + "@base-ui/react": "^1.6.0", "@better-auth/passkey": "^1.5.5", - "@hookform/resolvers": "^3.9.1", "@polinetwork/backend": "^0.17.0", - "@radix-ui/react-dialog": "^1.1.15", - "@t3-oss/env-nextjs": "^0.13.10", - "@tanstack/react-table": "^8.21.2", + "@t3-oss/env-core": "^0.13.10", + "@tanstack/react-router": "1.170.17", + "@tanstack/react-start": "1.168.27", + "@tanstack/react-store": "^0.11.0", + "@tanstack/react-table": "9.0.0-beta.38", "@trpc/client": "11.5.1", - "@trpc/next": "11.5.1", - "babel-plugin-react-compiler": "1.0.0", "better-auth": "^1.5.5", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "cmdk": "^1.1.1", - "date-fns": "^4.1.0", - "geist": "^1.3.0", - "input-otp": "^1.4.2", - "next": "^15.5.18", - "next-themes": "^0.4.4", - "postgres": "^3.4.4", - "radix-ui": "^1.4.3", - "react": "^18.3.1", - "react-day-picker": "^9.14.0", - "react-dom": "^18.3.1", - "react-error-boundary": "^6.1.0", - "react-hook-form": "^7.55.0", - "react-icons": "^5.7.0", - "server-only": "^0.0.1", - "shadcn": "^4.2.0", - "sonner": "^2.0.3", + "date-fns": "^4.4.0", + "lucide-react": "^0.545.0", + "motion": "^12.42.2", + "nitro": "3.0.260610-beta", + "react": "^19.2.0", + "react-day-picker": "^10.0.1", + "react-dom": "^19.2.0", + "shadcn": "^4.13.0", + "sonner": "^2.0.7", "superjson": "^2.2.1", - "tailwind-merge": "^3.0.1", - "tailwind-scrollbar": "^4.0.2", - "tailwindcss-animate": "^1.0.7", + "tailwind-merge": "^3.6.0", "tw-animate-css": "^1.4.0", "zod": "^4.3.5" }, "devDependencies": { "@biomejs/biome": "2.3.10", - "@tailwindcss/postcss": "^4.1.4", + "@tailwindcss/vite": "^4.3.2", "@trpc/server": "11.5.1", - "@types/node": "^20.14.10", - "@types/react": "^18.3.3", - "@types/react-dom": "^18.3.0", - "postcss": "^8.4.39", - "tailwindcss": "^4.1.4", - "typescript": "^5.5.3" + "@types/node": "^22.10.2", + "@types/react": "^19.2.0", + "@types/react-dom": "^19.2.0", + "@vitejs/plugin-react": "^6.0.1", + "tailwindcss": "^4.3.2", + "typescript": "^6.0.2", + "vite": "^8.0.0" }, - "ct3aMetadata": { - "initVersion": "7.38.1" - }, - "packageManager": "pnpm@10.8.1+sha512.c50088ba998c67b8ca8c99df8a5e02fd2ae2e2b29aaf238feaa9e124248d3f48f9fb6db2424949ff901cffbb5e0f0cc1ad6aedb602cd29450751d11c35023677" + "packageManager": "pnpm@10.8.1" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 11dc93d..5a6d4e5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,38 +9,35 @@ importers: .: dependencies: '@base-ui/react': - specifier: ^1.3.0 - version: 1.3.0(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: ^1.6.0 + version: 1.6.0(@date-fns/tz@1.5.0)(@types/react@19.2.17)(date-fns@4.4.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) '@better-auth/passkey': specifier: ^1.5.5 - version: 1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.1.3)(kysely@0.28.12)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-auth@1.5.5(mongodb@7.1.0)(next@15.5.18(@babel/core@7.29.0)(babel-plugin-react-compiler@1.0.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(better-call@1.3.2(zod@4.3.5))(nanostores@1.2.0) - '@hookform/resolvers': - specifier: ^3.9.1 - version: 3.10.0(react-hook-form@7.55.0(react@18.3.1)) + version: 1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.1.3)(kysely@0.28.12)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-auth@1.5.5(@tanstack/react-start@1.168.27(crossws@0.4.9(srvx@0.11.21))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(rolldown@1.1.5)(vite@8.1.4(@types/node@22.20.1)(jiti@2.7.0)))(mongodb@7.1.0)(next@15.5.18(@babel/core@7.29.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(solid-js@1.9.14))(better-call@1.3.2(zod@4.3.5))(nanostores@1.2.0) '@polinetwork/backend': specifier: ^0.17.0 version: 0.17.0 - '@radix-ui/react-dialog': - specifier: ^1.1.15 - version: 1.1.15(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@t3-oss/env-nextjs': + '@t3-oss/env-core': specifier: ^0.13.10 - version: 0.13.10(typescript@5.7.3)(zod@4.3.5) + version: 0.13.11(typescript@6.0.3)(zod@4.3.5) + '@tanstack/react-router': + specifier: 1.170.17 + version: 1.170.17(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@tanstack/react-start': + specifier: 1.168.27 + version: 1.168.27(crossws@0.4.9(srvx@0.11.21))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(rolldown@1.1.5)(vite@8.1.4(@types/node@22.20.1)(jiti@2.7.0)) + '@tanstack/react-store': + specifier: ^0.11.0 + version: 0.11.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7) '@tanstack/react-table': - specifier: ^8.21.2 - version: 8.21.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: 9.0.0-beta.38 + version: 9.0.0-beta.38(react-dom@19.2.7(react@19.2.7))(react@19.2.7) '@trpc/client': specifier: 11.5.1 - version: 11.5.1(@trpc/server@11.5.1(typescript@5.7.3))(typescript@5.7.3) - '@trpc/next': - specifier: 11.5.1 - version: 11.5.1(@tanstack/react-query@5.90.19(react@18.3.1))(@trpc/client@11.5.1(@trpc/server@11.5.1(typescript@5.7.3))(typescript@5.7.3))(@trpc/react-query@11.5.1(@tanstack/react-query@5.90.19(react@18.3.1))(@trpc/client@11.5.1(@trpc/server@11.5.1(typescript@5.7.3))(typescript@5.7.3))(@trpc/server@11.5.1(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3))(@trpc/server@11.5.1(typescript@5.7.3))(next@15.5.18(@babel/core@7.29.0)(babel-plugin-react-compiler@1.0.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3) - babel-plugin-react-compiler: - specifier: 1.0.0 - version: 1.0.0 + version: 11.5.1(@trpc/server@11.5.1(typescript@6.0.3))(typescript@6.0.3) better-auth: specifier: ^1.5.5 - version: 1.5.5(mongodb@7.1.0)(next@15.5.18(@babel/core@7.29.0)(babel-plugin-react-compiler@1.0.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 1.5.5(@tanstack/react-start@1.168.27(crossws@0.4.9(srvx@0.11.21))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(rolldown@1.1.5)(vite@8.1.4(@types/node@22.20.1)(jiti@2.7.0)))(mongodb@7.1.0)(next@15.5.18(@babel/core@7.29.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(solid-js@1.9.14) class-variance-authority: specifier: ^0.7.1 version: 0.7.1 @@ -49,67 +46,40 @@ importers: version: 2.1.1 cmdk: specifier: ^1.1.1 - version: 1.1.1(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 1.1.1(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) date-fns: - specifier: ^4.1.0 - version: 4.1.0 - geist: - specifier: ^1.3.0 - version: 1.3.1(next@15.5.18(@babel/core@7.29.0)(babel-plugin-react-compiler@1.0.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) - input-otp: - specifier: ^1.4.2 - version: 1.4.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - next: - specifier: ^15.5.18 - version: 15.5.18(@babel/core@7.29.0)(babel-plugin-react-compiler@1.0.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - next-themes: - specifier: ^0.4.4 - version: 0.4.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - postgres: - specifier: ^3.4.4 - version: 3.4.5 - radix-ui: - specifier: ^1.4.3 - version: 1.4.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: ^4.4.0 + version: 4.4.0 + lucide-react: + specifier: ^0.545.0 + version: 0.545.0(react@19.2.7) + motion: + specifier: ^12.42.2 + version: 12.42.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + nitro: + specifier: 3.0.260610-beta + version: 3.0.260610-beta(chokidar@5.0.0)(dotenv@17.4.2)(jiti@2.7.0)(mongodb@7.1.0)(vite@8.1.4(@types/node@22.20.1)(jiti@2.7.0)) react: - specifier: ^18.3.1 - version: 18.3.1 + specifier: ^19.2.0 + version: 19.2.7 react-day-picker: - specifier: ^9.14.0 - version: 9.14.0(react@18.3.1) + specifier: ^10.0.1 + version: 10.0.1(@types/react@19.2.17)(react@19.2.7) react-dom: - specifier: ^18.3.1 - version: 18.3.1(react@18.3.1) - react-error-boundary: - specifier: ^6.1.0 - version: 6.1.0(react@18.3.1) - react-hook-form: - specifier: ^7.55.0 - version: 7.55.0(react@18.3.1) - react-icons: - specifier: ^5.7.0 - version: 5.7.0(react@18.3.1) - server-only: - specifier: ^0.0.1 - version: 0.0.1 + specifier: ^19.2.0 + version: 19.2.7(react@19.2.7) shadcn: - specifier: ^4.2.0 - version: 4.2.0(@types/node@20.17.19)(typescript@5.7.3) + specifier: ^4.13.0 + version: 4.13.0(typescript@6.0.3) sonner: - specifier: ^2.0.3 - version: 2.0.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: ^2.0.7 + version: 2.0.7(react-dom@19.2.7(react@19.2.7))(react@19.2.7) superjson: specifier: ^2.2.1 version: 2.2.2 tailwind-merge: - specifier: ^3.0.1 - version: 3.0.1 - tailwind-scrollbar: - specifier: ^4.0.2 - version: 4.0.2(react@18.3.1)(tailwindcss@4.1.4) - tailwindcss-animate: - specifier: ^1.0.7 - version: 1.0.7(tailwindcss@4.1.4) + specifier: ^3.6.0 + version: 3.6.0 tw-animate-css: specifier: ^1.4.0 version: 1.4.0 @@ -120,41 +90,48 @@ importers: '@biomejs/biome': specifier: 2.3.10 version: 2.3.10 - '@tailwindcss/postcss': - specifier: ^4.1.4 - version: 4.1.4 + '@tailwindcss/vite': + specifier: ^4.3.2 + version: 4.3.2(vite@8.1.4(@types/node@22.20.1)(jiti@2.7.0)) '@trpc/server': specifier: 11.5.1 - version: 11.5.1(typescript@5.7.3) + version: 11.5.1(typescript@6.0.3) '@types/node': - specifier: ^20.14.10 - version: 20.17.19 + specifier: ^22.10.2 + version: 22.20.1 '@types/react': - specifier: ^18.3.3 - version: 18.3.18 + specifier: ^19.2.0 + version: 19.2.17 '@types/react-dom': - specifier: ^18.3.0 - version: 18.3.5(@types/react@18.3.18) - postcss: - specifier: ^8.4.39 - version: 8.5.2 + specifier: ^19.2.0 + version: 19.2.3(@types/react@19.2.17) + '@vitejs/plugin-react': + specifier: ^6.0.1 + version: 6.0.3(babel-plugin-react-compiler@1.0.0)(vite@8.1.4(@types/node@22.20.1)(jiti@2.7.0)) tailwindcss: - specifier: ^4.1.4 - version: 4.1.4 + specifier: ^4.3.2 + version: 4.3.2 typescript: - specifier: ^5.5.3 - version: 5.7.3 + specifier: ^6.0.2 + version: 6.0.3 + vite: + specifier: ^8.0.0 + version: 8.1.4(@types/node@22.20.1)(jiti@2.7.0) packages: - '@alloc/quick-lru@5.2.0': - resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} - engines: {node: '>=10'} + '@babel/code-frame@7.27.1': + resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} + engines: {node: '>=6.9.0'} '@babel/code-frame@7.29.0': resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==} engines: {node: '>=6.9.0'} + '@babel/code-frame@7.29.7': + resolution: {integrity: sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==} + engines: {node: '>=6.9.0'} + '@babel/compat-data@7.29.0': resolution: {integrity: sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==} engines: {node: '>=6.9.0'} @@ -167,16 +144,20 @@ packages: resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==} engines: {node: '>=6.9.0'} - '@babel/helper-annotate-as-pure@7.27.3': - resolution: {integrity: sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==} + '@babel/generator@7.29.7': + resolution: {integrity: sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-annotate-as-pure@7.29.7': + resolution: {integrity: sha512-OoK6239jHPuSQOoS0kfTVKn0b/rVTk0seKq4Gd2UMLtmOVLjDC0ki3e+c90Trqv2gMfvJFqkiljrr568+qddiw==} engines: {node: '>=6.9.0'} '@babel/helper-compilation-targets@7.28.6': resolution: {integrity: sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==} engines: {node: '>=6.9.0'} - '@babel/helper-create-class-features-plugin@7.28.6': - resolution: {integrity: sha512-dTOdvsjnG3xNT9Y0AUg1wAl38y+4Rl4sf9caSQZOXdNqVn+H+HbbJ4IyyHaIqNR6SW9oJpA/RuRjsjCw2IdIow==} + '@babel/helper-create-class-features-plugin@7.29.7': + resolution: {integrity: sha512-IY3ZD9Tmooqr3TUhc3DUWxiuo8xx1DWLhd5M7hQ+ZWJamqM2BbalrBJb2MisSLoYorOj75U03qULCxQTY9r3hg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 @@ -185,54 +166,76 @@ packages: resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} engines: {node: '>=6.9.0'} - '@babel/helper-member-expression-to-functions@7.28.5': - resolution: {integrity: sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==} + '@babel/helper-globals@7.29.7': + resolution: {integrity: sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-member-expression-to-functions@7.29.7': + resolution: {integrity: sha512-j+7JYmk1JYDtACIGj0QJqqWZjoUpMoEikQGADMaHgCMCSDqd2+P32rfcibUNrGOMWrlzK1WJBdxrB3JJQZwWtg==} engines: {node: '>=6.9.0'} '@babel/helper-module-imports@7.28.6': resolution: {integrity: sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==} engines: {node: '>=6.9.0'} + '@babel/helper-module-imports@7.29.7': + resolution: {integrity: sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==} + engines: {node: '>=6.9.0'} + '@babel/helper-module-transforms@7.28.6': resolution: {integrity: sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-optimise-call-expression@7.27.1': - resolution: {integrity: sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==} + '@babel/helper-module-transforms@7.29.7': + resolution: {integrity: sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-optimise-call-expression@7.29.7': + resolution: {integrity: sha512-+kmGVjcT9RGYzoDwdwEqEvGgKe3BYq+O1iGzjFubaNgZHwYHP6lsF2Yghf4kEuv9BV7tYDZ913aBW9am6YKong==} engines: {node: '>=6.9.0'} - '@babel/helper-plugin-utils@7.28.6': - resolution: {integrity: sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==} + '@babel/helper-plugin-utils@7.29.7': + resolution: {integrity: sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==} engines: {node: '>=6.9.0'} - '@babel/helper-replace-supers@7.28.6': - resolution: {integrity: sha512-mq8e+laIk94/yFec3DxSjCRD2Z0TAjhVbEJY3UQrlwVo15Lmt7C2wAUbK4bjnTs4APkwsYLTahXRraQXhb1WCg==} + '@babel/helper-replace-supers@7.29.7': + resolution: {integrity: sha512-atfGXWSeCiF4DnKZIfmJfQRkSw9b9gNNXR1kqKjbhG4pGYCOnkp8OcTB8E3NXjBu8NpheSnOeNKz8KT7UNFTmQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-skip-transparent-expression-wrappers@7.27.1': - resolution: {integrity: sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==} + '@babel/helper-skip-transparent-expression-wrappers@7.29.7': + resolution: {integrity: sha512-brcMGQaVzIeUb+6/bs1Av0f8YuNNjKY2JyvfRCsFuFsdKccEQ5Ges2y74D74NZ1Rz8lKJ9ksJkfqwQFJ/iNEyQ==} engines: {node: '>=6.9.0'} '@babel/helper-string-parser@7.27.1': resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-identifier@7.27.1': - resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==} + '@babel/helper-string-parser@7.29.7': + resolution: {integrity: sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==} engines: {node: '>=6.9.0'} '@babel/helper-validator-identifier@7.28.5': resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} engines: {node: '>=6.9.0'} + '@babel/helper-validator-identifier@7.29.7': + resolution: {integrity: sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==} + engines: {node: '>=6.9.0'} + '@babel/helper-validator-option@7.27.1': resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} engines: {node: '>=6.9.0'} + '@babel/helper-validator-option@7.29.7': + resolution: {integrity: sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==} + engines: {node: '>=6.9.0'} + '@babel/helpers@7.29.2': resolution: {integrity: sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==} engines: {node: '>=6.9.0'} @@ -242,69 +245,88 @@ packages: engines: {node: '>=6.0.0'} hasBin: true - '@babel/plugin-syntax-jsx@7.28.6': - resolution: {integrity: sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==} + '@babel/parser@7.29.7': + resolution: {integrity: sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/plugin-syntax-jsx@7.29.7': + resolution: {integrity: sha512-TSu8+mHCoEaaCDEZ0I3+6mvTBYR4PCxQwf2z9/r5Tbztv6NaLR3B9thGTTxX2WGuGHJqRiAbKPeGTJ5XWXVg6A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-typescript@7.28.6': - resolution: {integrity: sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A==} + '@babel/plugin-syntax-typescript@7.29.7': + resolution: {integrity: sha512-ngr+82Sh0xMz25TPCZi+nC2iTzjfCdWS2ONXTp/PtSCHCgaCNBpdMqgvJ2ccdLlClVZ7sisIgB914j/JFe+RZA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-modules-commonjs@7.28.6': - resolution: {integrity: sha512-jppVbf8IV9iWWwWTQIxJMAJCWBuuKx71475wHwYytrRGQ2CWiDvYlADQno3tcYpS/T2UUWFQp3nVtYfK/YBQrA==} + '@babel/plugin-transform-modules-commonjs@7.29.7': + resolution: {integrity: sha512-j0vCldybPC5b5dwCQOJ21uKtHzt7hxLygJTg9eF1ScfaikEDNfzn94XoW5Fi+seBR0nCyL23xaBFFkq7dTM8XQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-typescript@7.28.6': - resolution: {integrity: sha512-0YWL2RFxOqEm9Efk5PvreamxPME8OyY0wM5wh5lHjF+VtVhdneCWGzZeSqzOfiobVqQaNCd2z0tQvnI9DaPWPw==} + '@babel/plugin-transform-typescript@7.29.7': + resolution: {integrity: sha512-jK52h8LaLc7JarhQV2ofeFMts4H7vnOXnqZNA6fYglBTZewRBE51KWt3BUltW1P+KoPsYkHoJeXePuz4zo2LMw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/preset-typescript@7.28.5': - resolution: {integrity: sha512-+bQy5WOI2V6LJZpPVxY+yp66XdZ2yifu0Mc1aP5CQKgjn4QM5IN2i5fAZ4xKop47pr8rpVhiAeu+nDQa12C8+g==} + '@babel/preset-typescript@7.29.7': + resolution: {integrity: sha512-/Foi8vKY2EVbed/1eZx0gJEEwHAIxogrySI7rULcRIvhZzbvoE/b5qG5Ghc0WKAFKOHA9SD1x7RsFlOYdutIiQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/runtime@7.29.2': - resolution: {integrity: sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==} + '@babel/runtime@7.29.7': + resolution: {integrity: sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==} engines: {node: '>=6.9.0'} '@babel/template@7.28.6': resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==} engines: {node: '>=6.9.0'} + '@babel/template@7.29.7': + resolution: {integrity: sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==} + engines: {node: '>=6.9.0'} + '@babel/traverse@7.29.0': resolution: {integrity: sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==} engines: {node: '>=6.9.0'} - '@babel/types@7.28.2': - resolution: {integrity: sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==} + '@babel/traverse@7.29.7': + resolution: {integrity: sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==} engines: {node: '>=6.9.0'} '@babel/types@7.29.0': resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} engines: {node: '>=6.9.0'} - '@base-ui/react@1.3.0': - resolution: {integrity: sha512-FwpKqZbPz14AITp1CVgf4AjhKPe1OeeVKSBMdgD10zbFlj3QSWelmtCMLi2+/PFZZcIm3l87G7rwtCZJwHyXWA==} + '@babel/types@7.29.7': + resolution: {integrity: sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==} + engines: {node: '>=6.9.0'} + + '@base-ui/react@1.6.0': + resolution: {integrity: sha512-/jzjTWJYXhRFO45Bev9lc3cHbmjzCMpUqbMZ2AgKy/z25mY9B6shGSNcXcjQar9n5doM0KYW1W8fcFv2jZBuMw==} engines: {node: '>=14.0.0'} peerDependencies: + '@date-fns/tz': ^1.2.0 '@types/react': ^17 || ^18 || ^19 + date-fns: ^4.0.0 react: ^17 || ^18 || ^19 react-dom: ^17 || ^18 || ^19 peerDependenciesMeta: + '@date-fns/tz': + optional: true '@types/react': optional: true + date-fns: + optional: true - '@base-ui/utils@0.2.6': - resolution: {integrity: sha512-yQ+qeuqohwhsNpoYDqqXaLllYAkPCP4vYdDrVo8FQXaAPfHWm1pG/Vm+jmGTA5JFS0BAIjookyapuJFY8F9PIw==} + '@base-ui/utils@0.3.1': + resolution: {integrity: sha512-gFFiltORVmW/N6IILTGxizP3PBpVpysqML1ALY5Vk0mH+7faVkCknOU31goYHN5Aoek2dkjxva1XOD2Ce9WuIg==} peerDependencies: '@types/react': ^17 || ^18 || ^19 react: ^17 || ^18 || ^19 @@ -444,40 +466,31 @@ packages: cpu: [x64] os: [win32] - '@date-fns/tz@1.4.1': - resolution: {integrity: sha512-P5LUNhtbj6YfI3iJjw5EL9eUAG6OitD0W3fWQcpQjDRc/QIsL0tRNuO1PcDvPccWL1fSTXXdE1ds+l95DV/OFA==} + '@date-fns/tz@1.5.0': + resolution: {integrity: sha512-lwYN/vDPeNRULcepoE/LO2Pgx+7/RV+S9ARfbc9lr2DtGkOD7pAiruHvbR1RX3Qyf6ja47EWJDMsNK5vK08DJg==} - '@dotenvx/dotenvx@1.61.0': - resolution: {integrity: sha512-utL3cpZoFzflyqUkjYbxYujI6STBTmO5LFn4bbin/NZnRWN6wQ7eErhr3/Vpa5h/jicPFC6kTa42r940mQftJQ==} + '@dotenvx/dotenvx@1.75.1': + resolution: {integrity: sha512-/BITOC9dmS/edY2zQwZNicQ059O6RKabtQfyEafV0nGtfYRNHYy1DIPiYVcov40+tob9hfmBnbR963dS+EQ1DQ==} hasBin: true - '@ecies/ciphers@0.2.6': - resolution: {integrity: sha512-patgsRPKGkhhoBjETV4XxD0En4ui5fbX0hzayqI3M8tvNMGUoUvmyYAIWwlxBc1KX5cturfqByYdj5bYGRpN9g==} - engines: {bun: '>=1', deno: '>=2.7.10', node: '>=16'} - peerDependencies: - '@noble/ciphers': ^1.0.0 + '@dotenvx/primitives@0.8.0': + resolution: {integrity: sha512-VYJy0uhFm9zTJ1TxBaW/pA8bjbOM/OttaNMwZ1RHG4JKyRG7DhSdiqD1ipQoAyoD22olUtxbP78W9xY3Wd11bg==} + + '@emnapi/core@1.11.1': + resolution: {integrity: sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ==} - '@emnapi/runtime@1.10.0': - resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==} + '@emnapi/runtime@1.11.1': + resolution: {integrity: sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==} - '@floating-ui/core@1.6.9': - resolution: {integrity: sha512-uMXCuQ3BItDUbAMhIXw7UPXRfAlOAvZzdK9BWpE60MCn+Svt3aLn9jsPTi/WNGlRUu2uI0v5S7JiIUsbsvh3fw==} + '@emnapi/wasi-threads@1.2.2': + resolution: {integrity: sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==} '@floating-ui/core@1.7.5': resolution: {integrity: sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==} - '@floating-ui/dom@1.6.13': - resolution: {integrity: sha512-umqzocjDgNRGTuO7Q8CU32dkHkECqI8ZdMZ5Swb6QAM0t5rnlrN3lGo1hdpscRd3WS8T6DKYK4ephgIH9iRh3w==} - '@floating-ui/dom@1.7.6': resolution: {integrity: sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==} - '@floating-ui/react-dom@2.1.2': - resolution: {integrity: sha512-06okr5cgPzMNBy+Ycse2A6udMi4bqwW/zgBF/rwjcNqWkyr82Mcg8b0vjX8OJpZFy/FKjJmw6wV7t44kK6kW7A==} - peerDependencies: - react: '>=16.8.0' - react-dom: '>=16.8.0' - '@floating-ui/react-dom@2.1.8': resolution: {integrity: sha512-cC52bHwM/n/CxS87FH0yWdngEZrjdtLW/qVruo68qg+prK7ZQ4YGdut2GyDVpoGeAYe/h899rVeOVm6Oi40k2A==} peerDependencies: @@ -487,23 +500,15 @@ packages: '@floating-ui/utils@0.2.11': resolution: {integrity: sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==} - '@floating-ui/utils@0.2.9': - resolution: {integrity: sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==} - '@hexagon/base64@1.1.28': resolution: {integrity: sha512-lhqDEAvWixy3bZ+UOYbPwUbBkwBq5C1LAJ/xPC8Oi+lL54oyakv/npbA0aU2hgCsx/1NUd4IBvV03+aUBWxerw==} - '@hono/node-server@1.19.13': - resolution: {integrity: sha512-TsQLe4i2gvoTtrHje625ngThGBySOgSK3Xo2XRYOdqGN1teR8+I7vchQC46uLJi8OF62YTYA3AhSpumtkhsaKQ==} + '@hono/node-server@1.19.14': + resolution: {integrity: sha512-GwtvgtXxnWsucXvbQXkRgqksiH2Qed37H9xHZocE5sA3N8O8O8/8FA3uclQXxXVzc9XBZuEOMK7+r02FmSpHtw==} engines: {node: '>=18.14.1'} peerDependencies: hono: ^4 - '@hookform/resolvers@3.10.0': - resolution: {integrity: sha512-79Dv+3mDF7i+2ajj7SkypSKHhl1cbln1OGavqrsF7p6mbUv11xpqpacPsGDCTRvCSjEEIez2ef1NveSVL3b0Ag==} - peerDependencies: - react-hook-form: ^7.0.0 - '@img/colour@1.1.0': resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==} engines: {node: '>=18'} @@ -641,41 +646,6 @@ packages: cpu: [x64] os: [win32] - '@inquirer/ansi@1.0.2': - resolution: {integrity: sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ==} - engines: {node: '>=18'} - - '@inquirer/confirm@5.1.21': - resolution: {integrity: sha512-KR8edRkIsUayMXV+o3Gv+q4jlhENF9nMYUZs9PA2HzrXeHI8M5uDag70U7RJn9yyiMZSbtF5/UexBtAVtZGSbQ==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/core@10.3.2': - resolution: {integrity: sha512-43RTuEbfP8MbKzedNqBrlhhNKVwoK//vUFNW3Q3vZ88BLcrs4kYpGg+B2mm5p2K/HfygoCxuKwJJiv8PbGmE0A==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/figures@1.0.15': - resolution: {integrity: sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g==} - engines: {node: '>=18'} - - '@inquirer/type@3.0.10': - resolution: {integrity: sha512-BvziSRxfz5Ov8ch0z/n3oijRSEcEsHnhggm4xFZe93DHcUCTlutlq9Ox4SVENAfcRD22UQq7T/atg9Wr3k09eA==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@jridgewell/gen-mapping@0.3.13': resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} @@ -708,9 +678,11 @@ packages: '@mongodb-js/saslprep@1.4.11': resolution: {integrity: sha512-o9rAHc0IpIjuPSxRutWpE1F62x7n+4mVS4rCNHkzhIUMQcc18bb6xEq5wd2NdN0WjepIyXIppRshYI2kQDOZVA==} - '@mswjs/interceptors@0.41.3': - resolution: {integrity: sha512-cXu86tF4VQVfwz8W1SPbhoRyHJkti6mjH/XJIxp40jhO4j2k1m4KYrEykxqWPkFF3vrK4rgQppBh//AwyGSXPA==} - engines: {node: '>=18'} + '@napi-rs/wasm-runtime@1.1.6': + resolution: {integrity: sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg==} + peerDependencies: + '@emnapi/core': ^1.7.1 + '@emnapi/runtime': ^1.7.1 '@next/env@15.5.18': resolution: {integrity: sha512-hAV85Ckd9QR6RvH04MEKwsfLTksvFpO47j9xwtoIuvuPnlwecpSi+uZTtm8HirVbtlI2Fnz//xpcSTjFdyJk+g==} @@ -763,22 +735,10 @@ packages: cpu: [x64] os: [win32] - '@noble/ciphers@1.3.0': - resolution: {integrity: sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==} - engines: {node: ^14.21.3 || >=16} - '@noble/ciphers@2.1.1': resolution: {integrity: sha512-bysYuiVfhxNJuldNXlFEitTVdNnYUc+XNJZd7Qm2a5j1vZHgY+fazadNFWFaMK/2vye0JVlxV3gHmC0WDfAOQw==} engines: {node: '>= 20.19.0'} - '@noble/curves@1.9.7': - resolution: {integrity: sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw==} - engines: {node: ^14.21.3 || >=16} - - '@noble/hashes@1.8.0': - resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==} - engines: {node: ^14.21.3 || >=16} - '@noble/hashes@2.0.1': resolution: {integrity: sha512-XlOlEbQcE9fmuXxrVTXCTlG2nlRXa9Rj3rr5Ue/+tX+nmkgbX720YHh0VR3hBF9xDvwnb8D2shVGOwNx+ulArw==} engines: {node: '>= 20.19.0'} @@ -795,14 +755,24 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} - '@open-draft/deferred-promise@2.2.0': - resolution: {integrity: sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==} + '@oozcitak/dom@2.0.2': + resolution: {integrity: sha512-GjpKhkSYC3Mj4+lfwEyI1dqnsKTgwGy48ytZEhm4A/xnH/8z9M3ZVXKr/YGQi3uCLs1AEBS+x5T2JPiueEDW8w==} + engines: {node: '>=20.0'} + + '@oozcitak/infra@2.0.2': + resolution: {integrity: sha512-2g+E7hoE2dgCz/APPOEK5s3rMhJvNxSMBrP+U+j1OWsIbtSpWxxlUjq1lU8RIsFJNYv7NMlnVsCuHcUzJW+8vA==} + engines: {node: '>=20.0'} - '@open-draft/logger@0.3.0': - resolution: {integrity: sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==} + '@oozcitak/url@3.0.0': + resolution: {integrity: sha512-ZKfET8Ak1wsLAiLWNfFkZc/BraDccuTJKR6svTYc7sVjbR+Iu0vtXdiDMY4o6jaFl5TW2TlS7jbLl4VovtAJWQ==} + engines: {node: '>=20.0'} - '@open-draft/until@2.1.0': - resolution: {integrity: sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==} + '@oozcitak/util@10.0.0': + resolution: {integrity: sha512-hAX0pT/73190NLqBPPWSdBVGtbY6VOhWYK3qqHqtXQ1gK7kS2yz4+ivsN07hpJ6I3aeMtKP6J6npsEKOAzuTLA==} + engines: {node: '>=20.0'} + + '@oxc-project/types@0.139.0': + resolution: {integrity: sha512-r9gHphtCs+1M7J0pw6Sn/hh/Wpa/iQrOOkrNAlVLF/gHq+/CJmHIWKKUUhdWjcD6CIa8idarspCsASiXCXvFUw==} '@peculiar/asn1-android@2.6.0': resolution: {integrity: sha512-cBRCKtYPF7vJGN76/yG8VbxRcHLPF3HnkoHhKOZeHpoVtbMYfY9ROKtH3DtYUY9m8uI1Mh47PRhHf2hSK3xcSQ==} @@ -844,40 +814,29 @@ packages: '@polinetwork/backend@0.17.0': resolution: {integrity: sha512-NfU0i4It86LOMsZ5xyOX8ccOcbazwsC8j/D/B4sBb9PaJjENAdyFS27l9I4i0ihM2MrcFBJixxDdmnPO7/D/Rg==} - '@radix-ui/number@1.1.1': - resolution: {integrity: sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==} - - '@radix-ui/primitive@1.1.3': - resolution: {integrity: sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==} + '@radix-ui/primitive@1.1.6': + resolution: {integrity: sha512-w9hl+724uYEgCGR3bhuRepjBtrNB/6gkhCnAf58Ke+SLbHPPQqVZZB59z60roB+5H+nh3nWTcdJhQdFMEydWmw==} - '@radix-ui/react-accessible-icon@1.1.7': - resolution: {integrity: sha512-XM+E4WXl0OqUJFovy6GjmxxFyx9opfCAIUku4dlKRd5YEPqt4kALOkQOp0Of6reHuUkJuiPBEc5k0o4z4lTC8A==} + '@radix-ui/react-compose-refs@1.1.3': + resolution: {integrity: sha512-rYOP8OMnuuPMQF1uhPVlGNcCDlkokKqGFE3JcxFViIkAXP7EvFWUliJAstrapypaBLJNHbZL6jGhbVDGTwmVhA==} 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 - '@radix-ui/react-accordion@1.2.12': - resolution: {integrity: sha512-T4nygeh9YE9dLRPhAHSeOZi7HBXo+0kYIPJXayZfvWOWA0+n3dESrZbjfDPUABkUNym6Hd+f2IR113To8D2GPA==} + '@radix-ui/react-context@1.2.0': + resolution: {integrity: sha512-fOE+JtN9rygNZkCnHRBEP0TAvLldlhyOxMsbwFvTP4nAs+nBmfnna+o/Zski2wkmY1YMrFC0aSzsHoLY47iLrg==} 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 - '@radix-ui/react-alert-dialog@1.1.15': - resolution: {integrity: sha512-oTVLkEw5GpdRe29BqJ0LSDFWI3qu0vR1M0mUkOQWDIUnY/QIkLpgDMWuKxP94c2NAC2LGcgVhG1ImF3jkZ5wXw==} + '@radix-ui/react-dialog@1.1.20': + resolution: {integrity: sha512-cngVJcvK0yMvR7wICJpv+1uW3Qw4T7QM5sdbb+oE/lxOdTdvF00oaRpWUjVgmjyXe3J+xh7eZyXZlVF3g2g59g==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -889,8 +848,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-arrow@1.1.7': - resolution: {integrity: sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==} + '@radix-ui/react-dismissable-layer@1.1.16': + resolution: {integrity: sha512-t45h68IjFx0ccBnPJqk0X6ecv69LkCFWd6DNCFQX56mUnVEXZbNOLCH/u9fHlAjFZ1RrFdl8/m4zev7B7NyhXQ==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -902,21 +861,17 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-aspect-ratio@1.1.7': - resolution: {integrity: sha512-Yq6lvO9HQyPwev1onK1daHCHqXVLzPhSVjmsNjCa2Zcxy2f7uJD2itDtxknv6FzAKCwD1qQkeVDmX/cev13n/g==} + '@radix-ui/react-focus-guards@1.1.4': + resolution: {integrity: sha512-cot/aB/mOm0IYVYTTmQcEEK1M48lZWi8FlYe5nDPQQ8NYZUlXEFgncJ9p2Kzer3RKSrY7cTTpEMLZKNo9QoP5Q==} 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 - '@radix-ui/react-avatar@1.1.10': - resolution: {integrity: sha512-V8piFfWapM5OmNCXTzVQY+E1rDa53zY+MQ4Y7356v4fFz6vqCyUtIz2rUD44ZEdwg78/jKmMJHj07+C/Z/rcog==} + '@radix-ui/react-focus-scope@1.1.13': + resolution: {integrity: sha512-dE04aPEuP9rvKKT0d0KjSOtTEYNg6bmCYFsoSJpfC+y91Hic28ZfDCGgv6aJ+2Kw/LBXYipMZpyqVj/OD3Z8Gg==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -928,21 +883,17 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-checkbox@1.3.3': - resolution: {integrity: sha512-wBbpv+NQftHDdG86Qc0pIyXk5IR3tM8Vd0nWLKDcX8nNn4nXFOFwsKuqw2okA/1D/mpaAkmuyndrPJTYDNZtFw==} + '@radix-ui/react-id@1.1.2': + resolution: {integrity: sha512-orBC88futVpqCmhX1p4cvquNHsELQ+w+vBJnuj3ftETI5bJb0bZn3Tqu3SWN2IOcPycTnMGnhwoermvISt72sA==} 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 - '@radix-ui/react-collapsible@1.1.12': - resolution: {integrity: sha512-Uu+mSh4agx2ib1uIGPP4/CKNULyajb3p92LsVXmH2EHVMTfZWpll88XJ0j4W0z3f8NK1eYl1+Mf/szHPmcHzyA==} + '@radix-ui/react-portal@1.1.14': + resolution: {integrity: sha512-REwjAGPMa3J9oyDE4cuWkZbwnCbbyky66NurquQklXMSDn67cl6oGFx2gO7KZhPtFNbNw9xTWNrti3VIhgluYw==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -954,8 +905,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-collection@1.1.7': - resolution: {integrity: sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==} + '@radix-ui/react-presence@1.1.8': + resolution: {integrity: sha512-0hhyrQdXMaATgq4ammLG9+iPqsXxzZkgTSIxdrJHdfLnXO4Uo5L7BoO3/Xf0AEaettadGZWGGJMw6ujzQvIpGA==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -967,26 +918,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-compose-refs@1.1.1': - resolution: {integrity: sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-compose-refs@1.1.2': - resolution: {integrity: sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-context-menu@2.2.16': - resolution: {integrity: sha512-O8morBEW+HsVG28gYDZPTrT9UUovQUlJue5YO836tiTJhuIWBm/zQHc7j388sHWtdH/xUZurK9olD2+pcqx5ww==} + '@radix-ui/react-primitive@2.1.7': + resolution: {integrity: sha512-bC3NiwsprbxKjuon9l7X6BUTw7FPVzEYaL92MPEY5SCd/9hUTPXVFtVwRix7778wtRsVao+zE062gL79FZleeQ==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -998,8 +931,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-context@1.1.2': - resolution: {integrity: sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==} + '@radix-ui/react-slot@1.3.0': + resolution: {integrity: sha512-MojKku4U/miO8Av4Dkb+ctMAQx7JmY96LmtDQlAarCRtd7rN52QCSzBF+XAvr5S6coSVj9HEPBgHAHKEJVk/WA==} peerDependencies: '@types/react': '*' react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc @@ -1007,21 +940,17 @@ packages: '@types/react': optional: true - '@radix-ui/react-dialog@1.1.15': - resolution: {integrity: sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw==} + '@radix-ui/react-use-callback-ref@1.1.2': + resolution: {integrity: sha512-xCso9j1/u8sEgP1RNHjFrXJLApL8LiqOkI1R4ywuN00rxWdYg4oQXuwKLS3i0j5NWLromUD27/4nlxj2UFVvIw==} 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 - '@radix-ui/react-direction@1.1.1': - resolution: {integrity: sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==} + '@radix-ui/react-use-controllable-state@1.2.4': + resolution: {integrity: sha512-cx2DixxmSfjCcEoRvDvy1NLd6SWK94XFcEEOZUcharUlXbmahFQGKCfwdKZL2ub34iIwOPOEFVF80xb+yfLYiA==} peerDependencies: '@types/react': '*' react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc @@ -1029,756 +958,399 @@ packages: '@types/react': optional: true - '@radix-ui/react-dismissable-layer@1.1.11': - resolution: {integrity: sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==} + '@radix-ui/react-use-effect-event@0.0.3': + resolution: {integrity: sha512-6c8ZqvPTWILEKnyVkP53EGRCcpnJiKTC21sS/6R1GF5xKyHJJWQEPfkqlcgUkdRQivd6tb23abUwe4ngWmY0JA==} 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 - '@radix-ui/react-dropdown-menu@2.1.16': - resolution: {integrity: sha512-1PLGQEynI/3OX/ftV54COn+3Sud/Mn8vALg2rWnBLnRaGtJDduNW/22XjlGgPdpcIbiQxjKtb7BkcjP00nqfJw==} + '@radix-ui/react-use-layout-effect@1.1.2': + resolution: {integrity: sha512-jrBWOxZITuGcnjRCM2t2U5ZPkCLxD+Ym6DjfssS5haTj2iiak/DOb64JeN6OdLfLgptb6/e2kKR+ZuTrGoZTPA==} 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 - '@radix-ui/react-focus-guards@1.1.3': - resolution: {integrity: sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true + '@rolldown/binding-android-arm64@1.1.5': + resolution: {integrity: sha512-lZg8fqIv2v7FF237bwMgzGZEJvGL79/s5knJ/i6FmsGF4XXlzccZ4jb+TrFIxtSSxFtIpdsgrPZeMk1I9AFcyQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] - '@radix-ui/react-focus-scope@1.1.7': - resolution: {integrity: sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==} - 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 + '@rolldown/binding-darwin-arm64@1.1.5': + resolution: {integrity: sha512-51Bnx9pNiMRKSUNtBfySkNJ9vMU9Hh3I1ozDd6gyPPYzaXCfnptUcEZxXGYFn+ul2dtcMUiqGR1Yai2K10uoTw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] - '@radix-ui/react-form@0.1.8': - resolution: {integrity: sha512-QM70k4Zwjttifr5a4sZFts9fn8FzHYvQ5PiB19O2HsYibaHSVt9fH9rzB0XZo/YcM+b7t/p7lYCT/F5eOeF5yQ==} - 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 + '@rolldown/binding-darwin-x64@1.1.5': + resolution: {integrity: sha512-Tm+gbfC0aHu1tBA/JvKQh32S0K6YgCHkiAF4/W6xX0K0RmNuc94VeK419dJoE65R5aRxmo+noZQSWrAMF6yb6g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] - '@radix-ui/react-hover-card@1.1.15': - resolution: {integrity: sha512-qgTkjNT1CfKMoP0rcasmlH2r1DAiYicWsDsufxl940sT2wHNEWWv6FMWIQXWhVdmC1d/HYfbhQx60KYyAtKxjg==} - 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 + '@rolldown/binding-freebsd-x64@1.1.5': + resolution: {integrity: sha512-JMzDKCCXq93YccG5gz3hvOs1oXRKAf0XYpfOS88e+wZrC8Iugj6j68867vrYZkvpDDpKn/KoKORThmchMpF6TA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] - '@radix-ui/react-id@1.1.0': - resolution: {integrity: sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true + '@rolldown/binding-linux-arm-gnueabihf@1.1.5': + resolution: {integrity: sha512-uML21j2K5TfPGutKxub+M+nLjZIrWjXQ5Grx4lCe/nimTj9B4L63zHpjXLl4y0L3mcm2htEQIb06oCG/szerNw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] - '@radix-ui/react-id@1.1.1': - resolution: {integrity: sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true + '@rolldown/binding-linux-arm64-gnu@1.1.5': + resolution: {integrity: sha512-navSiuTMogvnQoZoM/v+l3ZWo50/NTwSHSzheABx/RCnmUPaKwq9qSo4Br2OYRs21+Fz8uFqITZM3H4opOB0/Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] - '@radix-ui/react-label@2.1.7': - resolution: {integrity: sha512-YT1GqPSL8kJn20djelMX7/cTRp/Y9w5IZHvfxQTVHrOqa2yMl7i/UfMqKRU5V7mEyKTrUVgJXhNQPVCG8PBLoQ==} - 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 + '@rolldown/binding-linux-arm64-musl@1.1.5': + resolution: {integrity: sha512-lAryqH7IteztmCXQXk0etKj4wBQ7Gx5S6LjKhsgp9zb8I5bsuvU/2llH1hDQcjsFeqIsovMVN339/8pUDDBXxA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + + '@rolldown/binding-linux-ppc64-gnu@1.1.5': + resolution: {integrity: sha512-fsK/sNBnxzBlL4O1JNrZakVQxPspqpED5dLtNsZS9oOKmtSpdNIzxH2kkol5HYTWJN47sE20ztMJPxfZ89qGOg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + + '@rolldown/binding-linux-s390x-gnu@1.1.5': + resolution: {integrity: sha512-gLYb4BIadlfTOYT5gO503n8zQjXflgzpD0FcyKh0Mzx3rqCZKnHoJWV9xe1KXUJ5lx2JfcSHr/mhzS0PC/McAA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] - '@radix-ui/react-menu@2.1.16': - resolution: {integrity: sha512-72F2T+PLlphrqLcAotYPp0uJMr5SjP5SL01wfEspJbru5Zs5vQaSHb4VB3ZMJPimgHHCHG7gMOeOB9H3Hdmtxg==} + '@rolldown/binding-linux-x64-gnu@1.1.5': + resolution: {integrity: sha512-FjcpEKUyJygHgs1o50VYNvkt5+7Le/VEdYt0AkRpkL33MnyQfwr8l5mXwMmfmTbyMPr5vJLC+8/Gd9gXnwU1QQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + + '@rolldown/binding-linux-x64-musl@1.1.5': + resolution: {integrity: sha512-Me+PfPI2TMeOQk0gYWfLQZtTktrmzbr8cDboqX83XKc7UrgAi55gF+2dUkWdxd19n55Essp2yeca+O9N5rBxHg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + + '@rolldown/binding-openharmony-arm64@1.1.5': + resolution: {integrity: sha512-yc5WrLzXks6zCQfn9Oxr8pORKyl/pF+QjHmW/Qx3qu0oyrrNC+y2JLTU1E2rcWYAmzlnqngWXHQjy51VzW70Vw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@rolldown/binding-wasm32-wasi@1.1.5': + resolution: {integrity: sha512-VbQGPX2b4r48TAMIM2cjgluIM1HYutm4pcTEJsle7iEP7sB1dFqtPLBVbdLAZCxy1txCcPxf4QFf4v8uvltPqA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [wasm32] + + '@rolldown/binding-win32-arm64-msvc@1.1.5': + resolution: {integrity: sha512-gHv82k63z4qpV5+Q1y/12KrK0ltWBukVDI8nZcbT7Tt/ZlOIVwppazneq0F93oDxTo3IgAMEDIoQh3E2n6mVsw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@rolldown/binding-win32-x64-msvc@1.1.5': + resolution: {integrity: sha512-tTZuDBPw85tEN5PQi1pnEBzDy0Z49HtScLAbD5t6hyeU92A95pRWaSMw1GZZi/RwgSgUIl0xrSlXIT/9QzvYSA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@rolldown/pluginutils@1.0.1': + resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==} + + '@sec-ant/readable-stream@0.4.1': + resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==} + + '@simplewebauthn/browser@13.2.2': + resolution: {integrity: sha512-FNW1oLQpTJyqG5kkDg5ZsotvWgmBaC6jCHR7Ej0qUNep36Wl9tj2eZu7J5rP+uhXgHaLk+QQ3lqcw2vS5MX1IA==} + + '@simplewebauthn/server@13.3.0': + resolution: {integrity: sha512-MLHYFrYG8/wK2i+86XMhiecK72nMaHKKt4bo+7Q1TbuG9iGjlSdfkPWKO5ZFE/BX+ygCJ7pr8H/AJeyAj1EaTQ==} + engines: {node: '>=20.0.0'} + + '@sindresorhus/merge-streams@4.0.0': + resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} + engines: {node: '>=18'} + + '@standard-schema/spec@1.1.0': + resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} + + '@swc/helpers@0.5.15': + resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} + + '@t3-oss/env-core@0.13.11': + resolution: {integrity: sha512-sM7GYY+KL7H/Hl0BE0inWfk3nRHZOLhmVn7sHGxaZt9FAR6KqREXAE+6TqKfiavfXmpRxO/OZ2QgKRd+oiBYRQ==} 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 + arktype: ^2.1.0 + typescript: '>=5.0.0' + valibot: ^1.0.0-beta.7 || ^1.0.0 + zod: ^3.24.0 || ^4.0.0 peerDependenciesMeta: - '@types/react': + arktype: optional: true - '@types/react-dom': + typescript: optional: true - - '@radix-ui/react-menubar@1.1.16': - resolution: {integrity: sha512-EB1FktTz5xRRi2Er974AUQZWg2yVBb1yjip38/lgwtCVRd3a+maUoGHN/xs9Yv8SY8QwbSEb+YrxGadVWbEutA==} - 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': + valibot: optional: true - '@types/react-dom': + zod: optional: true - '@radix-ui/react-navigation-menu@1.2.14': - resolution: {integrity: sha512-YB9mTFQvCOAQMHU+C/jVl96WmuWeltyUEpRJJky51huhds5W2FQr1J8D/16sQlf0ozxkPK8uF3niQMdUwZPv5w==} - 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 - - '@radix-ui/react-one-time-password-field@0.1.8': - resolution: {integrity: sha512-ycS4rbwURavDPVjCb5iS3aG4lURFDILi6sKI/WITUMZ13gMmn/xGjpLoqBAalhJaDk8I3UbCM5GzKHrnzwHbvg==} - 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 - - '@radix-ui/react-password-toggle-field@0.1.3': - resolution: {integrity: sha512-/UuCrDBWravcaMix4TdT+qlNdVwOM1Nck9kWx/vafXsdfj1ChfhOdfi3cy9SGBpWgTXwYCuboT/oYpJy3clqfw==} - 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 + '@tailwindcss/node@4.3.2': + resolution: {integrity: sha512-yWP/sqEcBLaD8JuA6zNwxoYKr75qxTioYwlRwekj5Jr/I5GXnoJfjetH/psLUIv74cYTH2lBUEzBkinthoYcBg==} - '@radix-ui/react-popover@1.1.15': - resolution: {integrity: sha512-kr0X2+6Yy/vJzLYJUPCZEc8SfQcf+1COFoAqauJm74umQhta9M7lNJHP7QQS3vkvcGLQUbWpMzwrXYwrYztHKA==} - 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 - - '@radix-ui/react-popper@1.2.8': - resolution: {integrity: sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw==} - 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 - - '@radix-ui/react-portal@1.1.9': - resolution: {integrity: sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==} - 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 - - '@radix-ui/react-presence@1.1.5': - resolution: {integrity: sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==} - 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 - - '@radix-ui/react-primitive@2.0.2': - resolution: {integrity: sha512-Ec/0d38EIuvDF+GZjcMU/Ze6MxntVJYO/fRlCPhCaVUyPY9WTalHJw54tp9sXeJo3tlShWpy41vQRgLRGOuz+w==} - 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 - - '@radix-ui/react-primitive@2.1.3': - resolution: {integrity: sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==} - 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 - - '@radix-ui/react-progress@1.1.7': - resolution: {integrity: sha512-vPdg/tF6YC/ynuBIJlk1mm7Le0VgW6ub6J2UWnTQ7/D23KXcPI1qy+0vBkgKgd38RCMJavBXpB83HPNFMTb0Fg==} - 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 + '@tailwindcss/oxide-android-arm64@4.3.2': + resolution: {integrity: sha512-WHxqIuHpvZ5VtdX6GTl1Ik/Vp2YuN42Et+0CdeaVd/frQ9jAvGmvR8vLT+jk3e8/Q3x8kECB9+R17pgpp2BulA==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [android] - '@radix-ui/react-radio-group@1.3.8': - resolution: {integrity: sha512-VBKYIYImA5zsxACdisNQ3BjCBfmbGH3kQlnFVqlWU4tXwjy7cGX8ta80BcrO+WJXIn5iBylEH3K6ZTlee//lgQ==} - 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 + '@tailwindcss/oxide-darwin-arm64@4.3.2': + resolution: {integrity: sha512-GZypeUY/IDJW3877KeM+O67vbXr3MBnbtEL4aYhNErv/JWZhye2vGSWWG9tB6iiqR2MqRNkY8IOUy4NdSZV26w==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [darwin] - '@radix-ui/react-roving-focus@1.1.11': - resolution: {integrity: sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA==} - 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 + '@tailwindcss/oxide-darwin-x64@4.3.2': + resolution: {integrity: sha512-UIIzmefR6KO1sDU7MzRqAxC8iBpft/VhkGjTjnhoS6k7Z3rQ9wEgA1ODSiyH/tcSYssulNm4Ci3hOeK1jH7ccQ==} + engines: {node: '>= 20'} + cpu: [x64] + os: [darwin] - '@radix-ui/react-scroll-area@1.2.10': - resolution: {integrity: sha512-tAXIa1g3sM5CGpVT0uIbUx/U3Gs5N8T52IICuCtObaos1S8fzsrPXG5WObkQN3S6NVl6wKgPhAIiBGbWnvc97A==} - 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 + '@tailwindcss/oxide-freebsd-x64@4.3.2': + resolution: {integrity: sha512-GN+uAmcI6DNspnCDwtOAZrTz6oukJnp337qZvxqCGLd3BHBzJpO0ZbTLRvJNdztOeAmTzewewGIMPb0tk2R4WA==} + engines: {node: '>= 20'} + cpu: [x64] + os: [freebsd] - '@radix-ui/react-select@2.2.6': - resolution: {integrity: sha512-I30RydO+bnn2PQztvo25tswPH+wFBjehVGtmagkU78yMdwTwVf12wnAOF+AeP8S2N8xD+5UPbGhkUfPyvT+mwQ==} - 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 + '@tailwindcss/oxide-linux-arm-gnueabihf@4.3.2': + resolution: {integrity: sha512-4ABn7qSbdHRwTiDiuWNegCyb5+2FJ4vKIKc3DmKrvAFw7MU1Lm11dIkTPwUaFdTzc7IsOpDbqBrlh0x6y36U/w==} + engines: {node: '>= 20'} + cpu: [arm] + os: [linux] - '@radix-ui/react-separator@1.1.7': - resolution: {integrity: sha512-0HEb8R9E8A+jZjvmFCy/J4xhbXy3TV+9XSnGJ3KvTtjlIUy/YQ/p6UYZvi7YbeoeXdyU9+Y3scizK6hkY37baA==} - 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 + '@tailwindcss/oxide-linux-arm64-gnu@4.3.2': + resolution: {integrity: sha512-wDgEIGwoM8w8pufh9LVt1PahDgNdKXrLC2qfAnV3vAmococ9RWbxeAw4pxPttd/TsJfwjyLf90Dg1y9y8I6Emw==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [linux] - '@radix-ui/react-slider@1.3.6': - resolution: {integrity: sha512-JPYb1GuM1bxfjMRlNLE+BcmBC8onfCi60Blk7OBqi2MLTFdS+8401U4uFjnwkOr49BLmXxLC6JHkvAsx5OJvHw==} - 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 + '@tailwindcss/oxide-linux-arm64-musl@4.3.2': + resolution: {integrity: sha512-J5Nuk0uZQIiMTJj3LEx4sAA9tMFUoXQZFv1J6An+QGYe53HKRJuFDi0rpq/tuouCZeAbOBY3kQ6g8qeD4TUjtA==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [linux] - '@radix-ui/react-slot@1.1.2': - resolution: {integrity: sha512-YAKxaiGsSQJ38VzKH86/BPRC4rh+b1Jpa+JneA5LRE7skmLPNAyeG8kPJj/oo4STLvlrs8vkf/iYyc3A5stYCQ==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true + '@tailwindcss/oxide-linux-x64-gnu@4.3.2': + resolution: {integrity: sha512-kqCZpSKOBEJO4mz7OqWoofBZeXTAwaVGPj0ErAj7CojmhKpWVWVOnrt9dE8odoIraZq4oj3ausM37kXi+Tow8w==} + engines: {node: '>= 20'} + cpu: [x64] + os: [linux] - '@radix-ui/react-slot@1.2.3': - resolution: {integrity: sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true + '@tailwindcss/oxide-linux-x64-musl@4.3.2': + resolution: {integrity: sha512-cixpqbh2toJDmkuCRI68nXA8ZxNmdK9Y+9v5h3MC3ZQKy/0BO8AWzlkWyRM7JAFSGBlfig4YVTPsK6MVgqz1uw==} + engines: {node: '>= 20'} + cpu: [x64] + os: [linux] - '@radix-ui/react-switch@1.2.6': - resolution: {integrity: sha512-bByzr1+ep1zk4VubeEVViV592vu2lHE2BZY5OnzehZqOOgogN80+mNtCqPkhn2gklJqOpxWgPoYTSnhBCqpOXQ==} - 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 + '@tailwindcss/oxide-wasm32-wasi@4.3.2': + resolution: {integrity: sha512-4ec2Z/LOmRsAgU23CS4xeJfcJlmRg94A/XrbGRCF1gyU/zdDfRLYDVsS+ynSZCmGNxQ1jQriQOKMQeQxBA3Isw==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + bundledDependencies: + - '@napi-rs/wasm-runtime' + - '@emnapi/core' + - '@emnapi/runtime' + - '@tybys/wasm-util' + - '@emnapi/wasi-threads' + - tslib - '@radix-ui/react-tabs@1.1.13': - resolution: {integrity: sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A==} - 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 + '@tailwindcss/oxide-win32-arm64-msvc@4.3.2': + resolution: {integrity: sha512-Zyr/M0+XcYZu3bZrUytc7TXvrk0ftWfl8gN2MwekNDzhqhKRUucMPSeOzM0o0wH5AWOU49BsKRrfKxI2atCPMQ==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [win32] - '@radix-ui/react-toast@1.2.15': - resolution: {integrity: sha512-3OSz3TacUWy4WtOXV38DggwxoqJK4+eDkNMl5Z/MJZaoUPaP4/9lf81xXMe1I2ReTAptverZUpbPY4wWwWyL5g==} - 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 + '@tailwindcss/oxide-win32-x64-msvc@4.3.2': + resolution: {integrity: sha512-QI9BO7KlNZsp2GuO0jwAAj5jCDABOKXRkCk2XuKTSaNEFSdfzqswYVTtCHBNKHLsqyjFyFkqlDiwkNbTYSssMQ==} + engines: {node: '>= 20'} + cpu: [x64] + os: [win32] - '@radix-ui/react-toggle-group@1.1.11': - resolution: {integrity: sha512-5umnS0T8JQzQT6HbPyO7Hh9dgd82NmS36DQr+X/YJ9ctFNCiiQd6IJAYYZ33LUwm8M+taCz5t2ui29fHZc4Y6Q==} - 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 + '@tailwindcss/oxide@4.3.2': + resolution: {integrity: sha512-z8ZgnzX8gdNoWLBLqBPoh/sjnxkwvf9ZuWjnO0l0yIzbLa5/9S+eC5QxGZKRobVHIC3/1BoMWjHblqWjcgFgag==} + engines: {node: '>= 20'} - '@radix-ui/react-toggle@1.1.10': - resolution: {integrity: sha512-lS1odchhFTeZv3xwHH31YPObmJn8gOg7Lq12inrr0+BH/l3Tsq32VfjqH1oh80ARM3mlkfMic15n0kg4sD1poQ==} + '@tailwindcss/vite@4.3.2': + resolution: {integrity: sha512-eHpMeX4JXfVNJDEcsouTeCBubJBTcTLigeaw/NTUW6PB5ATKKXdyonnXgTBX2VuRbjz1hjfz6C5XAhr52ImQXA==} 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 + vite: ^5.2.0 || ^6 || ^7 || ^8 - '@radix-ui/react-toolbar@1.1.11': - resolution: {integrity: sha512-4ol06/1bLoFu1nwUqzdD4Y5RZ9oDdKeiHIsntug54Hcr1pgaHiPqHFEaXI1IFP/EsOfROQZ8Mig9VTIRza6Tjg==} - 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 + '@tanstack/history@1.162.0': + resolution: {integrity: sha512-79pf/RkhteYZTRgcR4F9kbk84P2N8rugQJswxfIqovlbRiT3yI7eBE+5QorIrZaOKktsgzRlXh1l/du/xpl4iA==} + engines: {node: '>=20.19'} - '@radix-ui/react-tooltip@1.2.8': - resolution: {integrity: sha512-tY7sVt1yL9ozIxvmbtN5qtmH2krXcBCfjEiCgKGLqunJHvgvZG2Pcl2oQ3kbcZARb1BGEHdkLzcYGO8ynVlieg==} + '@tanstack/react-router@1.170.17': + resolution: {integrity: sha512-ppLkjCfSMaeug9rmFRYzOd4TIqWV+yTE7tzIny7alJsSnM7w4lzEZm6eqCehG0SPetpZ0R3K+UnanSmBgOAVcQ==} + engines: {node: '>=20.19'} 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 + react: '>=18.0.0 || >=19.0.0' + react-dom: '>=18.0.0 || >=19.0.0' - '@radix-ui/react-use-callback-ref@1.1.1': - resolution: {integrity: sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==} + '@tanstack/react-start-client@1.168.15': + resolution: {integrity: sha512-pW50PHvadgi50iNCw6deUOvqc9rzs30SstyFZY2tcS9z1XlqTlELSvGowjxdu2m0ymtqm1emj1jau1iP7+3+PQ==} + engines: {node: '>=22.12.0'} peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true + react: '>=18.0.0 || >=19.0.0' + react-dom: '>=18.0.0 || >=19.0.0' - '@radix-ui/react-use-controllable-state@1.2.2': - resolution: {integrity: sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==} + '@tanstack/react-start-rsc@0.1.26': + resolution: {integrity: sha512-+FMm3qtT1gWsl0i5sG/Q70mh1k7tzZUsPBaqbg4v34zVJZ+XGn1mJb34x2w7z1M0/e7co6GkZfV8BRpczrs8UA==} + engines: {node: '>=22.12.0'} peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + '@rspack/core': '>=2.0.0-0' + '@vitejs/plugin-rsc': '>=0.5.20' + react: '>=18.0.0 || >=19.0.0' + react-dom: '>=18.0.0 || >=19.0.0' + react-server-dom-rspack: '>=0.0.2' peerDependenciesMeta: - '@types/react': + '@rspack/core': optional: true - - '@radix-ui/react-use-effect-event@0.0.2': - resolution: {integrity: sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': + '@vitejs/plugin-rsc': optional: true - - '@radix-ui/react-use-escape-keydown@1.1.1': - resolution: {integrity: sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': + react-server-dom-rspack: optional: true - '@radix-ui/react-use-is-hydrated@0.1.0': - resolution: {integrity: sha512-U+UORVEq+cTnRIaostJv9AGdV3G6Y+zbVd+12e18jQ5A3c0xL03IhnHuiU4UV69wolOQp5GfR58NW/EgdQhwOA==} + '@tanstack/react-start-server@1.167.21': + resolution: {integrity: sha512-puJ7eFxaLuDzeM/tiLDJaXCA4uK+PZnEOoIC73zipsFqx865MGzrRS/GSZxeVxjavC5iHU+ZwC+rgI0qYSol1A==} + engines: {node: '>=22.12.0'} peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true + react: '>=18.0.0 || >=19.0.0' + react-dom: '>=18.0.0 || >=19.0.0' - '@radix-ui/react-use-layout-effect@1.1.0': - resolution: {integrity: sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==} + '@tanstack/react-start@1.168.27': + resolution: {integrity: sha512-rdGFDqfCW71gyofyAxaYxhelNKmeVjpmbpm0uFYbNHORCa///4aBxi7B7ecShibKv9O4GfJ66MPX5F0ozbm+ig==} + engines: {node: '>=22.12.0'} peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + '@rsbuild/core': ^2.0.0 + '@vitejs/plugin-rsc': '*' + react: '>=18.0.0 || >=19.0.0' + react-dom: '>=18.0.0 || >=19.0.0' + vite: '>=7.0.0' peerDependenciesMeta: - '@types/react': + '@rsbuild/core': optional: true - - '@radix-ui/react-use-layout-effect@1.1.1': - resolution: {integrity: sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': + '@vitejs/plugin-rsc': optional: true - - '@radix-ui/react-use-previous@1.1.1': - resolution: {integrity: sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': + vite: optional: true - '@radix-ui/react-use-rect@1.1.1': - resolution: {integrity: sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==} + '@tanstack/react-store@0.11.0': + resolution: {integrity: sha512-tX4YXh3PDkmpvGQWkWqKpzs/MSqbtuwY9dWdWhtV9Q50PmO+jOkUKIWIX4G85dwt7lxdHLXsiaEKPdKmC8F41w==} peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - '@radix-ui/react-use-size@1.1.1': - resolution: {integrity: sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==} + '@tanstack/react-store@0.9.3': + resolution: {integrity: sha512-y2iHd/N9OkoQbFJLUX1T9vbc2O9tjH0pQRgTcx1/Nz4IlwLvkgpuglXUx+mXt0g5ZDFrEeDnONPqkbfxXJKwRg==} peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - '@radix-ui/react-visually-hidden@1.2.3': - resolution: {integrity: sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug==} + '@tanstack/react-table@9.0.0-beta.38': + resolution: {integrity: sha512-FKBVI9SpHqj+Jf8bdxLUNajnfbl3iYt0bhUPAN93kHH2L/XxHF41JPQDKbpqQC40WejbfJEHj4RIUirf3OAmVA==} + engines: {node: '>=20'} 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 - - '@radix-ui/rect@1.1.1': - resolution: {integrity: sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==} - - '@sec-ant/readable-stream@0.4.1': - resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==} + react: '>=18' - '@simplewebauthn/browser@13.2.2': - resolution: {integrity: sha512-FNW1oLQpTJyqG5kkDg5ZsotvWgmBaC6jCHR7Ej0qUNep36Wl9tj2eZu7J5rP+uhXgHaLk+QQ3lqcw2vS5MX1IA==} - - '@simplewebauthn/server@13.3.0': - resolution: {integrity: sha512-MLHYFrYG8/wK2i+86XMhiecK72nMaHKKt4bo+7Q1TbuG9iGjlSdfkPWKO5ZFE/BX+ygCJ7pr8H/AJeyAj1EaTQ==} - engines: {node: '>=20.0.0'} - - '@sindresorhus/merge-streams@4.0.0': - resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} - engines: {node: '>=18'} - - '@standard-schema/spec@1.1.0': - resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} + '@tanstack/router-core@1.171.14': + resolution: {integrity: sha512-Mo3hwx0qB0cJsVYGDjG0+Ouf7VV74h/vsoDMGztdlyzDanp4gBA2s7IVvm6hFrmQM6GpD9F0Z7SqD7OldfLE7g==} + engines: {node: '>=20.19'} - '@swc/helpers@0.5.15': - resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} + '@tanstack/router-generator@1.167.18': + resolution: {integrity: sha512-kFvM4caRds9Q3EXg64bZubJ6rbDxyV0YDSBSGvOGzmKspQPdz5Xrh0uj5T1Ov8avUUg+c761u04VQAaEzSBXRw==} + engines: {node: '>=20.19'} - '@t3-oss/env-core@0.13.10': - resolution: {integrity: sha512-NNFfdlJ+HmPHkLi2HKy7nwuat9SIYOxei9K10lO2YlcSObDILY7mHZNSHsieIM3A0/5OOzw/P/b+yLvPdaG52g==} + '@tanstack/router-plugin@1.168.19': + resolution: {integrity: sha512-aFglwLc+bbPTgZlkXn3PvOwpjJAfgUyPGSuql4MP3XrqTTh6WkBiy2RYb6oaG5h0s7EKwivEuq85K3Y4V0Mt1g==} + engines: {node: '>=20.19'} peerDependencies: - arktype: ^2.1.0 - typescript: '>=5.0.0' - valibot: ^1.0.0-beta.7 || ^1.0.0 - zod: ^3.24.0 || ^4.0.0 + '@rsbuild/core': '>=1.0.2 || ^2.0.0' + '@tanstack/react-router': ^1.170.17 + vite: '>=5.0.0 || >=6.0.0 || >=7.0.0 || >=8.0.0' + vite-plugin-solid: ^2.11.10 || ^3.0.0-0 + webpack: '>=5.92.0' peerDependenciesMeta: - arktype: + '@rsbuild/core': optional: true - typescript: + '@tanstack/react-router': optional: true - valibot: + vite: optional: true - zod: + vite-plugin-solid: optional: true - - '@t3-oss/env-nextjs@0.13.10': - resolution: {integrity: sha512-JfSA2WXOnvcc/uMdp31paMsfbYhhdvLLRxlwvrnlPE9bwM/n0Z+Qb9xRv48nPpvfMhOrkrTYw1I5Yc06WIKBJQ==} - peerDependencies: - arktype: ^2.1.0 - typescript: '>=5.0.0' - valibot: ^1.0.0-beta.7 || ^1.0.0 - zod: ^3.24.0 || ^4.0.0 - peerDependenciesMeta: - arktype: + webpack: optional: true - typescript: - optional: true - valibot: - optional: true - zod: - optional: true - - '@tabby_ai/hijri-converter@1.0.5': - resolution: {integrity: sha512-r5bClKrcIusDoo049dSL8CawnHR6mRdDwhlQuIgZRNty68q0x8k3Lf1BtPAMxRf/GgnHBnIO4ujd3+GQdLWzxQ==} - engines: {node: '>=16.0.0'} - - '@tailwindcss/node@4.1.4': - resolution: {integrity: sha512-MT5118zaiO6x6hNA04OWInuAiP1YISXql8Z+/Y8iisV5nuhM8VXlyhRuqc2PEviPszcXI66W44bCIk500Oolhw==} - - '@tailwindcss/oxide-android-arm64@4.1.4': - resolution: {integrity: sha512-xMMAe/SaCN/vHfQYui3fqaBDEXMu22BVwQ33veLc8ep+DNy7CWN52L+TTG9y1K397w9nkzv+Mw+mZWISiqhmlA==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [android] - - '@tailwindcss/oxide-darwin-arm64@4.1.4': - resolution: {integrity: sha512-JGRj0SYFuDuAGilWFBlshcexev2hOKfNkoX+0QTksKYq2zgF9VY/vVMq9m8IObYnLna0Xlg+ytCi2FN2rOL0Sg==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [darwin] - - '@tailwindcss/oxide-darwin-x64@4.1.4': - resolution: {integrity: sha512-sdDeLNvs3cYeWsEJ4H1DvjOzaGios4QbBTNLVLVs0XQ0V95bffT3+scptzYGPMjm7xv4+qMhCDrkHwhnUySEzA==} - engines: {node: '>= 10'} - cpu: [x64] - os: [darwin] - - '@tailwindcss/oxide-freebsd-x64@4.1.4': - resolution: {integrity: sha512-VHxAqxqdghM83HslPhRsNhHo91McsxRJaEnShJOMu8mHmEj9Ig7ToHJtDukkuLWLzLboh2XSjq/0zO6wgvykNA==} - engines: {node: '>= 10'} - cpu: [x64] - os: [freebsd] - - '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.4': - resolution: {integrity: sha512-OTU/m/eV4gQKxy9r5acuesqaymyeSCnsx1cFto/I1WhPmi5HDxX1nkzb8KYBiwkHIGg7CTfo/AcGzoXAJBxLfg==} - engines: {node: '>= 10'} - cpu: [arm] - os: [linux] - - '@tailwindcss/oxide-linux-arm64-gnu@4.1.4': - resolution: {integrity: sha512-hKlLNvbmUC6z5g/J4H+Zx7f7w15whSVImokLPmP6ff1QqTVE+TxUM9PGuNsjHvkvlHUtGTdDnOvGNSEUiXI1Ww==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - - '@tailwindcss/oxide-linux-arm64-musl@4.1.4': - resolution: {integrity: sha512-X3As2xhtgPTY/m5edUtddmZ8rCruvBvtxYLMw9OsZdH01L2gS2icsHRwxdU0dMItNfVmrBezueXZCHxVeeb7Aw==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - - '@tailwindcss/oxide-linux-x64-gnu@4.1.4': - resolution: {integrity: sha512-2VG4DqhGaDSmYIu6C4ua2vSLXnJsb/C9liej7TuSO04NK+JJJgJucDUgmX6sn7Gw3Cs5ZJ9ZLrnI0QRDOjLfNQ==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - - '@tailwindcss/oxide-linux-x64-musl@4.1.4': - resolution: {integrity: sha512-v+mxVgH2kmur/X5Mdrz9m7TsoVjbdYQT0b4Z+dr+I4RvreCNXyCFELZL/DO0M1RsidZTrm6O1eMnV6zlgEzTMQ==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - - '@tailwindcss/oxide-wasm32-wasi@4.1.4': - resolution: {integrity: sha512-2TLe9ir+9esCf6Wm+lLWTMbgklIjiF0pbmDnwmhR9MksVOq+e8aP3TSsXySnBDDvTTVd/vKu1aNttEGj3P6l8Q==} - engines: {node: '>=14.0.0'} - cpu: [wasm32] - bundledDependencies: - - '@napi-rs/wasm-runtime' - - '@emnapi/core' - - '@emnapi/runtime' - - '@tybys/wasm-util' - - '@emnapi/wasi-threads' - - tslib - - '@tailwindcss/oxide-win32-arm64-msvc@4.1.4': - resolution: {integrity: sha512-VlnhfilPlO0ltxW9/BgfLI5547PYzqBMPIzRrk4W7uupgCt8z6Trw/tAj6QUtF2om+1MH281Pg+HHUJoLesmng==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [win32] - - '@tailwindcss/oxide-win32-x64-msvc@4.1.4': - resolution: {integrity: sha512-+7S63t5zhYjslUGb8NcgLpFXD+Kq1F/zt5Xv5qTv7HaFTG/DHyHD9GA6ieNAxhgyA4IcKa/zy7Xx4Oad2/wuhw==} - engines: {node: '>= 10'} - cpu: [x64] - os: [win32] - '@tailwindcss/oxide@4.1.4': - resolution: {integrity: sha512-p5wOpXyOJx7mKh5MXh5oKk+kqcz8T+bA3z/5VWWeQwFrmuBItGwz8Y2CHk/sJ+dNb9B0nYFfn0rj/cKHZyjahQ==} - engines: {node: '>= 10'} + '@tanstack/router-utils@1.162.2': + resolution: {integrity: sha512-hTWqJtqIFFdvuCl8WXNyrodp2L9zo2G37xKRrcVmVRWpAB2h+U1LuRAfS4tsFTiWOIoE/B+WDVFB8JpoEdw6jQ==} + engines: {node: '>=20.19'} - '@tailwindcss/postcss@4.1.4': - resolution: {integrity: sha512-bjV6sqycCEa+AQSt2Kr7wpGF1bOZJ5wsqnLEkqSbM/JEHxx/yhMH8wHmdkPyApF9xhHeMSwnnkDUUMMM/hYnXw==} + '@tanstack/start-client-core@1.170.13': + resolution: {integrity: sha512-o37M3msIK5ec87kPrIYJWXb1XPnjIe5/jrkGLXiXpFuVL99z7mhoBCzftKtVPtzqI8EElnRE/VGFYT9BHNnWcw==} + engines: {node: '>=22.12.0'} - '@tanstack/query-core@5.90.19': - resolution: {integrity: sha512-GLW5sjPVIvH491VV1ufddnfldyVB+teCnpPIvweEfkpRx7CfUmUGhoh9cdcUKBh/KwVxk22aNEDxeTsvmyB/WA==} + '@tanstack/start-fn-stubs@1.162.0': + resolution: {integrity: sha512-QWfUZ3Yo923tdQn38LyKMU8rcTw69zc+T4dAvgTWV4O56SqFRsGfS0lSWIMhJRwXIx/bvdi7nTUBDdZtTHtpTQ==} + engines: {node: '>=22.12.0'} - '@tanstack/react-query@5.90.19': - resolution: {integrity: sha512-qTZRZ4QyTzQc+M0IzrbKHxSeISUmRB3RPGmao5bT+sI6ayxSRhn0FXEnT5Hg3as8SBFcRosrXXRFB+yAcxVxJQ==} + '@tanstack/start-plugin-core@1.171.19': + resolution: {integrity: sha512-+fpW3Z/2vPT8HDV1c5p2WC6/g2k/AV/ujdJVDcn/VFd+gXRtzSX1D/LfozlaDbhDoEsqOnAk/mGwjg60JkUA2Q==} + engines: {node: '>=22.12.0'} peerDependencies: - react: ^18 || ^19 + '@rsbuild/core': ^2.0.0 + vite: '>=7.0.0' + peerDependenciesMeta: + '@rsbuild/core': + optional: true + vite: + optional: true - '@tanstack/react-table@8.21.2': - resolution: {integrity: sha512-11tNlEDTdIhMJba2RBH+ecJ9l1zgS2kjmexDPAraulc8jeNA4xocSNeyzextT0XJyASil4XsCYlJmf5jEWAtYg==} - engines: {node: '>=12'} - peerDependencies: - react: '>=16.8' - react-dom: '>=16.8' + '@tanstack/start-server-core@1.169.16': + resolution: {integrity: sha512-lvAjQpH3nHJtd4xy0iHIaWbsTbyN9EBxuYCxbtXH0EpeBQPg+TCPhu9GQC9WbbA1rE//s82CpE55oYDQMqkU5A==} + engines: {node: '>=22.12.0'} - '@tanstack/table-core@8.21.2': - resolution: {integrity: sha512-uvXk/U4cBiFMxt+p9/G7yUWI/UbHYbyghLCjlpWZ3mLeIZiUBSKcUnw9UnKkdRz7Z/N4UBuFLWQdJCjUe7HjvA==} - engines: {node: '>=12'} + '@tanstack/start-storage-context@1.167.16': + resolution: {integrity: sha512-zTegxlij4BC1DbCrC6rsVlMOQVMzOuG5IllacZEkrUdhiFwMIMYpk0VWGH+d0ucx5RBkmv8e8GNX3AOVBWclfg==} + engines: {node: '>=22.12.0'} - '@trpc/client@11.5.1': - resolution: {integrity: sha512-7I6JJ1I1lxv3S87ht3FAIZi0XxQa7hnQ9K+Oo5BH7cGO8ZtWe9Ftq6ItdkuDfpsnsRPcR2h158AMWbNs/iptqg==} - peerDependencies: - '@trpc/server': 11.5.1 - typescript: '>=5.7.2' + '@tanstack/store@0.11.0': + resolution: {integrity: sha512-WlzzCt3xi0G6pCAJu1U+2jiECwabETDpQDi3hfkFZvJii9AuZqEKbOiVarX1/bWhTNjU486yQtJCCasi/0q+Cw==} - '@trpc/next@11.5.1': - resolution: {integrity: sha512-MWb7Jqa0XYx0z2he7Eq7HSILc2z9oDqUtsbWz+S6LWCemewRSRzmG8UuoiZm+ICEoRa452RmqeQH1EYiPCWTUg==} - peerDependencies: - '@tanstack/react-query': ^5.59.15 - '@trpc/client': 11.5.1 - '@trpc/react-query': 11.5.1 - '@trpc/server': 11.5.1 - next: '*' - react: '>=16.8.0' - react-dom: '>=16.8.0' - typescript: '>=5.7.2' - peerDependenciesMeta: - '@tanstack/react-query': - optional: true - '@trpc/react-query': - optional: true + '@tanstack/store@0.9.3': + resolution: {integrity: sha512-8reSzl/qGWGGVKhBoxXPMWzATSbZLZFWhwBAFO9NAyp0TxzfBP0mIrGb8CP8KrQTmvzXlR/vFPPUrHTLBGyFyw==} - '@trpc/react-query@11.5.1': - resolution: {integrity: sha512-Y+e0Lp7na1LAjoYqtHVjxpfayOuvvnuchS723b4dsI/V0h3irBuI+bx38S3m7RgaIh/L1av1SldFrKIauk+r/A==} + '@tanstack/table-core@9.0.0-beta.38': + resolution: {integrity: sha512-Sr+jaFelc5CfkyYeVrPYYPL6PQJyP17p5WQHt+ip2vfKzxmhNLXD2mrI66wC8sNYfrhuWt6a5fMiSr4W3dXMDg==} + engines: {node: '>=20'} + + '@tanstack/virtual-file-routes@1.162.0': + resolution: {integrity: sha512-uhOeFyxLcU41HzvrxsGpiWdcMbScY1EDgbZ5K7DVRMYInbLYWAC0EA/kx9wXAoSM8q82bUG2hRl8+EAjE6XAbA==} + engines: {node: '>=20.19'} + + '@trpc/client@11.5.1': + resolution: {integrity: sha512-7I6JJ1I1lxv3S87ht3FAIZi0XxQa7hnQ9K+Oo5BH7cGO8ZtWe9Ftq6ItdkuDfpsnsRPcR2h158AMWbNs/iptqg==} peerDependencies: - '@tanstack/react-query': ^5.80.3 - '@trpc/client': 11.5.1 '@trpc/server': 11.5.1 - react: '>=18.2.0' - react-dom: '>=18.2.0' typescript: '>=5.7.2' '@trpc/server@11.5.1': @@ -1789,25 +1361,19 @@ packages: '@ts-morph/common@0.27.0': resolution: {integrity: sha512-Wf29UqxWDpc+i61k3oIOzcUfQt79PIT9y/MWfAGlrkjg6lBC1hwDECLXPVJAhWjiGbfBCxZd65F/LIZF3+jeJQ==} - '@types/node@20.17.19': - resolution: {integrity: sha512-LEwC7o1ifqg/6r2gn9Dns0f1rhK+fPFDoMiceTJ6kWmVk6bgXBI/9IOWfVan4WiAavK9pIVWdX0/e3J+eEUh5A==} - - '@types/prismjs@1.26.5': - resolution: {integrity: sha512-AUZTa7hQ2KY5L7AmtSiqxlhWxb4ina0yd8hNbl4TWuqnv/pFP0nDMb3YrfSBf4hJVGLh2YEIBfKaBW/9UEl6IQ==} + '@tybys/wasm-util@0.10.3': + resolution: {integrity: sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==} - '@types/prop-types@15.7.14': - resolution: {integrity: sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==} + '@types/node@22.20.1': + resolution: {integrity: sha512-EANqOCF9QFyra+4pfxUcX9STKJpCLjMbObVzljIJomAWSnuSIEAvyzEU53GaajbXJEgdh0iEcPL+DGvpUd4k1Q==} - '@types/react-dom@18.3.5': - resolution: {integrity: sha512-P4t6saawp+b/dFrUr2cvkVsfvPguwsxtH6dNIYRllMsefqFzkZk5UIjzyDOv5g1dXIPdG4Sp1yCR4Z6RCUsG/Q==} + '@types/react-dom@19.2.3': + resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==} peerDependencies: - '@types/react': ^18.0.0 + '@types/react': ^19.2.0 - '@types/react@18.3.18': - resolution: {integrity: sha512-t4yC+vtgnkYjNSKlFx1jkAhH8LgTo2N/7Qvi83kdEaUtMDiwpbLAktKDaAMlRcJ5eSxZkH74eEGt1ky31d7kfQ==} - - '@types/statuses@2.0.6': - resolution: {integrity: sha512-xMAgYwceFhRA2zY+XbEA7mxYbA093wdiW8Vu6gZPGWy9cmOyU9XesH1tNcEWsKFd5Vzrqx5T3D38PWx1FIIXkA==} + '@types/react@19.2.17': + resolution: {integrity: sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==} '@types/validate-npm-package-name@4.0.2': resolution: {integrity: sha512-lrpDziQipxCEeK5kWxvljWYhUvOiB2A9izZd9B2AFarYAkqZshb4lPbRs7zKEic6eGtH8V/2qJW+dPp9OtF6bw==} @@ -1818,13 +1384,30 @@ packages: '@types/whatwg-url@13.0.0': resolution: {integrity: sha512-N8WXpbE6Wgri7KUSvrmQcqrMllKZ9uxkYWMt+mCSGwNc0Hsw9VQTW7ApqI4XNrx6/SaM2QQJCzMPDEXE058s+Q==} + '@vitejs/plugin-react@6.0.3': + resolution: {integrity: sha512-vmFvco5/QuC2f9Oj+wTk0+9XeDFkHxSamwZKYc7MxYwKICfvUvlMhqKI0VuICPltGqh1neqBKDvO4kes1ya8vg==} + engines: {node: ^20.19.0 || >=22.12.0} + peerDependencies: + '@rolldown/plugin-babel': ^0.1.7 || ^0.2.0 + babel-plugin-react-compiler: ^1.0.0 + vite: ^8.0.0 + peerDependenciesMeta: + '@rolldown/plugin-babel': + optional: true + babel-plugin-react-compiler: + optional: true + accepts@2.0.0: resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} engines: {node: '>= 0.6'} - agent-base@7.1.4: - resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} - engines: {node: '>= 14'} + ajv-formats@2.1.1: + resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true ajv-formats@3.0.1: resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==} @@ -1834,8 +1417,12 @@ packages: ajv: optional: true - ajv@8.18.0: - resolution: {integrity: sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==} + ajv@8.20.0: + resolution: {integrity: sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==} + + ansi-colors@4.1.3: + resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} + engines: {node: '>=6'} ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} @@ -1845,15 +1432,15 @@ packages: resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} engines: {node: '>=12'} - ansi-styles@4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} + ansis@4.3.1: + resolution: {integrity: sha512-BJ8/l4R5LRE7hW9WdSuGYrLSHi2ynxeFpDFbH0K/CgNeY/tyhk+vO6TYxXC5r5CpUhNVX310xzPsN/H9lCdfOA==} + engines: {node: '>=14'} argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - aria-hidden@1.2.4: - resolution: {integrity: sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==} + aria-hidden@1.2.6: + resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==} engines: {node: '>=10'} asn1js@3.0.7: @@ -1864,6 +1451,13 @@ packages: resolution: {integrity: sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==} engines: {node: '>=4'} + atomically@1.7.0: + resolution: {integrity: sha512-Xcz9l0z7y9yQ9rdDaxlmaI4uJHf/T8g9hOEzJcsEqX2SjCj4J20uK7+ldkDHMbpJDK76wF7xEIgxc/vSlsfw5w==} + engines: {node: '>=10.12.0'} + + babel-dead-code-elimination@1.0.12: + resolution: {integrity: sha512-GERT7L2TiYcYDtYk1IpD+ASAYXjKbLTDPhBtYj7X1NuRMDTMtAx9kyBenub1Ev41lo91OHCKdmP+egTDmfQ7Ig==} + babel-plugin-react-compiler@1.0.0: resolution: {integrity: sha512-Ixm8tFfoKKIPYdCCKYTsqv+Fd4IJ0DQqMyEimo+pxUOMUR9cVPlwTrFt9Avu+3cb6Zp3mAzl+t1MrG2fxxKsxw==} @@ -1946,12 +1540,12 @@ packages: zod: optional: true - body-parser@2.2.2: - resolution: {integrity: sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==} + body-parser@2.3.0: + resolution: {integrity: sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw==} engines: {node: '>=18'} - brace-expansion@5.0.5: - resolution: {integrity: sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==} + brace-expansion@5.0.7: + resolution: {integrity: sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA==} engines: {node: 18 || 20 || >=22} braces@3.0.3: @@ -1994,6 +1588,10 @@ packages: resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + chokidar@5.0.0: + resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==} + engines: {node: '>= 20.19.0'} + class-variance-authority@0.7.1: resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==} @@ -2005,17 +1603,9 @@ packages: resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} engines: {node: '>=6'} - cli-width@4.1.0: - resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} - engines: {node: '>= 12'} - client-only@0.0.1: resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} - cliui@8.0.1: - resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} - engines: {node: '>=12'} - clsx@2.1.1: resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} engines: {node: '>=6'} @@ -2029,13 +1619,6 @@ packages: code-block-writer@13.0.3: resolution: {integrity: sha512-Oofo0pq3IKnsFtuHqSF7TqBfr71aeyZDVJ0HpmqB7FBM2qEigL0iPONSCZSO9pE9dZTAxANe5XHG9Uy0YMv8cg==} - color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} - - color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - commander@11.1.0: resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} engines: {node: '>=16'} @@ -2044,6 +1627,14 @@ packages: resolution: {integrity: sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==} engines: {node: '>=20'} + conf@10.2.0: + resolution: {integrity: sha512-8fLl9F04EJqjSqH+QjITQfJF8BrOVaYr1jewVgSRAEWePfxT0sku4w2hrGQ60BC/TNLGQ2pgxNlTbWQmMPFvXg==} + engines: {node: '>=12'} + + consola@3.4.2: + resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} + engines: {node: ^14.18.0 || >=16.10.0} + content-disposition@1.1.0: resolution: {integrity: sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==} engines: {node: '>=18'} @@ -2052,9 +1643,16 @@ packages: resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} engines: {node: '>= 0.6'} + content-type@2.0.0: + resolution: {integrity: sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==} + engines: {node: '>=18'} + convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + cookie-es@3.1.1: + resolution: {integrity: sha512-UaXxwISYJPTr9hwQxMFYZ7kNhSXboMXP+Z3TRX6f1/NyaGPfuNUZOWP1pUEb75B2HjfklIYLVRfWiFZJyC6Npg==} + cookie-signature@1.2.2: resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==} engines: {node: '>=6.6.0'} @@ -2063,10 +1661,6 @@ packages: resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} engines: {node: '>= 0.6'} - cookie@1.1.1: - resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==} - engines: {node: '>=18'} - copy-anything@3.0.5: resolution: {integrity: sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==} engines: {node: '>=12.13'} @@ -2075,8 +1669,8 @@ packages: resolution: {integrity: sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==} engines: {node: '>= 0.10'} - cosmiconfig@9.0.1: - resolution: {integrity: sha512-hr4ihw+DBqcvrsEDioRO31Z17x71pUYoNe/4h6Z0wB72p7MU7/9gH8Q3s12NFhHPfYBBOV3qyfUxmr/Yn3shnQ==} + cosmiconfig@9.0.2: + resolution: {integrity: sha512-gtTZxTDau1wL7Y7zifc2dd8jHSK/k6BTx/2Xp/BpdlAdnlYWFVt7qhJqgwi7637yRwRQ3qL4ZidbB4I8tA5VOg==} engines: {node: '>=14'} peerDependencies: typescript: '>=4.9.5' @@ -2088,23 +1682,51 @@ packages: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} + crossws@0.4.9: + resolution: {integrity: sha512-iWx+1OMSG2aOHpjyf9AESOzkwsVdS49cXM9dVrI2PDhxU5l2RIWE/KG56gk4BbAnsMoycvniJ9OnOxO9LRzHVA==} + peerDependencies: + srvx: '>=0.11.5' + peerDependenciesMeta: + srvx: + optional: true + cssesc@3.0.0: resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} engines: {node: '>=4'} hasBin: true - csstype@3.1.3: - resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} - data-uri-to-buffer@4.0.1: - resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} - engines: {node: '>= 12'} + date-fns@4.4.0: + resolution: {integrity: sha512-+1UMbeh68lH1SegH83CGWwpb6OHHbpSgr3+s5Eww5M4CAgswBpoWS0AjTOfEJ33HiYKz1hdj/KTFprzXHmq/6w==} - date-fns-jalali@4.1.0-0: - resolution: {integrity: sha512-hTIP/z+t+qKwBDcmmsnmjWTduxCg+5KfdqWQvb2X/8C9+knYY6epN/pfxdDuyVlSVeFz0sM5eEfwIUQ70U4ckg==} + db0@0.3.4: + resolution: {integrity: sha512-RiXXi4WaNzPTHEOu8UPQKMooIbqOEyqA1t7Z6MsdxSCeb8iUC9ko3LcmsLmeUt2SM5bctfArZKkRQggKZz7JNw==} + peerDependencies: + '@electric-sql/pglite': '*' + '@libsql/client': '*' + better-sqlite3: '*' + drizzle-orm: '*' + mysql2: '*' + sqlite3: '*' + peerDependenciesMeta: + '@electric-sql/pglite': + optional: true + '@libsql/client': + optional: true + better-sqlite3: + optional: true + drizzle-orm: + optional: true + mysql2: + optional: true + sqlite3: + optional: true - date-fns@4.1.0: - resolution: {integrity: sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==} + debounce-fn@4.0.0: + resolution: {integrity: sha512-8pYCQiL9Xdcg0UPSD3d+0KMlOjp+KGU5EPwYddgzQ7DATsg4fuUDjQtsYLmWjnk2obnNHgV3vE2Y4jejSOJVBQ==} + engines: {node: '>=10'} debug@4.4.3: resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} @@ -2135,6 +1757,10 @@ packages: resolution: {integrity: sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw==} engines: {node: '>=18'} + define-lazy-prop@2.0.0: + resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} + engines: {node: '>=8'} + define-lazy-prop@3.0.0: resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} engines: {node: '>=12'} @@ -2157,18 +1783,18 @@ packages: resolution: {integrity: sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw==} engines: {node: '>=0.3.1'} - dotenv@17.4.1: - resolution: {integrity: sha512-k8DaKGP6r1G30Lx8V4+pCsLzKr8vLmV2paqEj1Y55GdAgJuIqpRp5FfajGF8KtwMxCz9qJc6wUIJnm053d/WCw==} + dot-prop@6.0.1: + resolution: {integrity: sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==} + engines: {node: '>=10'} + + dotenv@17.4.2: + resolution: {integrity: sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw==} engines: {node: '>=12'} dunder-proto@1.0.1: resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} engines: {node: '>= 0.4'} - eciesjs@0.4.18: - resolution: {integrity: sha512-wG99Zcfcys9fZux7Cft8BAX/YrOJLJSZ3jyYPfhZHqN2E+Ffx+QXBDsv3gubEgPtV6dTzJMSQUwk1H98/t/0wQ==} - engines: {bun: '>=1', deno: '>=2', node: '>=16'} - ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} @@ -2178,21 +1804,40 @@ packages: emoji-regex@10.6.0: resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} - emoji-regex@8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - encodeurl@2.0.0: resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} engines: {node: '>= 0.8'} - enhanced-resolve@5.18.1: - resolution: {integrity: sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==} + enhanced-resolve@5.21.6: + resolution: {integrity: sha512-aNnGCvbJ/RIyWo1IuhNdVjnNF+EjH9wpzpNHt+ci/m9He9LJvUN8wrCcXjp9cWsGNAuvSpVFTx/vraAFQ8qGjQ==} engines: {node: '>=10.13.0'} + enquirer@2.4.1: + resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} + engines: {node: '>=8.6'} + env-paths@2.2.1: resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} engines: {node: '>=6'} + env-runner@0.1.16: + resolution: {integrity: sha512-2LRJM4P2KLX6J83QZZrMqvgCDt/D5ea7wPcI3yYiy5cG/9rX5QwdwZFx0D7ktWnjdRyZxYjttGGorb5nFqb1CA==} + hasBin: true + peerDependencies: + '@netlify/runtime': ^4.1.23 + '@vercel/queue': '>=0.2.0' + miniflare: ^4.20260515.0 + wrangler: ^4.0.0 + peerDependenciesMeta: + '@netlify/runtime': + optional: true + '@vercel/queue': + optional: true + miniflare: + optional: true + wrangler: + optional: true + error-ex@1.3.4: resolution: {integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==} @@ -2204,8 +1849,8 @@ packages: resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} engines: {node: '>= 0.4'} - es-object-atoms@1.1.1: - resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + es-object-atoms@1.1.2: + resolution: {integrity: sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==} engines: {node: '>= 0.4'} escalade@3.2.0: @@ -2224,8 +1869,8 @@ packages: resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} engines: {node: '>= 0.6'} - eventsource-parser@3.0.6: - resolution: {integrity: sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==} + eventsource-parser@3.1.0: + resolution: {integrity: sha512-kJezFj9YFAMLeORyi7aCLxLbD5/qWMQnoMVlVPyHIll7lgRJCc3JVln9Vgl9nwQi0YkMnhdGTMNn7CkRRAptMg==} engines: {node: '>=18.0.0'} eventsource@3.0.7: @@ -2240,8 +1885,8 @@ packages: resolution: {integrity: sha512-9Be3ZoN4LmYR90tUoVu2te2BsbzHfhJyfEiAVfz7N5/zv+jduIfLrV2xdQXOHbaD6KgpGdO9PRPM1Y4Q9QkPkA==} engines: {node: ^18.19.0 || >=20.5.0} - express-rate-limit@8.3.2: - resolution: {integrity: sha512-77VmFeJkO0/rvimEDuUC5H30oqUC4EyOhyGccfqoLebB0oiEYfM7nwPrsDsBL1gsTpwfzX8SFy2MT3TDyRq+bg==} + express-rate-limit@8.5.2: + resolution: {integrity: sha512-5Kb34ipNX694DH48vN9irak1Qx30nb0PLYHXfJgw4YEjiC3ZEmZJhwOp+VfiCYwFzvFTdB9QkArYS5kXa2cx2A==} engines: {node: '>= 16'} peerDependencies: express: '>= 4.11' @@ -2250,6 +1895,9 @@ packages: resolution: {integrity: sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==} engines: {node: '>= 18'} + exsolve@1.1.0: + resolution: {integrity: sha512-D+42+T12DdIlJM3uepa55qGiL3sYdLBOxIl2ifQCzCHz4c7eiolaHsi3BIqEr7JxBzxv2pYZQX9kw16ziMcEmw==} + fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -2257,8 +1905,8 @@ packages: resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} engines: {node: '>=8.6.0'} - fast-uri@3.1.0: - resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==} + fast-uri@3.1.3: + resolution: {integrity: sha512-i70LwGWUduXqzicKXWshooq+sWL1K3WUU5rKZNG/0i3a1OSoX3HqhH5WbWwTmqWfor4urUakGPiRQcleRZTwOg==} fastq@1.20.1: resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} @@ -2272,9 +1920,8 @@ packages: picomatch: optional: true - fetch-blob@3.2.0: - resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} - engines: {node: ^12.20 || >= 14.13} + fetchdts@0.1.7: + resolution: {integrity: sha512-YoZjBdafyLIop9lSxXVI33oLD5kN31q4Td+CasofLLYeLXRFeOsuOw0Uo+XNRi9PZlbfdlN2GmRtm4tCEQ9/KA==} figures@6.1.0: resolution: {integrity: sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==} @@ -2288,43 +1935,53 @@ packages: resolution: {integrity: sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==} engines: {node: '>= 18.0.0'} - formdata-polyfill@4.0.10: - resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} - engines: {node: '>=12.20.0'} + find-up@3.0.0: + resolution: {integrity: sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==} + engines: {node: '>=6'} forwarded@0.2.0: resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} engines: {node: '>= 0.6'} + framer-motion@12.42.2: + resolution: {integrity: sha512-5XY9luDiu0oHfHBjpDthFMh0ES+122w6p/papSJBweMkO8Sn+PW2QaEgRblQBpWFnuvZS5qvarpt/hO2pjGmnw==} + peerDependencies: + '@emotion/is-prop-valid': '*' + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@emotion/is-prop-valid': + optional: true + react: + optional: true + react-dom: + optional: true + fresh@2.0.0: resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} engines: {node: '>= 0.8'} - fs-extra@11.3.4: - resolution: {integrity: sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA==} + fs-extra@11.3.6: + resolution: {integrity: sha512-w8ZNZr2mKIc7qeNaQ9AVPT1+iFaI+Avd4xudVOvdDJ8VytREi1Ft5Ih7hd9jjehod8vAM5GMsfQ/TpPf4EyoEA==} engines: {node: '>=14.14'} + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} fuzzysort@3.1.0: resolution: {integrity: sha512-sR9BNCjBg6LNgwvxlBd0sBABvQitkLzoVY9MYYROQVX/FvfJ4Mai9LsGhDgd8qYdds0bY77VzYd5iuB+v5rwQQ==} - geist@1.3.1: - resolution: {integrity: sha512-Q4gC1pBVPN+D579pBaz0TRRnGA4p9UK6elDY/xizXdFk/g4EKR5g0I+4p/Kj6gM0SajDBZ/0FvDV9ey9ud7BWw==} - peerDependencies: - next: '>=13.2.0' - gensync@1.0.0-beta.2: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} - get-caller-file@2.0.5: - resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} - engines: {node: 6.* || 8.* || >= 10.*} - - get-east-asian-width@1.5.0: - resolution: {integrity: sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==} + get-east-asian-width@1.6.0: + resolution: {integrity: sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==} engines: {node: '>=18'} get-intrinsic@1.3.0: @@ -2362,32 +2019,47 @@ packages: graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} - graphql@16.13.2: - resolution: {integrity: sha512-5bJ+nf/UCpAjHM8i06fl7eLyVC9iuNAjm9qzkiu2ZGhM0VscSvS6WDPfAwkdkBuoXGM9FJSbKl6wylMwP9Ktig==} - engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} + h3@2.0.1-rc.20: + resolution: {integrity: sha512-28ljodXuUp0fZovdiSRq4G9OgrxCztrJe5VdYzXAB7ueRvI7pIUqLU14Xi3XqdYJ/khXjfpUOOD2EQa6CmBgsg==} + engines: {node: '>=20.11.1'} + hasBin: true + peerDependencies: + crossws: ^0.4.1 + peerDependenciesMeta: + crossws: + optional: true + + h3@2.0.1-rc.22: + resolution: {integrity: sha512-Esv0DMIuPkCTSWCA0vO73vcTqwzH1wjSrAO1TXNu/K3up1sZHa9EKMapbmxCDYBeymC3fVTk4qxp7ogQWQ+KgA==} + engines: {node: '>=20.11.1'} + hasBin: true + peerDependencies: + crossws: ^0.4.1 + peerDependenciesMeta: + crossws: + optional: true has-symbols@1.1.0: resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} engines: {node: '>= 0.4'} - hasown@2.0.2: - resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + hasown@2.0.4: + resolution: {integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==} engines: {node: '>= 0.4'} - headers-polyfill@4.0.3: - resolution: {integrity: sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ==} - - hono@4.12.12: - resolution: {integrity: sha512-p1JfQMKaceuCbpJKAPKVqyqviZdS0eUxH9v82oWo1kb9xjQ5wA6iP3FNVAPDFlz5/p7d45lO+BpSk1tuSZMF4Q==} + hono@4.12.29: + resolution: {integrity: sha512-1hNiRjawYrLq/4m3DQQjPGFg0VZkk4RjQJDff/excI6Dm9BiL75qxGrd7/c6YOxPdq6AscP3LiXhQ6fKFC1Waw==} engines: {node: '>=16.9.0'} + hookable@6.1.1: + resolution: {integrity: sha512-U9LYDy1CwhMCnprUfeAZWZGByVbhd54hwepegYTK7Pi5NvqEj63ifz5z+xukznehT7i6NIZRu89Ay1AZmRsLEQ==} + http-errors@2.0.1: resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} engines: {node: '>= 0.8'} - https-proxy-agent@7.0.6: - resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} - engines: {node: '>= 14'} + httpxy@0.5.5: + resolution: {integrity: sha512-uDjmnPyp1q4Sgzf3w+J/Fc6UqcCEj0x4Wjp7OqK5dGhNeDgpyrAmnS6ey8QWrX3SWDon2DMKf9sBa5X9+CVyMA==} human-signals@2.1.0: resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} @@ -2397,8 +2069,8 @@ packages: resolution: {integrity: sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==} engines: {node: '>=18.18.0'} - iconv-lite@0.7.2: - resolution: {integrity: sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==} + iconv-lite@0.7.3: + resolution: {integrity: sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==} engines: {node: '>=0.10.0'} ignore@5.3.2: @@ -2412,14 +2084,8 @@ packages: inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - input-otp@1.4.2: - resolution: {integrity: sha512-l3jWwYNvrEa6NTCt7BECfCm48GvwuZzkoeG3gBL2w4CHeOXW3eKFmf9UNYkNfYc3mxMrthMnxjIE07MT0zLBQA==} - peerDependencies: - react: ^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc - - ip-address@10.1.0: - resolution: {integrity: sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==} + ip-address@10.2.0: + resolution: {integrity: sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA==} engines: {node: '>= 12'} ipaddr.js@1.9.1: @@ -2429,6 +2095,11 @@ packages: is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + is-docker@2.2.1: + resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} + engines: {node: '>=8'} + hasBin: true + is-docker@3.0.0: resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -2438,10 +2109,6 @@ packages: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} - is-fullwidth-code-point@3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} - is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} @@ -2459,13 +2126,14 @@ packages: resolution: {integrity: sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==} engines: {node: '>=12'} - is-node-process@1.2.0: - resolution: {integrity: sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==} - is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} + is-obj@2.0.0: + resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==} + engines: {node: '>=8'} + is-obj@3.0.0: resolution: {integrity: sha512-IlsXEHOjtKhpN8r/tRFj2nDyTmHvcfNeu/nrRIcXE17ROeatXchkojffa1SpdqW4cr/Fj6QkEf/Gn4zf6KKvEQ==} engines: {node: '>=12'} @@ -2501,10 +2169,18 @@ packages: resolution: {integrity: sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==} engines: {node: '>=12.13'} + is-wsl@2.2.0: + resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} + engines: {node: '>=8'} + is-wsl@3.1.1: resolution: {integrity: sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==} engines: {node: '>=16'} + isbot@5.2.0: + resolution: {integrity: sha512-gbZiGCb4B5xaoxg9mS7koAyRdvJnArk10VLSHOgz6rtBG93/pi1xOFaVvXMKZ7JXgyZ8zAbNRK5uIBdIUTFSqw==} + engines: {node: '>=18'} + isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} @@ -2512,8 +2188,8 @@ packages: resolution: {integrity: sha512-6B3tLtFqtQS4ekarvLVMZ+X+VlvQekbe4taUkf/rhVO3d/h0M2rfARm/pXLcPEsjjMsFgrFgSrhQIxcSVrBz8w==} engines: {node: '>=18'} - jiti@2.4.2: - resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==} + jiti@2.7.0: + resolution: {integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==} hasBin: true jose@6.1.3: @@ -2537,6 +2213,9 @@ packages: json-schema-traverse@1.0.0: resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + json-schema-typed@7.0.3: + resolution: {integrity: sha512-7DE8mpG+/fVw+dTpjbxnx47TaMnDfOI1jwft9g1VybltZCduyRQPJPvc+zzKY9WPHxhPWczyFuYa6I8Mw4iU5A==} + json-schema-typed@8.0.2: resolution: {integrity: sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==} @@ -2545,8 +2224,8 @@ packages: engines: {node: '>=6'} hasBin: true - jsonfile@6.2.0: - resolution: {integrity: sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==} + jsonfile@6.2.1: + resolution: {integrity: sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==} kleur@3.0.3: resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} @@ -2560,84 +2239,98 @@ packages: resolution: {integrity: sha512-kWiueDWXhbCchgiotwXkwdxZE/6h56IHAeFWg4euUfW0YsmO9sxbAxzx1KLLv2lox15EfuuxHQvgJ1qIfZuHGw==} engines: {node: '>=20.0.0'} - lightningcss-darwin-arm64@1.29.2: - resolution: {integrity: sha512-cK/eMabSViKn/PG8U/a7aCorpeKLMlK0bQeNHmdb7qUnBkNPnL+oV5DjJUo0kqWsJUapZsM4jCfYItbqBDvlcA==} + lightningcss-android-arm64@1.32.0: + resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [android] + + lightningcss-darwin-arm64@1.32.0: + resolution: {integrity: sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [darwin] - lightningcss-darwin-x64@1.29.2: - resolution: {integrity: sha512-j5qYxamyQw4kDXX5hnnCKMf3mLlHvG44f24Qyi2965/Ycz829MYqjrVg2H8BidybHBp9kom4D7DR5VqCKDXS0w==} + lightningcss-darwin-x64@1.32.0: + resolution: {integrity: sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [darwin] - lightningcss-freebsd-x64@1.29.2: - resolution: {integrity: sha512-wDk7M2tM78Ii8ek9YjnY8MjV5f5JN2qNVO+/0BAGZRvXKtQrBC4/cn4ssQIpKIPP44YXw6gFdpUF+Ps+RGsCwg==} + lightningcss-freebsd-x64@1.32.0: + resolution: {integrity: sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [freebsd] - lightningcss-linux-arm-gnueabihf@1.29.2: - resolution: {integrity: sha512-IRUrOrAF2Z+KExdExe3Rz7NSTuuJ2HvCGlMKoquK5pjvo2JY4Rybr+NrKnq0U0hZnx5AnGsuFHjGnNT14w26sg==} + lightningcss-linux-arm-gnueabihf@1.32.0: + resolution: {integrity: sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==} engines: {node: '>= 12.0.0'} cpu: [arm] os: [linux] - lightningcss-linux-arm64-gnu@1.29.2: - resolution: {integrity: sha512-KKCpOlmhdjvUTX/mBuaKemp0oeDIBBLFiU5Fnqxh1/DZ4JPZi4evEH7TKoSBFOSOV3J7iEmmBaw/8dpiUvRKlQ==} + lightningcss-linux-arm64-gnu@1.32.0: + resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] - lightningcss-linux-arm64-musl@1.29.2: - resolution: {integrity: sha512-Q64eM1bPlOOUgxFmoPUefqzY1yV3ctFPE6d/Vt7WzLW4rKTv7MyYNky+FWxRpLkNASTnKQUaiMJ87zNODIrrKQ==} + lightningcss-linux-arm64-musl@1.32.0: + resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] - lightningcss-linux-x64-gnu@1.29.2: - resolution: {integrity: sha512-0v6idDCPG6epLXtBH/RPkHvYx74CVziHo6TMYga8O2EiQApnUPZsbR9nFNrg2cgBzk1AYqEd95TlrsL7nYABQg==} + lightningcss-linux-x64-gnu@1.32.0: + resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] - lightningcss-linux-x64-musl@1.29.2: - resolution: {integrity: sha512-rMpz2yawkgGT8RULc5S4WiZopVMOFWjiItBT7aSfDX4NQav6M44rhn5hjtkKzB+wMTRlLLqxkeYEtQ3dd9696w==} + lightningcss-linux-x64-musl@1.32.0: + resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] - lightningcss-win32-arm64-msvc@1.29.2: - resolution: {integrity: sha512-nL7zRW6evGQqYVu/bKGK+zShyz8OVzsCotFgc7judbt6wnB2KbiKKJwBE4SGoDBQ1O94RjW4asrCjQL4i8Fhbw==} + lightningcss-win32-arm64-msvc@1.32.0: + resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [win32] - lightningcss-win32-x64-msvc@1.29.2: - resolution: {integrity: sha512-EdIUW3B2vLuHmv7urfzMI/h2fmlnOQBk1xlsDxkN1tCWKjNFjfLhGxYk8C8mzpSfr+A6jFFIi8fU6LbQGsRWjA==} + lightningcss-win32-x64-msvc@1.32.0: + resolution: {integrity: sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [win32] - lightningcss@1.29.2: - resolution: {integrity: sha512-6b6gd/RUXKaw5keVdSEtqFVdzWnU5jMxTUjA2bVcMNPLwSQ08Sv/UodBVtETLCn7k4S1Ibxwh7k68IwLZPgKaA==} + lightningcss@1.32.0: + resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==} engines: {node: '>= 12.0.0'} lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + locate-path@3.0.0: + resolution: {integrity: sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==} + engines: {node: '>=6'} + log-symbols@6.0.0: resolution: {integrity: sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==} engines: {node: '>=18'} - loose-envify@1.4.0: - resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} - hasBin: true - lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + lucide-react@0.545.0: + resolution: {integrity: sha512-7r1/yUuflQDSt4f1bpn5ZAocyIxcTyVyBBChSVtBKn5M+392cPmI5YJMWOJKk/HUWGm5wg83chlAZtCcGbEZtw==} + peerDependencies: + react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + math-intrinsics@1.1.0: resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} engines: {node: '>= 0.4'} @@ -2676,6 +2369,10 @@ packages: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} engines: {node: '>=6'} + mimic-fn@3.1.0: + resolution: {integrity: sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==} + engines: {node: '>=8'} + mimic-function@5.0.1: resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==} engines: {node: '>=18'} @@ -2718,33 +2415,34 @@ packages: socks: optional: true - ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + motion-dom@12.42.2: + resolution: {integrity: sha512-5gIMWLp/PycBtJRJWRgjxke5n8dlvkSn2DrYW+tr3XcqAZY1xZh6BJyooJXCM8wdfM7wfMjkBJNLge1CKPUIRA==} - msw@2.13.2: - resolution: {integrity: sha512-go2H1TIERKkC48pXiwec5l6sbNqYuvqOk3/vHGo1Zd+pq/H63oFawDQerH+WQdUw/flJFHDG7F+QdWMwhntA/A==} - engines: {node: '>=18'} - hasBin: true + motion-utils@12.39.0: + resolution: {integrity: sha512-8nadJAJjTtqRkmRF36FoJTrywK9nnFmnPwnSMyxaOCU7GDjN9RTMJIxx9De8ErM+vpPhMccr/6fo5WciyQLnMQ==} + + motion@12.42.2: + resolution: {integrity: sha512-Atvv11yUKIid41cVrRBDVX5m8tF8kNpExRSlbpt6APClhDjtwQssgFHhQzejxw7/7YYbjHSPKBVbHo05BuJT5Q==} peerDependencies: - typescript: '>= 4.8.x' + '@emotion/is-prop-valid': '*' + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 peerDependenciesMeta: - typescript: + '@emotion/is-prop-valid': + optional: true + react: + optional: true + react-dom: optional: true - mute-stream@2.0.0: - resolution: {integrity: sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==} - engines: {node: ^18.17.0 || >=20.5.0} + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} nanoid@3.3.12: resolution: {integrity: sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true - nanoid@3.3.8: - resolution: {integrity: sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} - hasBin: true - nanostores@1.2.0: resolution: {integrity: sha512-F0wCzbsH80G7XXo0Jd9/AVQC7ouWY6idUCTnMwW5t/Rv9W8qmO6endavDwg7TNp5GbugwSukFMVZqzPSrSMndg==} engines: {node: ^20.0.0 || >=22.0.0} @@ -2753,12 +2451,6 @@ packages: resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} engines: {node: '>= 0.6'} - next-themes@0.4.4: - resolution: {integrity: sha512-LDQ2qIOJF0VnuVrrMSMLrWGjRMkq+0mpgl6e0juCLqdJ+oo8Q84JRWT6Wh11VDQKkMMe+dVzDKLWs5n87T+PkQ==} - peerDependencies: - react: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc - react-dom: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc - next@15.5.18: resolution: {integrity: sha512-eKL8zUJkX9Y5lE+RX/2YJoItVdGlIscyVyboeD9wSpp0PaGqjoA4tTpT2qPqz9ax+5IzGESyLSeZ/RCwbSZ2uQ==} engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} @@ -2780,14 +2472,39 @@ packages: sass: optional: true - node-domexception@1.0.0: - resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} - engines: {node: '>=10.5.0'} - deprecated: Use your platform's native DOMException instead + nf3@0.3.21: + resolution: {integrity: sha512-DJ1Ss/jfUdqETSbouezgAyh6NmD3r2NnpX7Vhwz7nPTc8TvqFddJ/tMgYDwhWU4H/vTOUXDYG3sWsB9vGBX/HA==} - node-fetch@3.3.2: - resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + nitro@3.0.260610-beta: + resolution: {integrity: sha512-KPb4L5yaF/Rx/xoGMpgHRJvZhbhGiqbRKOwwPLCH9jKTKTsEUHLjnJas85AeCzaswqa8Wi52eQBtRsODC4PS0Q==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@vercel/queue': ^0.3.0 + dotenv: '*' + giget: '*' + jiti: ^2.7.0 + rollup: ^4.61.1 + vite: ^7 || ^8 + xml2js: ^0.6.2 + zephyr-agent: ^0.2.0 + peerDependenciesMeta: + '@vercel/queue': + optional: true + dotenv: + optional: true + giget: + optional: true + jiti: + optional: true + rollup: + optional: true + vite: + optional: true + xml2js: + optional: true + zephyr-agent: + optional: true node-releases@2.0.37: resolution: {integrity: sha512-1h5gKZCF+pO/o3Iqt5Jp7wc9rH3eJJ0+nh/CIoiRwjRxde/hAHyLPXYN4V3CqKAbiZPSeJFSWHmJsbkicta0Eg==} @@ -2812,6 +2529,15 @@ packages: resolution: {integrity: sha512-EFVjAYfzWqWsBMRHPMAXLCDIJnpMhdWAqR7xG6M6a2cs6PMFpl/+Z20w9zDW4vkxOFfddegBKq9Rehd0bxWE7A==} engines: {node: '>= 10'} + ocache@0.1.5: + resolution: {integrity: sha512-kNNnkkVQup/QDvmTz8Q84wc2ntiyoVHDxa6eHWKt5qdGAmFRBIxy83rxgCYEjW0x06UJ9E3P6VgM2yY4rOBH4w==} + + ofetch@2.0.0-alpha.3: + resolution: {integrity: sha512-zpYTCs2byOuft65vI3z43Dd6iSdFbOZZLb9/d21aCpx2rGastVU9dOCv0lu4ykc1Ur1anAYjDi3SUvR0vq50JA==} + + ohash@2.0.11: + resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==} + on-finished@2.4.1: resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} engines: {node: '>= 0.8'} @@ -2831,12 +2557,25 @@ packages: resolution: {integrity: sha512-smsWv2LzFjP03xmvFoJ331ss6h+jixfA4UUV/Bsiyuu4YJPfN+FIQGOIiv4w9/+MoHkfkJ22UIaQWRVFRfH6Vw==} engines: {node: '>=20'} + open@8.4.2: + resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} + engines: {node: '>=12'} + ora@8.2.0: resolution: {integrity: sha512-weP+BZ8MVNnlCm8c0Qdc1WSWq4Qn7I+9CJGm7Qali6g44e/PUzbjNqJX5NJ9ljlNMosfJvg1fKEGILklK9cwnw==} engines: {node: '>=18'} - outvariant@1.4.3: - resolution: {integrity: sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==} + p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + + p-locate@3.0.0: + resolution: {integrity: sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==} + engines: {node: '>=6'} + + p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} @@ -2857,6 +2596,10 @@ packages: path-browserify@1.0.1: resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} + path-exists@3.0.0: + resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==} + engines: {node: '>=4'} + path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} @@ -2865,12 +2608,12 @@ packages: resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} engines: {node: '>=12'} - path-to-regexp@6.3.0: - resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==} - path-to-regexp@8.4.2: resolution: {integrity: sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==} + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} @@ -2878,47 +2621,43 @@ packages: resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==} engines: {node: '>=8.6'} - picomatch@4.0.4: - resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} + picomatch@4.0.5: + resolution: {integrity: sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==} engines: {node: '>=12'} pkce-challenge@5.0.1: resolution: {integrity: sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==} engines: {node: '>=16.20.0'} - postcss-selector-parser@7.1.1: - resolution: {integrity: sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==} + pkg-up@3.1.0: + resolution: {integrity: sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==} + engines: {node: '>=8'} + + postcss-selector-parser@7.1.4: + resolution: {integrity: sha512-HeP7D2wyhkR+XaK6v4W8oRF62Dsz4flyuczALJp61GckGm42u1saSSJ/0auvcBqxs3jMRFEcPK34At/0JBKdOg==} engines: {node: '>=4'} postcss@8.4.31: resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} engines: {node: ^10 || ^12 || >=14} - postcss@8.5.2: - resolution: {integrity: sha512-MjOadfU3Ys9KYoX0AdkBlFEF1Vx37uCCeN4ZHnmwm9FfpbsGWMZeBLMmmpY+6Ocqod7mkdZ0DT31OlbsFrLlkA==} + postcss@8.5.16: + resolution: {integrity: sha512-vuwillviilfKZsg0VGj5R/YwwcHx4SLsIOI/7K6mQkWx+l5cUHTjj5g0AasTBcyXsbfTgrwsUNmVUb5xVwyPwg==} engines: {node: ^10 || ^12 || >=14} - postcss@8.5.9: - resolution: {integrity: sha512-7a70Nsot+EMX9fFU3064K/kdHWZqGVY+BADLyXc8Dfv+mTLLVl6JzJpPaCZ2kQL9gIJvKXSLMHhqdRRjwQeFtw==} - engines: {node: ^10 || ^12 || >=14} - - postgres@3.4.5: - resolution: {integrity: sha512-cDWgoah1Gez9rN3H4165peY9qfpEo+SA61oQv65O3cRUE1pOEoJWwddwcqKE8XZYjbblOJlYDlLV4h67HrEVDg==} - engines: {node: '>=12'} - powershell-utils@0.1.0: resolution: {integrity: sha512-dM0jVuXJPsDN6DvRpea484tCUaMiXWjuCn++HGTqUWzGDjv5tZkEZldAJ/UMlqRYGFrD/etByo4/xOuC/snX2A==} engines: {node: '>=20'} + prettier@3.9.5: + resolution: {integrity: sha512-/FVl766LpUfB5vXgCYOYa0MeV/441Ia99AeICQIQFTY/Nw0roZwULcXpku5i1/m5kt/baz+s4Zogspd839HSMg==} + engines: {node: '>=14'} + hasBin: true + pretty-ms@9.3.0: resolution: {integrity: sha512-gjVS5hOP+M3wMm5nmNOucbIrqudzs9v/57bWRHQWLYklXqoXKrVfYW2W9+glfGsqtPgpiz5WwyEEB+ksXIx3gQ==} engines: {node: '>=18'} - prism-react-renderer@2.4.1: - resolution: {integrity: sha512-ey8Ls/+Di31eqzUxC46h8MksNuGx/n0AAC8uKpwFau4RPDYLuE3EXTp8N8G2vX2N7UC/+IXeNUnlWBGGcAG+Ig==} - peerDependencies: - react: '>=16.0.0' - prompts@2.4.2: resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} engines: {node: '>= 6'} @@ -2938,60 +2677,35 @@ packages: resolution: {integrity: sha512-KTqnxsgGiQ6ZAzZCVlJH5eOjSnvlyEgx1m8bkRJfOhmGRqfo5KLvmAlACQkrjEtOQ4B7wF9TdSLIs9O90MX9xA==} engines: {node: '>=16.0.0'} - qs@6.15.1: - resolution: {integrity: sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg==} + qs@6.15.3: + resolution: {integrity: sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A==} engines: {node: '>=0.6'} queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - radix-ui@1.4.3: - resolution: {integrity: sha512-aWizCQiyeAenIdUbqEpXgRA1ya65P13NKn/W8rWkcN0OPkRDxdBVLWnIEDsS2RpwCK2nobI7oMUSmexzTDyAmA==} - 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 - - range-parser@1.2.1: - resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + range-parser@1.3.0: + resolution: {integrity: sha512-hek2mFQpPuI4E1BBKrSto+BU3e3x4xuarsbiwr3+lf7p44juvFMV0XFWQAP3xUyqXA4RrXLIoaSUGbSt056ZMw==} engines: {node: '>= 0.6'} raw-body@3.0.2: resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==} engines: {node: '>= 0.10'} - react-day-picker@9.14.0: - resolution: {integrity: sha512-tBaoDWjPwe0M5pGrum4H0SR6Lyk+BO9oHnp9JbKpGKW2mlraNPgP9BMfsg5pWpwrssARmeqk7YBl2oXutZTaHA==} + react-day-picker@10.0.1: + resolution: {integrity: sha512-eNh6BlwcYInWaJtRv18mXQ06Ys/H6rdTZAnTaSdOYJuTpwP1JMCHNd1FDRadA+gbeinq+psdULN5Xnowy9mV8w==} engines: {node: '>=18'} peerDependencies: + '@types/react': '>=16.8.0' react: '>=16.8.0' + peerDependenciesMeta: + '@types/react': + optional: true - react-dom@18.3.1: - resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} - peerDependencies: - react: ^18.3.1 - - react-error-boundary@6.1.0: - resolution: {integrity: sha512-02k9WQ/mUhdbXir0tC1NiMesGzRPaCsJEWU/4bcFrbY1YMZOtHShtZP6zw0SJrBWA/31H0KT9/FgdL8+sPKgHA==} - peerDependencies: - react: ^18.0.0 || ^19.0.0 - - react-hook-form@7.55.0: - resolution: {integrity: sha512-XRnjsH3GVMQz1moZTW53MxfoWN7aDpUg/GpVNc4A3eXRVNdGXfbzJ4vM4aLQ8g6XCUh1nIbx70aaNCl7kxnjog==} - engines: {node: '>=18.0.0'} - peerDependencies: - react: ^16.8.0 || ^17 || ^18 || ^19 - - react-icons@5.7.0: - resolution: {integrity: sha512-LBLy340Rzqy6+/yVhZKT3B/QpP1BZaesGqasf09HPOBzRarcDIFH0WwXlXQfE7q7ipxK4MSiC5DIBWURCny6fw==} + react-dom@19.2.7: + resolution: {integrity: sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==} peerDependencies: - react: '*' + react: ^19.2.7 react-remove-scroll-bar@2.3.8: resolution: {integrity: sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==} @@ -3003,8 +2717,8 @@ packages: '@types/react': optional: true - react-remove-scroll@2.6.3: - resolution: {integrity: sha512-pnAi91oOk8g8ABQKGF5/M9qxmmOPxaAnopyTHYfqYEwJhyFrbbBtHuSgtKEoH0jpcxx5o3hXqH1mNd9/Oi+8iQ==} + react-remove-scroll@2.7.2: + resolution: {integrity: sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q==} engines: {node: '>=10'} peerDependencies: '@types/react': '*' @@ -3023,27 +2737,27 @@ packages: '@types/react': optional: true - react@18.3.1: - resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} + react@19.2.7: + resolution: {integrity: sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==} engines: {node: '>=0.10.0'} - recast@0.23.11: - resolution: {integrity: sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA==} + readdirp@5.0.0: + resolution: {integrity: sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==} + engines: {node: '>= 20.19.0'} + + recast@0.23.12: + resolution: {integrity: sha512-dEWRjcINDu/F4l2dYx57ugBtD7HV9KXESyxhzw/MqWLeglJrsjJKqACPyUPg+6AF8mIgm+Zi0dZ3ACoIg+QtpA==} engines: {node: '>= 4'} reflect-metadata@0.2.2: resolution: {integrity: sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==} - require-directory@2.1.1: - resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} - engines: {node: '>=0.10.0'} - require-from-string@2.0.2: resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} engines: {node: '>=0.10.0'} - reselect@5.1.1: - resolution: {integrity: sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==} + reselect@5.2.0: + resolution: {integrity: sha512-AgZ3UOZm3YndfrJ4OYjgrT7bmCm/1iqkjvEfH/oYjzh6PD2qw4QuT3jjnXIrpdt4MTpMXclMT3lXbmRY+XRakw==} resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} @@ -3053,16 +2767,21 @@ packages: resolution: {integrity: sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==} engines: {node: '>=18'} - rettime@0.10.1: - resolution: {integrity: sha512-uyDrIlUEH37cinabq0AX4QbgV4HbFZ/gqoiunWQ1UqBtRvTTytwhNYjE++pO/MjPTZL5KQCf2bEoJ/BJNVQ5Kw==} - reusify@1.1.0: resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + rolldown@1.1.5: + resolution: {integrity: sha512-t9z29cJjXf/vxQ8dyhCSpt6H6aSwHTk8cT5I3iy6SMXuFpk5mB6PL6XfC8PCwrPTx93udwKUm9HRteAlTGBLiA==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + rou3@0.7.12: resolution: {integrity: sha512-iFE4hLDuloSWcD7mjdCDhx2bKcIsYbtOTpfH5MHHLSKMOUyjqQXTeZVa289uuwEGEKFoE/BAPbhaU4B774nceg==} + rou3@0.8.1: + resolution: {integrity: sha512-ePa+XGk00/3HuCqrEnK3LxJW7I0SdNg6EFzKUJG73hMAdDcOUC/i/aSz7LSDwLrGr33kal/rqOGydzwl6U7zBA==} + router@2.2.0: resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==} engines: {node: '>= 18'} @@ -3077,8 +2796,8 @@ packages: safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - scheduler@0.23.2: - resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} + scheduler@0.27.0: + resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} semver@6.3.1: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} @@ -3093,21 +2812,29 @@ packages: resolution: {integrity: sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==} engines: {node: '>= 18'} + seroval-plugins@1.5.5: + resolution: {integrity: sha512-+BDhqYM6CEn3x09v44dpa9p6974FuUB2dxk+Ctn04k0cO1Zt6QODTXfmEZK0eBaTe/fJBvP4NMGuNJ+R8T+QMg==} + engines: {node: '>=10'} + peerDependencies: + seroval: ^1.0 + + seroval@1.5.5: + resolution: {integrity: sha512-bSjOuPcwPKLSJNhr9+bZxA20nQxVle5J5MNsYRVE6cIg7KpRLXGupymePavu0jrxlPiPsr4xGZSB8yUY2sH2sw==} + engines: {node: '>=10'} + serve-static@2.2.1: resolution: {integrity: sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==} engines: {node: '>= 18'} - server-only@0.0.1: - resolution: {integrity: sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA==} - set-cookie-parser@3.0.1: resolution: {integrity: sha512-n7Z7dXZhJbwuAHhNzkTti6Aw9QDDjZtm3JTpTGATIdNzdQz5GuFs22w90BcvF4INfnrL5xrX3oGsuqO5Dx3A1Q==} setprototypeof@1.2.0: resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} - shadcn@4.2.0: - resolution: {integrity: sha512-ZDuV340itidaUd4Gi1BxQX+Y7Ush6BHp6URZBM2RyxUUBZ6yFtOWIr4nVY+Ro+YRSpo82v7JrsmtcU5xoBCMJQ==} + shadcn@4.13.0: + resolution: {integrity: sha512-5fuJ4jI/GcPeA/iTL4cJivCZuYQGXz/N3bIzyd+Gd/FM6xUCy2MxGG+LaDQuw2cjNy9zGPSFPTEmI048UwPTZA==} + engines: {node: '>=20.18.1'} hasBin: true sharp@0.34.5: @@ -3134,8 +2861,8 @@ packages: resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} engines: {node: '>= 0.4'} - side-channel@1.1.0: - resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + side-channel@1.1.1: + resolution: {integrity: sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==} engines: {node: '>= 0.4'} signal-exit@3.0.7: @@ -3148,8 +2875,11 @@ packages: sisteransi@1.0.5: resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} - sonner@2.0.3: - resolution: {integrity: sha512-njQ4Hht92m0sMqqHVDL32V2Oun9W1+PHO9NDv9FHfJjT3JT22IG4Jpo3FPQy+mouRKCXFWO+r67v6MrHX2zeIA==} + solid-js@1.9.14: + resolution: {integrity: sha512-sAEXC0Kk0S1EDg+8ysEWJDbYhA3RRoEjwuySUGlKIemeo0I5YZfOyumNjNs9Sv3y2nmhD+0rW66ag2HsMuQiGQ==} + + sonner@2.0.7: + resolution: {integrity: sha512-W6ZN4p58k8aDKA4XPcx2hpIQXBRAgyiWVkYhT7CvK6D3iAu7xjvVyhQHg2/iaKJZ1XVJ4r7XuwGL+WGEK37i9w==} peerDependencies: react: ^18.0.0 || ^19.0.0 || ^19.0.0-rc react-dom: ^18.0.0 || ^19.0.0 || ^19.0.0-rc @@ -3162,9 +2892,18 @@ packages: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} + source-map@0.7.6: + resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} + engines: {node: '>= 12'} + sparse-bitfield@3.0.3: resolution: {integrity: sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==} + srvx@0.11.21: + resolution: {integrity: sha512-GWTHjKMeekX8CwJf4VU9Oo6mJpSGaflGMddbCvR+Cmmh9sslRMiGbAoqqZacE0r1ncARh6buCEETr2W52F8b1w==} + engines: {node: '>=20.16.0'} + hasBin: true + statuses@2.0.2: resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} engines: {node: '>= 0.8'} @@ -3173,13 +2912,6 @@ packages: resolution: {integrity: sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==} engines: {node: '>=18'} - strict-event-emitter@0.5.1: - resolution: {integrity: sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==} - - string-width@4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} - string-width@7.2.0: resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} engines: {node: '>=18'} @@ -3225,43 +2957,28 @@ packages: resolution: {integrity: sha512-5JRxVqC8I8NuOUjzBbvVJAKNM8qoVuH0O77h4WInc/qC2q5IreqKxYwgkga3PfA22OayK2ikceb/B26dztPl+Q==} engines: {node: '>=16'} - tabbable@6.4.0: - resolution: {integrity: sha512-05PUHKSNE8ou2dwIxTngl4EzcnsCDZGJ/iCLtDflR/SHB/ny14rXc+qU5P4mG9JkusiV7EivzY9Mhm55AzAvCg==} - - tagged-tag@1.0.0: - resolution: {integrity: sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==} - engines: {node: '>=20'} - - tailwind-merge@3.0.1: - resolution: {integrity: sha512-AvzE8FmSoXC7nC+oU5GlQJbip2UO7tmOhOfQyOmPhrStOGXHU08j8mZEHZ4BmCqY5dWTCo4ClWkNyRNx1wpT0g==} - - tailwind-scrollbar@4.0.2: - resolution: {integrity: sha512-wAQiIxAPqk0MNTPptVe/xoyWi27y+NRGnTwvn4PQnbvB9kp8QUBiGl/wsfoVBHnQxTmhXJSNt9NHTmcz9EivFA==} - engines: {node: '>=12.13.0'} - peerDependencies: - tailwindcss: 4.x + systeminformation@5.31.15: + resolution: {integrity: sha512-7mqCtD28TK5dVdLAQONVa/Do/NBgMH2dxqf49nh6DIKoEWuDg6tkgGBP+dN22VEJVPZa/QqiHomhWNRn4WUNTQ==} + engines: {node: '>=8.0.0'} + os: [darwin, linux, win32, freebsd, openbsd, netbsd, sunos, android] + hasBin: true - tailwindcss-animate@1.0.7: - resolution: {integrity: sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==} - peerDependencies: - tailwindcss: '>=3.0.0 || insiders' + tailwind-merge@3.6.0: + resolution: {integrity: sha512-uxL7qAVQriqRQPAyK3pj66VqskWqoZ37PW94jwOTwNfq/z9oyu1V+eqrZqtR2+fCiXdYOZe/Modt8GtvqNzu+w==} - tailwindcss@4.1.4: - resolution: {integrity: sha512-1ZIUqtPITFbv/DxRmDr5/agPqJwF69d24m9qmM1939TJehgY539CtzeZRjbLt5G6fSy/7YqqYsfvoTEw9xUI2A==} + tailwindcss@4.3.2: + resolution: {integrity: sha512-WtctNNSH8A9jlMIqxzuYumOHU5uGZyRv0Q5svQl+oEPy5w84YpBxdb7MdqyiSPQge5jTJ6zFQLq0PFygdccSBA==} - tapable@2.2.1: - resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} + tapable@2.3.3: + resolution: {integrity: sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==} engines: {node: '>=6'} tiny-invariant@1.3.3: resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} - tldts-core@7.0.28: - resolution: {integrity: sha512-7W5Efjhsc3chVdFhqtaU0KtK32J37Zcr9RKtID54nG+tIpcY79CQK/veYPODxtD/LJ4Lue66jvrQzIX2Z2/pUQ==} - - tldts@7.0.28: - resolution: {integrity: sha512-+Zg3vWhRUv8B1maGSTFdev9mjoo8Etn2Ayfs4cnjlD3CsGkxXX4QyW3j2WJ0wdjYcYmy7Lx2RDsZMhgCWafKIw==} - hasBin: true + tinyglobby@0.2.17: + resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} + engines: {node: '>=12.0.0'} to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} @@ -3271,10 +2988,6 @@ packages: resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} engines: {node: '>=0.6'} - tough-cookie@6.0.1: - resolution: {integrity: sha512-LktZQb3IeoUWB9lqR5EWTHgW/VTITCXg4D21M+lvybRVdylLrRMnqaIONLVb5mav8vM19m44HIcGq4qASeu2Qw==} - engines: {node: '>=16'} - tr46@5.1.1: resolution: {integrity: sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==} engines: {node: '>=18'} @@ -3299,21 +3012,27 @@ packages: tw-animate-css@1.4.0: resolution: {integrity: sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ==} - type-fest@5.5.0: - resolution: {integrity: sha512-PlBfpQwiUvGViBNX84Yxwjsdhd1TUlXr6zjX7eoirtCPIr08NAmxwa+fcYBTeRQxHo9YC9wwF3m9i700sHma8g==} - engines: {node: '>=20'} - - type-is@2.0.1: - resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==} - engines: {node: '>= 0.6'} + type-is@2.1.0: + resolution: {integrity: sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==} + engines: {node: '>= 18'} - typescript@5.7.3: - resolution: {integrity: sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==} + typescript@6.0.3: + resolution: {integrity: sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==} engines: {node: '>=14.17'} hasBin: true - undici-types@6.19.8: - resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} + ufo@1.6.4: + resolution: {integrity: sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==} + + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + + undici@7.28.0: + resolution: {integrity: sha512-cRZYrTDwWznlnRiPjggAGxZXanty6M8RV1ff8Wm4LWXBp7/IG8v5DnOm74DtUBp9OONpK75YlPnIjQqX0dBDtA==} + engines: {node: '>=20.18.1'} + + unenv@2.0.0-rc.24: + resolution: {integrity: sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw==} unicorn-magic@0.3.0: resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==} @@ -3327,8 +3046,112 @@ packages: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} - until-async@3.0.2: - resolution: {integrity: sha512-IiSk4HlzAMqTUseHHe3VhIGyuFmN90zMTpD3Z3y8jeQbzLIq500MVM7Jq2vUAnTKAFPJrqwkzr6PoTcPhGcOiw==} + unplugin@3.3.0: + resolution: {integrity: sha512-qa66K+crbfyE6JK10GjvbJeRrOsuC/JpbnHctfyp/i4oBTxWOzJfRZyDiOk1PtErMFRu8JhsU/wPvOdBNWe5Rg==} + engines: {node: ^20.19.0 || >=22.12.0} + peerDependencies: + '@farmfe/core': '*' + '@rspack/core': '*' + bun-types-no-globals: '*' + esbuild: '*' + rolldown: '*' + rollup: '*' + unloader: '*' + vite: '*' + webpack: '*' + peerDependenciesMeta: + '@farmfe/core': + optional: true + '@rspack/core': + optional: true + bun-types-no-globals: + optional: true + esbuild: + optional: true + rolldown: + optional: true + rollup: + optional: true + unloader: + optional: true + vite: + optional: true + webpack: + optional: true + + unstorage@2.0.0-alpha.7: + resolution: {integrity: sha512-ELPztchk2zgFJnakyodVY3vJWGW9jy//keJ32IOJVGUMyaPydwcA1FtVvWqT0TNRch9H+cMNEGllfVFfScImog==} + peerDependencies: + '@azure/app-configuration': ^1.11.0 + '@azure/cosmos': ^4.9.1 + '@azure/data-tables': ^13.3.2 + '@azure/identity': ^4.13.0 + '@azure/keyvault-secrets': ^4.10.0 + '@azure/storage-blob': ^12.31.0 + '@capacitor/preferences': ^6 || ^7 || ^8 + '@deno/kv': '>=0.13.0' + '@netlify/blobs': ^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0 + '@planetscale/database': ^1.19.0 + '@upstash/redis': ^1.36.2 + '@vercel/blob': '>=0.27.3' + '@vercel/functions': ^2.2.12 || ^3.0.0 + '@vercel/kv': ^1.0.1 + aws4fetch: ^1.0.20 + chokidar: ^4 || ^5 + db0: '>=0.3.4' + idb-keyval: ^6.2.2 + ioredis: ^5.9.3 + lru-cache: ^11.2.6 + mongodb: ^6 || ^7 + ofetch: '*' + uploadthing: ^7.7.4 + peerDependenciesMeta: + '@azure/app-configuration': + optional: true + '@azure/cosmos': + optional: true + '@azure/data-tables': + optional: true + '@azure/identity': + optional: true + '@azure/keyvault-secrets': + optional: true + '@azure/storage-blob': + optional: true + '@capacitor/preferences': + optional: true + '@deno/kv': + optional: true + '@netlify/blobs': + optional: true + '@planetscale/database': + optional: true + '@upstash/redis': + optional: true + '@vercel/blob': + optional: true + '@vercel/functions': + optional: true + '@vercel/kv': + optional: true + aws4fetch: + optional: true + chokidar: + optional: true + db0: + optional: true + idb-keyval: + optional: true + ioredis: + optional: true + lru-cache: + optional: true + mongodb: + optional: true + ofetch: + optional: true + uploadthing: + optional: true update-browserslist-db@1.2.3: resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} @@ -3372,14 +3195,64 @@ packages: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} - web-streams-polyfill@3.3.3: - resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} - engines: {node: '>= 8'} + vite@8.1.4: + resolution: {integrity: sha512-bTT9PsdWO+MQMNG9ZXIP/qM9wGh37DFxTV/sPq9cFpHr3w4jkgef032PkAL9jAqhk3Nz8NQw3O8n6/xFkqO4QQ==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + '@vitejs/devtools': ^0.3.0 + esbuild: ^0.27.0 || ^0.28.0 + jiti: '>=1.21.0' + less: ^4.0.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + '@vitejs/devtools': + optional: true + esbuild: + optional: true + jiti: + optional: true + less: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + vitefu@1.1.3: + resolution: {integrity: sha512-ub4okH7Z5KLjb6hDyjqrGXqWtWvoYdU3IGm/NorpgHncKoLTCfRIbvlhBm7r0YstIaQRYlp4yEbFqDcKSzXSSg==} + peerDependencies: + vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 + peerDependenciesMeta: + vite: + optional: true webidl-conversions@7.0.0: resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} engines: {node: '>=12'} + webpack-virtual-modules@0.6.2: + resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} + whatwg-url@14.2.0: resolution: {integrity: sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==} engines: {node: '>=18'} @@ -3394,14 +3267,6 @@ packages: engines: {node: ^16.13.0 || >=18.0.0} hasBin: true - wrap-ansi@6.2.0: - resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} - engines: {node: '>=8'} - - wrap-ansi@7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} - engines: {node: '>=10'} - wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} @@ -3409,29 +3274,17 @@ packages: resolution: {integrity: sha512-g/eziiSUNBSsdDJtCLB8bdYEUMj4jR7AGeUo96p/3dTafgjHhpF4RiCFPiRILwjQoDXx5MqkBr4fwWtR3Ky4Wg==} engines: {node: '>=20'} - y18n@5.0.8: - resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} - engines: {node: '>=10'} + xmlbuilder2@4.0.3: + resolution: {integrity: sha512-bx8Q1STctnNaaDymWnkfQLKofs0mGNN7rLLapJlGuV3VlvegD7Ls4ggMjE3aUSWItCCzU0PEv45lI87iSigiCA==} + engines: {node: '>=20.0'} yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} - yargs-parser@21.1.1: - resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} - engines: {node: '>=12'} - - yargs@17.7.2: - resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} - engines: {node: '>=12'} - - yocto-spinner@1.1.0: - resolution: {integrity: sha512-/BY0AUXnS7IKO354uLLA2eRcWiqDifEbd6unXCsOxkFDAkhgUL3PH9X2bFoaU0YchnDXsF+iKleeTLJGckbXfA==} + yocto-spinner@1.2.1: + resolution: {integrity: sha512-9cbFWLhbiZp+820O4pkHGNncI7+MrUGzBOjw8NMG+ewsY+aG0DdEXnr19Smxao32YOjLZRMdn1UtaxcrXOYOIg==} engines: {node: '>=18.19'} - yoctocolors-cjs@2.1.3: - resolution: {integrity: sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==} - engines: {node: '>=18'} - yoctocolors@2.1.2: resolution: {integrity: sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==} engines: {node: '>=18'} @@ -3450,9 +3303,16 @@ packages: zod@4.3.6: resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==} + zod@4.4.3: + resolution: {integrity: sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==} + snapshots: - '@alloc/quick-lru@5.2.0': {} + '@babel/code-frame@7.27.1': + dependencies: + '@babel/helper-validator-identifier': 7.29.7 + js-tokens: 4.0.0 + picocolors: 1.1.1 '@babel/code-frame@7.29.0': dependencies: @@ -3460,6 +3320,12 @@ snapshots: js-tokens: 4.0.0 picocolors: 1.1.1 + '@babel/code-frame@7.29.7': + dependencies: + '@babel/helper-validator-identifier': 7.29.7 + js-tokens: 4.0.0 + picocolors: 1.1.1 + '@babel/compat-data@7.29.0': {} '@babel/core@7.29.0': @@ -3490,9 +3356,17 @@ snapshots: '@jridgewell/trace-mapping': 0.3.31 jsesc: 3.1.0 - '@babel/helper-annotate-as-pure@7.27.3': + '@babel/generator@7.29.7': + dependencies: + '@babel/parser': 7.29.7 + '@babel/types': 7.29.7 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 + + '@babel/helper-annotate-as-pure@7.29.7': dependencies: - '@babel/types': 7.28.2 + '@babel/types': 7.29.7 '@babel/helper-compilation-targets@7.28.6': dependencies: @@ -3502,25 +3376,27 @@ snapshots: lru-cache: 5.1.1 semver: 6.3.1 - '@babel/helper-create-class-features-plugin@7.28.6(@babel/core@7.29.0)': + '@babel/helper-create-class-features-plugin@7.29.7(@babel/core@7.29.0)': dependencies: '@babel/core': 7.29.0 - '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-member-expression-to-functions': 7.28.5 - '@babel/helper-optimise-call-expression': 7.27.1 - '@babel/helper-replace-supers': 7.28.6(@babel/core@7.29.0) - '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - '@babel/traverse': 7.29.0 + '@babel/helper-annotate-as-pure': 7.29.7 + '@babel/helper-member-expression-to-functions': 7.29.7 + '@babel/helper-optimise-call-expression': 7.29.7 + '@babel/helper-replace-supers': 7.29.7(@babel/core@7.29.0) + '@babel/helper-skip-transparent-expression-wrappers': 7.29.7 + '@babel/traverse': 7.29.7 semver: 6.3.1 transitivePeerDependencies: - supports-color '@babel/helper-globals@7.28.0': {} - '@babel/helper-member-expression-to-functions@7.28.5': + '@babel/helper-globals@7.29.7': {} + + '@babel/helper-member-expression-to-functions@7.29.7': dependencies: - '@babel/traverse': 7.29.0 - '@babel/types': 7.29.0 + '@babel/traverse': 7.29.7 + '@babel/types': 7.29.7 transitivePeerDependencies: - supports-color @@ -3531,6 +3407,13 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/helper-module-imports@7.29.7': + dependencies: + '@babel/traverse': 7.29.7 + '@babel/types': 7.29.7 + transitivePeerDependencies: + - supports-color + '@babel/helper-module-transforms@7.28.6(@babel/core@7.29.0)': dependencies: '@babel/core': 7.29.0 @@ -3540,36 +3423,49 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/helper-optimise-call-expression@7.27.1': + '@babel/helper-module-transforms@7.29.7(@babel/core@7.29.0)': dependencies: - '@babel/types': 7.28.2 + '@babel/core': 7.29.0 + '@babel/helper-module-imports': 7.29.7 + '@babel/helper-validator-identifier': 7.29.7 + '@babel/traverse': 7.29.7 + transitivePeerDependencies: + - supports-color + + '@babel/helper-optimise-call-expression@7.29.7': + dependencies: + '@babel/types': 7.29.7 - '@babel/helper-plugin-utils@7.28.6': {} + '@babel/helper-plugin-utils@7.29.7': {} - '@babel/helper-replace-supers@7.28.6(@babel/core@7.29.0)': + '@babel/helper-replace-supers@7.29.7(@babel/core@7.29.0)': dependencies: '@babel/core': 7.29.0 - '@babel/helper-member-expression-to-functions': 7.28.5 - '@babel/helper-optimise-call-expression': 7.27.1 - '@babel/traverse': 7.29.0 + '@babel/helper-member-expression-to-functions': 7.29.7 + '@babel/helper-optimise-call-expression': 7.29.7 + '@babel/traverse': 7.29.7 transitivePeerDependencies: - supports-color - '@babel/helper-skip-transparent-expression-wrappers@7.27.1': + '@babel/helper-skip-transparent-expression-wrappers@7.29.7': dependencies: - '@babel/traverse': 7.29.0 - '@babel/types': 7.28.2 + '@babel/traverse': 7.29.7 + '@babel/types': 7.29.7 transitivePeerDependencies: - supports-color '@babel/helper-string-parser@7.27.1': {} - '@babel/helper-validator-identifier@7.27.1': {} + '@babel/helper-string-parser@7.29.7': {} '@babel/helper-validator-identifier@7.28.5': {} + '@babel/helper-validator-identifier@7.29.7': {} + '@babel/helper-validator-option@7.27.1': {} + '@babel/helper-validator-option@7.29.7': {} + '@babel/helpers@7.29.2': dependencies: '@babel/template': 7.28.6 @@ -3579,47 +3475,51 @@ snapshots: dependencies: '@babel/types': 7.29.0 - '@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0)': + '@babel/parser@7.29.7': + dependencies: + '@babel/types': 7.29.7 + + '@babel/plugin-syntax-jsx@7.29.7(@babel/core@7.29.0)': dependencies: '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-syntax-typescript@7.28.6(@babel/core@7.29.0)': + '@babel/plugin-syntax-typescript@7.29.7(@babel/core@7.29.0)': dependencies: '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-transform-modules-commonjs@7.28.6(@babel/core@7.29.0)': + '@babel/plugin-transform-modules-commonjs@7.29.7(@babel/core@7.29.0)': dependencies: '@babel/core': 7.29.0 - '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) - '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.29.7 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-typescript@7.28.6(@babel/core@7.29.0)': + '@babel/plugin-transform-typescript@7.29.7(@babel/core@7.29.0)': dependencies: '@babel/core': 7.29.0 - '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) - '@babel/helper-plugin-utils': 7.28.6 - '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - '@babel/plugin-syntax-typescript': 7.28.6(@babel/core@7.29.0) + '@babel/helper-annotate-as-pure': 7.29.7 + '@babel/helper-create-class-features-plugin': 7.29.7(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.29.7 + '@babel/helper-skip-transparent-expression-wrappers': 7.29.7 + '@babel/plugin-syntax-typescript': 7.29.7(@babel/core@7.29.0) transitivePeerDependencies: - supports-color - '@babel/preset-typescript@7.28.5(@babel/core@7.29.0)': + '@babel/preset-typescript@7.29.7(@babel/core@7.29.0)': dependencies: '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/helper-validator-option': 7.27.1 - '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-modules-commonjs': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-typescript': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.29.7 + '@babel/helper-validator-option': 7.29.7 + '@babel/plugin-syntax-jsx': 7.29.7(@babel/core@7.29.0) + '@babel/plugin-transform-modules-commonjs': 7.29.7(@babel/core@7.29.0) + '@babel/plugin-transform-typescript': 7.29.7(@babel/core@7.29.0) transitivePeerDependencies: - supports-color - '@babel/runtime@7.29.2': {} + '@babel/runtime@7.29.7': {} '@babel/template@7.28.6': dependencies: @@ -3627,6 +3527,12 @@ snapshots: '@babel/parser': 7.29.2 '@babel/types': 7.29.0 + '@babel/template@7.29.7': + dependencies: + '@babel/code-frame': 7.29.7 + '@babel/parser': 7.29.7 + '@babel/types': 7.29.7 + '@babel/traverse@7.29.0': dependencies: '@babel/code-frame': 7.29.0 @@ -3639,39 +3545,52 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/types@7.28.2': + '@babel/traverse@7.29.7': dependencies: - '@babel/helper-string-parser': 7.27.1 - '@babel/helper-validator-identifier': 7.27.1 + '@babel/code-frame': 7.29.7 + '@babel/generator': 7.29.7 + '@babel/helper-globals': 7.29.7 + '@babel/parser': 7.29.7 + '@babel/template': 7.29.7 + '@babel/types': 7.29.7 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color '@babel/types@7.29.0': dependencies: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.28.5 - '@base-ui/react@1.3.0(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@babel/types@7.29.7': + dependencies: + '@babel/helper-string-parser': 7.29.7 + '@babel/helper-validator-identifier': 7.29.7 + + '@base-ui/react@1.6.0(@date-fns/tz@1.5.0)(@types/react@19.2.17)(date-fns@4.4.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': dependencies: - '@babel/runtime': 7.29.2 - '@base-ui/utils': 0.2.6(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@floating-ui/react-dom': 2.1.8(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@babel/runtime': 7.29.7 + '@base-ui/utils': 0.3.1(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@floating-ui/react-dom': 2.1.8(react-dom@19.2.7(react@19.2.7))(react@19.2.7) '@floating-ui/utils': 0.2.11 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - tabbable: 6.4.0 - use-sync-external-store: 1.6.0(react@18.3.1) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + use-sync-external-store: 1.6.0(react@19.2.7) optionalDependencies: - '@types/react': 18.3.18 + '@date-fns/tz': 1.5.0 + '@types/react': 19.2.17 + date-fns: 4.4.0 - '@base-ui/utils@0.2.6(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@base-ui/utils@0.3.1(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': dependencies: - '@babel/runtime': 7.29.2 + '@babel/runtime': 7.29.7 '@floating-ui/utils': 0.2.11 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - reselect: 5.1.1 - use-sync-external-store: 1.6.0(react@18.3.1) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + reselect: 5.2.0 + use-sync-external-store: 1.6.0(react@19.2.7) optionalDependencies: - '@types/react': 18.3.18 + '@types/react': 19.2.17 '@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.1.3)(kysely@0.28.12)(nanostores@1.2.0)': dependencies: @@ -3706,14 +3625,14 @@ snapshots: '@better-auth/utils': 0.3.1 mongodb: 7.1.0 - '@better-auth/passkey@1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.1.3)(kysely@0.28.12)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-auth@1.5.5(mongodb@7.1.0)(next@15.5.18(@babel/core@7.29.0)(babel-plugin-react-compiler@1.0.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(better-call@1.3.2(zod@4.3.5))(nanostores@1.2.0)': + '@better-auth/passkey@1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.1.3)(kysely@0.28.12)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-auth@1.5.5(@tanstack/react-start@1.168.27(crossws@0.4.9(srvx@0.11.21))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(rolldown@1.1.5)(vite@8.1.4(@types/node@22.20.1)(jiti@2.7.0)))(mongodb@7.1.0)(next@15.5.18(@babel/core@7.29.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(solid-js@1.9.14))(better-call@1.3.2(zod@4.3.5))(nanostores@1.2.0)': dependencies: '@better-auth/core': 1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.1.3)(kysely@0.28.12)(nanostores@1.2.0) '@better-auth/utils': 0.3.1 '@better-fetch/fetch': 1.1.21 '@simplewebauthn/browser': 13.2.2 '@simplewebauthn/server': 13.3.0 - better-auth: 1.5.5(mongodb@7.1.0)(next@15.5.18(@babel/core@7.29.0)(babel-plugin-react-compiler@1.0.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + better-auth: 1.5.5(@tanstack/react-start@1.168.27(crossws@0.4.9(srvx@0.11.21))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(rolldown@1.1.5)(vite@8.1.4(@types/node@22.20.1)(jiti@2.7.0)))(mongodb@7.1.0)(next@15.5.18(@babel/core@7.29.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(solid-js@1.9.14) better-call: 1.3.2(zod@4.3.5) nanostores: 1.2.0 zod: 4.3.6 @@ -3768,73 +3687,67 @@ snapshots: '@biomejs/cli-win32-x64@2.3.10': optional: true - '@date-fns/tz@1.4.1': {} + '@date-fns/tz@1.5.0': {} - '@dotenvx/dotenvx@1.61.0': + '@dotenvx/dotenvx@1.75.1': dependencies: + '@dotenvx/primitives': 0.8.0 commander: 11.1.0 - dotenv: 17.4.1 - eciesjs: 0.4.18 + conf: 10.2.0 + dotenv: 17.4.2 + enquirer: 2.4.1 + env-paths: 2.2.1 execa: 5.1.1 - fdir: 6.5.0(picomatch@4.0.4) + fdir: 6.5.0(picomatch@4.0.5) ignore: 5.3.2 object-treeify: 1.1.33 - picomatch: 4.0.4 + open: 8.4.2 + picomatch: 4.0.5 + systeminformation: 5.31.15 + undici: 7.28.0 which: 4.0.0 - yocto-spinner: 1.1.0 + yocto-spinner: 1.2.1 - '@ecies/ciphers@0.2.6(@noble/ciphers@1.3.0)': + '@dotenvx/primitives@0.8.0': {} + + '@emnapi/core@1.11.1': dependencies: - '@noble/ciphers': 1.3.0 + '@emnapi/wasi-threads': 1.2.2 + tslib: 2.8.1 + optional: true - '@emnapi/runtime@1.10.0': + '@emnapi/runtime@1.11.1': dependencies: tslib: 2.8.1 optional: true - '@floating-ui/core@1.6.9': + '@emnapi/wasi-threads@1.2.2': dependencies: - '@floating-ui/utils': 0.2.9 + tslib: 2.8.1 + optional: true '@floating-ui/core@1.7.5': dependencies: '@floating-ui/utils': 0.2.11 - '@floating-ui/dom@1.6.13': - dependencies: - '@floating-ui/core': 1.6.9 - '@floating-ui/utils': 0.2.9 - '@floating-ui/dom@1.7.6': dependencies: '@floating-ui/core': 1.7.5 '@floating-ui/utils': 0.2.11 - '@floating-ui/react-dom@2.1.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@floating-ui/dom': 1.6.13 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - - '@floating-ui/react-dom@2.1.8(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@floating-ui/react-dom@2.1.8(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': dependencies: '@floating-ui/dom': 1.7.6 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) '@floating-ui/utils@0.2.11': {} - '@floating-ui/utils@0.2.9': {} - '@hexagon/base64@1.1.28': {} - '@hono/node-server@1.19.13(hono@4.12.12)': + '@hono/node-server@1.19.14(hono@4.12.29)': dependencies: - hono: 4.12.12 - - '@hookform/resolvers@3.10.0(react-hook-form@7.55.0(react@18.3.1))': - dependencies: - react-hook-form: 7.55.0(react@18.3.1) + hono: 4.12.29 '@img/colour@1.1.0': optional: true @@ -3921,7 +3834,7 @@ snapshots: '@img/sharp-wasm32@0.34.5': dependencies: - '@emnapi/runtime': 1.10.0 + '@emnapi/runtime': 1.11.1 optional: true '@img/sharp-win32-arm64@0.34.5': @@ -3933,34 +3846,6 @@ snapshots: '@img/sharp-win32-x64@0.34.5': optional: true - '@inquirer/ansi@1.0.2': {} - - '@inquirer/confirm@5.1.21(@types/node@20.17.19)': - dependencies: - '@inquirer/core': 10.3.2(@types/node@20.17.19) - '@inquirer/type': 3.0.10(@types/node@20.17.19) - optionalDependencies: - '@types/node': 20.17.19 - - '@inquirer/core@10.3.2(@types/node@20.17.19)': - dependencies: - '@inquirer/ansi': 1.0.2 - '@inquirer/figures': 1.0.15 - '@inquirer/type': 3.0.10(@types/node@20.17.19) - cli-width: 4.1.0 - mute-stream: 2.0.0 - signal-exit: 4.1.0 - wrap-ansi: 6.2.0 - yoctocolors-cjs: 2.1.3 - optionalDependencies: - '@types/node': 20.17.19 - - '@inquirer/figures@1.0.15': {} - - '@inquirer/type@3.0.10(@types/node@20.17.19)': - optionalDependencies: - '@types/node': 20.17.19 - '@jridgewell/gen-mapping@0.3.13': dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -3984,17 +3869,17 @@ snapshots: '@modelcontextprotocol/sdk@1.29.0(zod@3.25.76)': dependencies: - '@hono/node-server': 1.19.13(hono@4.12.12) - ajv: 8.18.0 - ajv-formats: 3.0.1(ajv@8.18.0) + '@hono/node-server': 1.19.14(hono@4.12.29) + ajv: 8.20.0 + ajv-formats: 3.0.1(ajv@8.20.0) content-type: 1.0.5 cors: 2.8.6 cross-spawn: 7.0.6 eventsource: 3.0.7 - eventsource-parser: 3.0.6 + eventsource-parser: 3.1.0 express: 5.2.1 - express-rate-limit: 8.3.2(express@5.2.1) - hono: 4.12.12 + express-rate-limit: 8.5.2(express@5.2.1) + hono: 4.12.29 jose: 6.1.3 json-schema-typed: 8.0.2 pkce-challenge: 5.0.1 @@ -4008,16 +3893,15 @@ snapshots: dependencies: sparse-bitfield: 3.0.3 - '@mswjs/interceptors@0.41.3': + '@napi-rs/wasm-runtime@1.1.6(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)': dependencies: - '@open-draft/deferred-promise': 2.2.0 - '@open-draft/logger': 0.3.0 - '@open-draft/until': 2.1.0 - is-node-process: 1.2.0 - outvariant: 1.4.3 - strict-event-emitter: 0.5.1 + '@emnapi/core': 1.11.1 + '@emnapi/runtime': 1.11.1 + '@tybys/wasm-util': 0.10.3 + optional: true - '@next/env@15.5.18': {} + '@next/env@15.5.18': + optional: true '@next/swc-darwin-arm64@15.5.18': optional: true @@ -4043,16 +3927,8 @@ snapshots: '@next/swc-win32-x64-msvc@15.5.18': optional: true - '@noble/ciphers@1.3.0': {} - '@noble/ciphers@2.1.1': {} - '@noble/curves@1.9.7': - dependencies: - '@noble/hashes': 1.8.0 - - '@noble/hashes@1.8.0': {} - '@noble/hashes@2.0.1': {} '@nodelib/fs.scandir@2.1.5': @@ -4067,14 +3943,24 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.20.1 - '@open-draft/deferred-promise@2.2.0': {} + '@oozcitak/dom@2.0.2': + dependencies: + '@oozcitak/infra': 2.0.2 + '@oozcitak/url': 3.0.0 + '@oozcitak/util': 10.0.0 + + '@oozcitak/infra@2.0.2': + dependencies: + '@oozcitak/util': 10.0.0 - '@open-draft/logger@0.3.0': + '@oozcitak/url@3.0.0': dependencies: - is-node-process: 1.2.0 - outvariant: 1.4.3 + '@oozcitak/infra': 2.0.2 + '@oozcitak/util': 10.0.0 + + '@oozcitak/util@10.0.0': {} - '@open-draft/until@2.1.0': {} + '@oxc-project/types@0.139.0': {} '@peculiar/asn1-android@2.6.0': dependencies: @@ -4174,787 +4060,193 @@ snapshots: '@polinetwork/backend@0.17.0': {} - '@radix-ui/number@1.1.1': {} + '@radix-ui/primitive@1.1.6': {} - '@radix-ui/primitive@1.1.3': {} - - '@radix-ui/react-accessible-icon@1.1.7(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) - - '@radix-ui/react-accordion@1.2.12(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-collapsible': 1.1.12(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-collection': 1.1.7(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-direction': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-id': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.18)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) - - '@radix-ui/react-alert-dialog@1.1.15(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-dialog': 1.1.15(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slot': 1.2.3(@types/react@18.3.18)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) - - '@radix-ui/react-arrow@1.1.7(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) - - '@radix-ui/react-aspect-ratio@1.1.7(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) - - '@radix-ui/react-avatar@1.1.10(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/react-context': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-is-hydrated': 0.1.0(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.18)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) - - '@radix-ui/react-checkbox@1.3.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-previous': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-size': 1.1.1(@types/react@18.3.18)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) - - '@radix-ui/react-collapsible@1.1.12(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-id': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.18)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) - - '@radix-ui/react-collection@1.1.7(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slot': 1.2.3(@types/react@18.3.18)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) - - '@radix-ui/react-compose-refs@1.1.1(@types/react@18.3.18)(react@18.3.1)': - dependencies: - react: 18.3.1 - optionalDependencies: - '@types/react': 18.3.18 - - '@radix-ui/react-compose-refs@1.1.2(@types/react@18.3.18)(react@18.3.1)': + '@radix-ui/react-compose-refs@1.1.3(@types/react@19.2.17)(react@19.2.7)': dependencies: - react: 18.3.1 - optionalDependencies: - '@types/react': 18.3.18 - - '@radix-ui/react-context-menu@2.2.16(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-context': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-menu': 2.1.16(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.18)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + react: 19.2.7 optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) + '@types/react': 19.2.17 - '@radix-ui/react-context@1.1.2(@types/react@18.3.18)(react@18.3.1)': + '@radix-ui/react-context@1.2.0(@types/react@19.2.17)(react@19.2.7)': dependencies: - react: 18.3.1 + react: 19.2.7 optionalDependencies: - '@types/react': 18.3.18 - - '@radix-ui/react-dialog@1.1.15(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-focus-guards': 1.1.3(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-id': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slot': 1.2.3(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.18)(react@18.3.1) - aria-hidden: 1.2.4 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - react-remove-scroll: 2.6.3(@types/react@18.3.18)(react@18.3.1) + '@types/react': 19.2.17 + + '@radix-ui/react-dialog@1.1.20(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': + dependencies: + '@radix-ui/primitive': 1.1.6 + '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.17)(react@19.2.7) + '@radix-ui/react-context': 1.2.0(@types/react@19.2.17)(react@19.2.7) + '@radix-ui/react-dismissable-layer': 1.1.16(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@radix-ui/react-focus-guards': 1.1.4(@types/react@19.2.17)(react@19.2.7) + '@radix-ui/react-focus-scope': 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@radix-ui/react-id': 1.1.2(@types/react@19.2.17)(react@19.2.7) + '@radix-ui/react-portal': 1.1.14(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@radix-ui/react-presence': 1.1.8(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@radix-ui/react-primitive': 2.1.7(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@radix-ui/react-slot': 1.3.0(@types/react@19.2.17)(react@19.2.7) + '@radix-ui/react-use-controllable-state': 1.2.4(@types/react@19.2.17)(react@19.2.7) + '@radix-ui/react-use-layout-effect': 1.1.2(@types/react@19.2.17)(react@19.2.7) + aria-hidden: 1.2.6 + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + react-remove-scroll: 2.7.2(@types/react@19.2.17)(react@19.2.7) optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) - - '@radix-ui/react-direction@1.1.1(@types/react@18.3.18)(react@18.3.1)': - dependencies: - react: 18.3.1 + '@types/react': 19.2.17 + '@types/react-dom': 19.2.3(@types/react@19.2.17) + + '@radix-ui/react-dismissable-layer@1.1.16(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': + dependencies: + '@radix-ui/primitive': 1.1.6 + '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.17)(react@19.2.7) + '@radix-ui/react-primitive': 2.1.7(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@radix-ui/react-use-callback-ref': 1.1.2(@types/react@19.2.17)(react@19.2.7) + '@radix-ui/react-use-effect-event': 0.0.3(@types/react@19.2.17)(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) optionalDependencies: - '@types/react': 18.3.18 + '@types/react': 19.2.17 + '@types/react-dom': 19.2.3(@types/react@19.2.17) - '@radix-ui/react-dismissable-layer@1.1.11(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-focus-guards@1.1.4(@types/react@19.2.17)(react@19.2.7)': dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@18.3.18)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + react: 19.2.7 optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) - - '@radix-ui/react-dropdown-menu@2.1.16(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-id': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-menu': 2.1.16(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.18)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) + '@types/react': 19.2.17 - '@radix-ui/react-focus-guards@1.1.3(@types/react@18.3.18)(react@18.3.1)': + '@radix-ui/react-focus-scope@1.1.13(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': dependencies: - react: 18.3.1 + '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.17)(react@19.2.7) + '@radix-ui/react-primitive': 2.1.7(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@radix-ui/react-use-callback-ref': 1.1.2(@types/react@19.2.17)(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) optionalDependencies: - '@types/react': 18.3.18 + '@types/react': 19.2.17 + '@types/react-dom': 19.2.3(@types/react@19.2.17) - '@radix-ui/react-focus-scope@1.1.7(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-id@1.1.2(@types/react@19.2.17)(react@19.2.7)': dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.18)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) - - '@radix-ui/react-form@0.1.8(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-id': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-label': 2.1.7(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.2(@types/react@19.2.17)(react@19.2.7) + react: 19.2.7 optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) - - '@radix-ui/react-hover-card@1.1.15(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-popper': 1.2.8(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.18)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) + '@types/react': 19.2.17 - '@radix-ui/react-id@1.1.0(@types/react@18.3.18)(react@18.3.1)': + '@radix-ui/react-portal@1.1.14(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': dependencies: - '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.18)(react@18.3.1) - react: 18.3.1 + '@radix-ui/react-primitive': 2.1.7(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@radix-ui/react-use-layout-effect': 1.1.2(@types/react@19.2.17)(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) optionalDependencies: - '@types/react': 18.3.18 + '@types/react': 19.2.17 + '@types/react-dom': 19.2.3(@types/react@19.2.17) - '@radix-ui/react-id@1.1.1(@types/react@18.3.18)(react@18.3.1)': + '@radix-ui/react-presence@1.1.8(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': dependencies: - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.18)(react@18.3.1) - react: 18.3.1 + '@radix-ui/react-use-layout-effect': 1.1.2(@types/react@19.2.17)(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) optionalDependencies: - '@types/react': 18.3.18 + '@types/react': 19.2.17 + '@types/react-dom': 19.2.3(@types/react@19.2.17) - '@radix-ui/react-label@2.1.7(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-primitive@2.1.7(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': dependencies: - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) - - '@radix-ui/react-menu@2.1.16(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-collection': 1.1.7(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-direction': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-focus-guards': 1.1.3(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-id': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-popper': 1.2.8(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slot': 1.2.3(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.18)(react@18.3.1) - aria-hidden: 1.2.4 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - react-remove-scroll: 2.6.3(@types/react@18.3.18)(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) - - '@radix-ui/react-menubar@1.1.16(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-collection': 1.1.7(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-direction': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-id': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-menu': 2.1.16(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.18)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) - - '@radix-ui/react-navigation-menu@1.2.14(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-collection': 1.1.7(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-direction': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-id': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-previous': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) - - '@radix-ui/react-one-time-password-field@0.1.8(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/number': 1.1.1 - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-collection': 1.1.7(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-direction': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-effect-event': 0.0.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-is-hydrated': 0.1.0(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.18)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) - - '@radix-ui/react-password-toggle-field@0.1.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-id': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-effect-event': 0.0.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-is-hydrated': 0.1.0(@types/react@18.3.18)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + '@radix-ui/react-slot': 1.3.0(@types/react@19.2.17)(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) - - '@radix-ui/react-popover@1.1.15(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-focus-guards': 1.1.3(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-id': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-popper': 1.2.8(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slot': 1.2.3(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.18)(react@18.3.1) - aria-hidden: 1.2.4 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - react-remove-scroll: 2.6.3(@types/react@18.3.18)(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) - - '@radix-ui/react-popper@1.2.8(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@floating-ui/react-dom': 2.1.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-arrow': 1.1.7(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-rect': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-size': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/rect': 1.1.1 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) + '@types/react': 19.2.17 + '@types/react-dom': 19.2.3(@types/react@19.2.17) - '@radix-ui/react-portal@1.1.9(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-slot@1.3.0(@types/react@19.2.17)(react@19.2.7)': dependencies: - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.18)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.17)(react@19.2.7) + react: 19.2.7 optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) + '@types/react': 19.2.17 - '@radix-ui/react-presence@1.1.5(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-use-callback-ref@1.1.2(@types/react@19.2.17)(react@19.2.7)': dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.18)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + react: 19.2.7 optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) + '@types/react': 19.2.17 - '@radix-ui/react-primitive@2.0.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-use-controllable-state@1.2.4(@types/react@19.2.17)(react@19.2.7)': dependencies: - '@radix-ui/react-slot': 1.1.2(@types/react@18.3.18)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + '@radix-ui/primitive': 1.1.6 + '@radix-ui/react-use-effect-event': 0.0.3(@types/react@19.2.17)(react@19.2.7) + '@radix-ui/react-use-layout-effect': 1.1.2(@types/react@19.2.17)(react@19.2.7) + react: 19.2.7 optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) + '@types/react': 19.2.17 - '@radix-ui/react-primitive@2.1.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-use-effect-event@0.0.3(@types/react@19.2.17)(react@19.2.7)': dependencies: - '@radix-ui/react-slot': 1.2.3(@types/react@18.3.18)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.2(@types/react@19.2.17)(react@19.2.7) + react: 19.2.7 optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) + '@types/react': 19.2.17 - '@radix-ui/react-progress@1.1.7(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-use-layout-effect@1.1.2(@types/react@19.2.17)(react@19.2.7)': dependencies: - '@radix-ui/react-context': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) - - '@radix-ui/react-radio-group@1.3.8(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-direction': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-previous': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-size': 1.1.1(@types/react@18.3.18)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) - - '@radix-ui/react-roving-focus@1.1.11(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-collection': 1.1.7(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-direction': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-id': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.18)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + react: 19.2.7 optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) - - '@radix-ui/react-scroll-area@1.2.10(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/number': 1.1.1 - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-direction': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.18)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) - - '@radix-ui/react-select@2.2.6(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/number': 1.1.1 - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-collection': 1.1.7(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-direction': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-focus-guards': 1.1.3(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-id': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-popper': 1.2.8(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slot': 1.2.3(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-previous': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - aria-hidden: 1.2.4 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - react-remove-scroll: 2.6.3(@types/react@18.3.18)(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) + '@types/react': 19.2.17 - '@radix-ui/react-separator@1.1.7(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) - - '@radix-ui/react-slider@1.3.6(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/number': 1.1.1 - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-collection': 1.1.7(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-direction': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-previous': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-size': 1.1.1(@types/react@18.3.18)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) + '@rolldown/binding-android-arm64@1.1.5': + optional: true - '@radix-ui/react-slot@1.1.2(@types/react@18.3.18)(react@18.3.1)': - dependencies: - '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) - react: 18.3.1 - optionalDependencies: - '@types/react': 18.3.18 + '@rolldown/binding-darwin-arm64@1.1.5': + optional: true - '@radix-ui/react-slot@1.2.3(@types/react@18.3.18)(react@18.3.1)': - dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.18)(react@18.3.1) - react: 18.3.1 - optionalDependencies: - '@types/react': 18.3.18 - - '@radix-ui/react-switch@1.2.6(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-previous': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-size': 1.1.1(@types/react@18.3.18)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) - - '@radix-ui/react-tabs@1.1.13(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-context': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-direction': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-id': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.18)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) - - '@radix-ui/react-toast@1.2.15(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-collection': 1.1.7(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) - - '@radix-ui/react-toggle-group@1.1.11(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-context': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-direction': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-toggle': 1.1.10(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.18)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) + '@rolldown/binding-darwin-x64@1.1.5': + optional: true - '@radix-ui/react-toggle@1.1.10(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.18)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) - - '@radix-ui/react-toolbar@1.1.11(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-context': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-direction': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-separator': 1.1.7(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-toggle-group': 1.1.11(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) - - '@radix-ui/react-tooltip@1.2.8(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-id': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-popper': 1.2.8(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slot': 1.2.3(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) + '@rolldown/binding-freebsd-x64@1.1.5': + optional: true - '@radix-ui/react-use-callback-ref@1.1.1(@types/react@18.3.18)(react@18.3.1)': - dependencies: - react: 18.3.1 - optionalDependencies: - '@types/react': 18.3.18 + '@rolldown/binding-linux-arm-gnueabihf@1.1.5': + optional: true - '@radix-ui/react-use-controllable-state@1.2.2(@types/react@18.3.18)(react@18.3.1)': - dependencies: - '@radix-ui/react-use-effect-event': 0.0.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.18)(react@18.3.1) - react: 18.3.1 - optionalDependencies: - '@types/react': 18.3.18 + '@rolldown/binding-linux-arm64-gnu@1.1.5': + optional: true - '@radix-ui/react-use-effect-event@0.0.2(@types/react@18.3.18)(react@18.3.1)': - dependencies: - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.18)(react@18.3.1) - react: 18.3.1 - optionalDependencies: - '@types/react': 18.3.18 + '@rolldown/binding-linux-arm64-musl@1.1.5': + optional: true - '@radix-ui/react-use-escape-keydown@1.1.1(@types/react@18.3.18)(react@18.3.1)': - dependencies: - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.18)(react@18.3.1) - react: 18.3.1 - optionalDependencies: - '@types/react': 18.3.18 + '@rolldown/binding-linux-ppc64-gnu@1.1.5': + optional: true - '@radix-ui/react-use-is-hydrated@0.1.0(@types/react@18.3.18)(react@18.3.1)': - dependencies: - react: 18.3.1 - use-sync-external-store: 1.6.0(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.18 + '@rolldown/binding-linux-s390x-gnu@1.1.5': + optional: true - '@radix-ui/react-use-layout-effect@1.1.0(@types/react@18.3.18)(react@18.3.1)': - dependencies: - react: 18.3.1 - optionalDependencies: - '@types/react': 18.3.18 + '@rolldown/binding-linux-x64-gnu@1.1.5': + optional: true - '@radix-ui/react-use-layout-effect@1.1.1(@types/react@18.3.18)(react@18.3.1)': - dependencies: - react: 18.3.1 - optionalDependencies: - '@types/react': 18.3.18 + '@rolldown/binding-linux-x64-musl@1.1.5': + optional: true - '@radix-ui/react-use-previous@1.1.1(@types/react@18.3.18)(react@18.3.1)': - dependencies: - react: 18.3.1 - optionalDependencies: - '@types/react': 18.3.18 + '@rolldown/binding-openharmony-arm64@1.1.5': + optional: true - '@radix-ui/react-use-rect@1.1.1(@types/react@18.3.18)(react@18.3.1)': + '@rolldown/binding-wasm32-wasi@1.1.5': dependencies: - '@radix-ui/rect': 1.1.1 - react: 18.3.1 - optionalDependencies: - '@types/react': 18.3.18 + '@emnapi/core': 1.11.1 + '@emnapi/runtime': 1.11.1 + '@napi-rs/wasm-runtime': 1.1.6(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1) + optional: true - '@radix-ui/react-use-size@1.1.1(@types/react@18.3.18)(react@18.3.1)': - dependencies: - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.18)(react@18.3.1) - react: 18.3.1 - optionalDependencies: - '@types/react': 18.3.18 + '@rolldown/binding-win32-arm64-msvc@1.1.5': + optional: true - '@radix-ui/react-visually-hidden@1.2.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) + '@rolldown/binding-win32-x64-msvc@1.1.5': + optional: true - '@radix-ui/rect@1.1.1': {} + '@rolldown/pluginutils@1.0.1': {} '@sec-ant/readable-stream@0.4.1': {} @@ -4978,134 +4270,326 @@ snapshots: '@swc/helpers@0.5.15': dependencies: tslib: 2.8.1 + optional: true - '@t3-oss/env-core@0.13.10(typescript@5.7.3)(zod@4.3.5)': - optionalDependencies: - typescript: 5.7.3 - zod: 4.3.5 - - '@t3-oss/env-nextjs@0.13.10(typescript@5.7.3)(zod@4.3.5)': - dependencies: - '@t3-oss/env-core': 0.13.10(typescript@5.7.3)(zod@4.3.5) + '@t3-oss/env-core@0.13.11(typescript@6.0.3)(zod@4.3.5)': optionalDependencies: - typescript: 5.7.3 + typescript: 6.0.3 zod: 4.3.5 - '@tabby_ai/hijri-converter@1.0.5': {} - - '@tailwindcss/node@4.1.4': + '@tailwindcss/node@4.3.2': dependencies: - enhanced-resolve: 5.18.1 - jiti: 2.4.2 - lightningcss: 1.29.2 - tailwindcss: 4.1.4 + '@jridgewell/remapping': 2.3.5 + enhanced-resolve: 5.21.6 + jiti: 2.7.0 + lightningcss: 1.32.0 + magic-string: 0.30.21 + source-map-js: 1.2.1 + tailwindcss: 4.3.2 - '@tailwindcss/oxide-android-arm64@4.1.4': + '@tailwindcss/oxide-android-arm64@4.3.2': optional: true - '@tailwindcss/oxide-darwin-arm64@4.1.4': + '@tailwindcss/oxide-darwin-arm64@4.3.2': optional: true - '@tailwindcss/oxide-darwin-x64@4.1.4': + '@tailwindcss/oxide-darwin-x64@4.3.2': optional: true - '@tailwindcss/oxide-freebsd-x64@4.1.4': + '@tailwindcss/oxide-freebsd-x64@4.3.2': optional: true - '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.4': + '@tailwindcss/oxide-linux-arm-gnueabihf@4.3.2': optional: true - '@tailwindcss/oxide-linux-arm64-gnu@4.1.4': + '@tailwindcss/oxide-linux-arm64-gnu@4.3.2': optional: true - '@tailwindcss/oxide-linux-arm64-musl@4.1.4': + '@tailwindcss/oxide-linux-arm64-musl@4.3.2': optional: true - '@tailwindcss/oxide-linux-x64-gnu@4.1.4': + '@tailwindcss/oxide-linux-x64-gnu@4.3.2': optional: true - '@tailwindcss/oxide-linux-x64-musl@4.1.4': + '@tailwindcss/oxide-linux-x64-musl@4.3.2': optional: true - '@tailwindcss/oxide-wasm32-wasi@4.1.4': + '@tailwindcss/oxide-wasm32-wasi@4.3.2': optional: true - '@tailwindcss/oxide-win32-arm64-msvc@4.1.4': + '@tailwindcss/oxide-win32-arm64-msvc@4.3.2': optional: true - '@tailwindcss/oxide-win32-x64-msvc@4.1.4': + '@tailwindcss/oxide-win32-x64-msvc@4.3.2': optional: true - '@tailwindcss/oxide@4.1.4': + '@tailwindcss/oxide@4.3.2': optionalDependencies: - '@tailwindcss/oxide-android-arm64': 4.1.4 - '@tailwindcss/oxide-darwin-arm64': 4.1.4 - '@tailwindcss/oxide-darwin-x64': 4.1.4 - '@tailwindcss/oxide-freebsd-x64': 4.1.4 - '@tailwindcss/oxide-linux-arm-gnueabihf': 4.1.4 - '@tailwindcss/oxide-linux-arm64-gnu': 4.1.4 - '@tailwindcss/oxide-linux-arm64-musl': 4.1.4 - '@tailwindcss/oxide-linux-x64-gnu': 4.1.4 - '@tailwindcss/oxide-linux-x64-musl': 4.1.4 - '@tailwindcss/oxide-wasm32-wasi': 4.1.4 - '@tailwindcss/oxide-win32-arm64-msvc': 4.1.4 - '@tailwindcss/oxide-win32-x64-msvc': 4.1.4 - - '@tailwindcss/postcss@4.1.4': - dependencies: - '@alloc/quick-lru': 5.2.0 - '@tailwindcss/node': 4.1.4 - '@tailwindcss/oxide': 4.1.4 - postcss: 8.5.2 - tailwindcss: 4.1.4 - - '@tanstack/query-core@5.90.19': - optional: true + '@tailwindcss/oxide-android-arm64': 4.3.2 + '@tailwindcss/oxide-darwin-arm64': 4.3.2 + '@tailwindcss/oxide-darwin-x64': 4.3.2 + '@tailwindcss/oxide-freebsd-x64': 4.3.2 + '@tailwindcss/oxide-linux-arm-gnueabihf': 4.3.2 + '@tailwindcss/oxide-linux-arm64-gnu': 4.3.2 + '@tailwindcss/oxide-linux-arm64-musl': 4.3.2 + '@tailwindcss/oxide-linux-x64-gnu': 4.3.2 + '@tailwindcss/oxide-linux-x64-musl': 4.3.2 + '@tailwindcss/oxide-wasm32-wasi': 4.3.2 + '@tailwindcss/oxide-win32-arm64-msvc': 4.3.2 + '@tailwindcss/oxide-win32-x64-msvc': 4.3.2 + + '@tailwindcss/vite@4.3.2(vite@8.1.4(@types/node@22.20.1)(jiti@2.7.0))': + dependencies: + '@tailwindcss/node': 4.3.2 + '@tailwindcss/oxide': 4.3.2 + tailwindcss: 4.3.2 + vite: 8.1.4(@types/node@22.20.1)(jiti@2.7.0) + + '@tanstack/history@1.162.0': {} + + '@tanstack/react-router@1.170.17(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': + dependencies: + '@tanstack/history': 1.162.0 + '@tanstack/react-store': 0.9.3(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@tanstack/router-core': 1.171.14 + isbot: 5.2.0 + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + + '@tanstack/react-start-client@1.168.15(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': + dependencies: + '@tanstack/react-router': 1.170.17(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@tanstack/router-core': 1.171.14 + '@tanstack/start-client-core': 1.170.13 + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + + '@tanstack/react-start-rsc@0.1.26(crossws@0.4.9(srvx@0.11.21))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(rolldown@1.1.5)(vite@8.1.4(@types/node@22.20.1)(jiti@2.7.0))': + dependencies: + '@tanstack/react-router': 1.170.17(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@tanstack/router-core': 1.171.14 + '@tanstack/router-utils': 1.162.2 + '@tanstack/start-client-core': 1.170.13 + '@tanstack/start-fn-stubs': 1.162.0 + '@tanstack/start-plugin-core': 1.171.19(@tanstack/react-router@1.170.17(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(crossws@0.4.9(srvx@0.11.21))(rolldown@1.1.5)(vite@8.1.4(@types/node@22.20.1)(jiti@2.7.0)) + '@tanstack/start-server-core': 1.169.16(crossws@0.4.9(srvx@0.11.21)) + '@tanstack/start-storage-context': 1.167.16 + pathe: 2.0.3 + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + transitivePeerDependencies: + - '@farmfe/core' + - '@rsbuild/core' + - bun-types-no-globals + - crossws + - esbuild + - rolldown + - rollup + - supports-color + - unloader + - vite + - vite-plugin-solid + - webpack + + '@tanstack/react-start-server@1.167.21(crossws@0.4.9(srvx@0.11.21))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': + dependencies: + '@tanstack/react-router': 1.170.17(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@tanstack/router-core': 1.171.14 + '@tanstack/start-server-core': 1.169.16(crossws@0.4.9(srvx@0.11.21)) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + transitivePeerDependencies: + - crossws + + '@tanstack/react-start@1.168.27(crossws@0.4.9(srvx@0.11.21))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(rolldown@1.1.5)(vite@8.1.4(@types/node@22.20.1)(jiti@2.7.0))': + dependencies: + '@tanstack/react-router': 1.170.17(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@tanstack/react-start-client': 1.168.15(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@tanstack/react-start-rsc': 0.1.26(crossws@0.4.9(srvx@0.11.21))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(rolldown@1.1.5)(vite@8.1.4(@types/node@22.20.1)(jiti@2.7.0)) + '@tanstack/react-start-server': 1.167.21(crossws@0.4.9(srvx@0.11.21))(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@tanstack/router-utils': 1.162.2 + '@tanstack/start-client-core': 1.170.13 + '@tanstack/start-plugin-core': 1.171.19(@tanstack/react-router@1.170.17(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(crossws@0.4.9(srvx@0.11.21))(rolldown@1.1.5)(vite@8.1.4(@types/node@22.20.1)(jiti@2.7.0)) + '@tanstack/start-server-core': 1.169.16(crossws@0.4.9(srvx@0.11.21)) + pathe: 2.0.3 + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + optionalDependencies: + vite: 8.1.4(@types/node@22.20.1)(jiti@2.7.0) + transitivePeerDependencies: + - '@farmfe/core' + - '@rspack/core' + - bun-types-no-globals + - crossws + - esbuild + - react-server-dom-rspack + - rolldown + - rollup + - supports-color + - unloader + - vite-plugin-solid + - webpack - '@tanstack/react-query@5.90.19(react@18.3.1)': + '@tanstack/react-store@0.11.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': dependencies: - '@tanstack/query-core': 5.90.19 - react: 18.3.1 - optional: true + '@tanstack/store': 0.11.0 + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + use-sync-external-store: 1.6.0(react@19.2.7) + + '@tanstack/react-store@0.9.3(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': + dependencies: + '@tanstack/store': 0.9.3 + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + use-sync-external-store: 1.6.0(react@19.2.7) - '@tanstack/react-table@8.21.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@tanstack/react-table@9.0.0-beta.38(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': dependencies: - '@tanstack/table-core': 8.21.2 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + '@tanstack/react-store': 0.11.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@tanstack/table-core': 9.0.0-beta.38 + react: 19.2.7 + transitivePeerDependencies: + - react-dom - '@tanstack/table-core@8.21.2': {} + '@tanstack/router-core@1.171.14': + dependencies: + '@tanstack/history': 1.162.0 + cookie-es: 3.1.1 + seroval: 1.5.5 + seroval-plugins: 1.5.5(seroval@1.5.5) - '@trpc/client@11.5.1(@trpc/server@11.5.1(typescript@5.7.3))(typescript@5.7.3)': + '@tanstack/router-generator@1.167.18': dependencies: - '@trpc/server': 11.5.1(typescript@5.7.3) - typescript: 5.7.3 + '@babel/types': 7.29.7 + '@tanstack/router-core': 1.171.14 + '@tanstack/router-utils': 1.162.2 + '@tanstack/virtual-file-routes': 1.162.0 + jiti: 2.7.0 + magic-string: 0.30.21 + prettier: 3.9.5 + zod: 4.4.3 + transitivePeerDependencies: + - supports-color - '@trpc/next@11.5.1(@tanstack/react-query@5.90.19(react@18.3.1))(@trpc/client@11.5.1(@trpc/server@11.5.1(typescript@5.7.3))(typescript@5.7.3))(@trpc/react-query@11.5.1(@tanstack/react-query@5.90.19(react@18.3.1))(@trpc/client@11.5.1(@trpc/server@11.5.1(typescript@5.7.3))(typescript@5.7.3))(@trpc/server@11.5.1(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3))(@trpc/server@11.5.1(typescript@5.7.3))(next@15.5.18(@babel/core@7.29.0)(babel-plugin-react-compiler@1.0.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3)': + '@tanstack/router-plugin@1.168.19(@tanstack/react-router@1.170.17(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(rolldown@1.1.5)(vite@8.1.4(@types/node@22.20.1)(jiti@2.7.0))': dependencies: - '@trpc/client': 11.5.1(@trpc/server@11.5.1(typescript@5.7.3))(typescript@5.7.3) - '@trpc/server': 11.5.1(typescript@5.7.3) - next: 15.5.18(@babel/core@7.29.0)(babel-plugin-react-compiler@1.0.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - typescript: 5.7.3 + '@babel/core': 7.29.0 + '@babel/template': 7.29.7 + '@babel/types': 7.29.7 + '@tanstack/router-core': 1.171.14 + '@tanstack/router-generator': 1.167.18 + '@tanstack/router-utils': 1.162.2 + chokidar: 5.0.0 + unplugin: 3.3.0(rolldown@1.1.5)(vite@8.1.4(@types/node@22.20.1)(jiti@2.7.0)) + zod: 4.4.3 optionalDependencies: - '@tanstack/react-query': 5.90.19(react@18.3.1) - '@trpc/react-query': 11.5.1(@tanstack/react-query@5.90.19(react@18.3.1))(@trpc/client@11.5.1(@trpc/server@11.5.1(typescript@5.7.3))(typescript@5.7.3))(@trpc/server@11.5.1(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3) + '@tanstack/react-router': 1.170.17(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + vite: 8.1.4(@types/node@22.20.1)(jiti@2.7.0) + transitivePeerDependencies: + - '@farmfe/core' + - '@rspack/core' + - bun-types-no-globals + - esbuild + - rolldown + - rollup + - supports-color + - unloader - '@trpc/react-query@11.5.1(@tanstack/react-query@5.90.19(react@18.3.1))(@trpc/client@11.5.1(@trpc/server@11.5.1(typescript@5.7.3))(typescript@5.7.3))(@trpc/server@11.5.1(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3)': + '@tanstack/router-utils@1.162.2': dependencies: - '@tanstack/react-query': 5.90.19(react@18.3.1) - '@trpc/client': 11.5.1(@trpc/server@11.5.1(typescript@5.7.3))(typescript@5.7.3) - '@trpc/server': 11.5.1(typescript@5.7.3) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - typescript: 5.7.3 - optional: true + '@babel/generator': 7.29.7 + '@babel/parser': 7.29.7 + '@babel/types': 7.29.7 + ansis: 4.3.1 + babel-dead-code-elimination: 1.0.12 + diff: 8.0.4 + pathe: 2.0.3 + tinyglobby: 0.2.17 + transitivePeerDependencies: + - supports-color + + '@tanstack/start-client-core@1.170.13': + dependencies: + '@tanstack/router-core': 1.171.14 + '@tanstack/start-fn-stubs': 1.162.0 + '@tanstack/start-storage-context': 1.167.16 + seroval: 1.5.5 + + '@tanstack/start-fn-stubs@1.162.0': {} + + '@tanstack/start-plugin-core@1.171.19(@tanstack/react-router@1.170.17(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(crossws@0.4.9(srvx@0.11.21))(rolldown@1.1.5)(vite@8.1.4(@types/node@22.20.1)(jiti@2.7.0))': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/core': 7.29.0 + '@babel/types': 7.29.7 + '@tanstack/router-core': 1.171.14 + '@tanstack/router-generator': 1.167.18 + '@tanstack/router-plugin': 1.168.19(@tanstack/react-router@1.170.17(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(rolldown@1.1.5)(vite@8.1.4(@types/node@22.20.1)(jiti@2.7.0)) + '@tanstack/router-utils': 1.162.2 + '@tanstack/start-server-core': 1.169.16(crossws@0.4.9(srvx@0.11.21)) + exsolve: 1.1.0 + lightningcss: 1.32.0 + pathe: 2.0.3 + picomatch: 4.0.5 + seroval: 1.5.5 + source-map: 0.7.6 + srvx: 0.11.21 + tinyglobby: 0.2.17 + ufo: 1.6.4 + vitefu: 1.1.3(vite@8.1.4(@types/node@22.20.1)(jiti@2.7.0)) + xmlbuilder2: 4.0.3 + zod: 4.4.3 + optionalDependencies: + vite: 8.1.4(@types/node@22.20.1)(jiti@2.7.0) + transitivePeerDependencies: + - '@farmfe/core' + - '@rspack/core' + - '@tanstack/react-router' + - bun-types-no-globals + - crossws + - esbuild + - rolldown + - rollup + - supports-color + - unloader + - vite-plugin-solid + - webpack + + '@tanstack/start-server-core@1.169.16(crossws@0.4.9(srvx@0.11.21))': + dependencies: + '@tanstack/history': 1.162.0 + '@tanstack/router-core': 1.171.14 + '@tanstack/start-client-core': 1.170.13 + '@tanstack/start-storage-context': 1.167.16 + fetchdts: 0.1.7 + h3-v2: h3@2.0.1-rc.20(crossws@0.4.9(srvx@0.11.21)) + seroval: 1.5.5 + transitivePeerDependencies: + - crossws - '@trpc/server@11.5.1(typescript@5.7.3)': + '@tanstack/start-storage-context@1.167.16': dependencies: - typescript: 5.7.3 + '@tanstack/router-core': 1.171.14 + + '@tanstack/store@0.11.0': {} + + '@tanstack/store@0.9.3': {} + + '@tanstack/table-core@9.0.0-beta.38': + dependencies: + '@tanstack/store': 0.11.0 + + '@tanstack/virtual-file-routes@1.162.0': {} + + '@trpc/client@11.5.1(@trpc/server@11.5.1(typescript@6.0.3))(typescript@6.0.3)': + dependencies: + '@trpc/server': 11.5.1(typescript@6.0.3) + typescript: 6.0.3 + + '@trpc/server@11.5.1(typescript@6.0.3)': + dependencies: + typescript: 6.0.3 '@ts-morph/common@0.27.0': dependencies: @@ -5113,24 +4597,22 @@ snapshots: minimatch: 10.2.5 path-browserify: 1.0.1 - '@types/node@20.17.19': + '@tybys/wasm-util@0.10.3': dependencies: - undici-types: 6.19.8 - - '@types/prismjs@1.26.5': {} - - '@types/prop-types@15.7.14': {} + tslib: 2.8.1 + optional: true - '@types/react-dom@18.3.5(@types/react@18.3.18)': + '@types/node@22.20.1': dependencies: - '@types/react': 18.3.18 + undici-types: 6.21.0 - '@types/react@18.3.18': + '@types/react-dom@19.2.3(@types/react@19.2.17)': dependencies: - '@types/prop-types': 15.7.14 - csstype: 3.1.3 + '@types/react': 19.2.17 - '@types/statuses@2.0.6': {} + '@types/react@19.2.17': + dependencies: + csstype: 3.2.3 '@types/validate-npm-package-name@4.0.2': {} @@ -5140,35 +4622,44 @@ snapshots: dependencies: '@types/webidl-conversions': 7.0.3 + '@vitejs/plugin-react@6.0.3(babel-plugin-react-compiler@1.0.0)(vite@8.1.4(@types/node@22.20.1)(jiti@2.7.0))': + dependencies: + '@rolldown/pluginutils': 1.0.1 + vite: 8.1.4(@types/node@22.20.1)(jiti@2.7.0) + optionalDependencies: + babel-plugin-react-compiler: 1.0.0 + accepts@2.0.0: dependencies: mime-types: 3.0.2 negotiator: 1.0.0 - agent-base@7.1.4: {} + ajv-formats@2.1.1(ajv@8.20.0): + optionalDependencies: + ajv: 8.20.0 - ajv-formats@3.0.1(ajv@8.18.0): + ajv-formats@3.0.1(ajv@8.20.0): optionalDependencies: - ajv: 8.18.0 + ajv: 8.20.0 - ajv@8.18.0: + ajv@8.20.0: dependencies: fast-deep-equal: 3.1.3 - fast-uri: 3.1.0 + fast-uri: 3.1.3 json-schema-traverse: 1.0.0 require-from-string: 2.0.2 + ansi-colors@4.1.3: {} + ansi-regex@5.0.1: {} ansi-regex@6.2.2: {} - ansi-styles@4.3.0: - dependencies: - color-convert: 2.0.1 + ansis@4.3.1: {} argparse@2.0.1: {} - aria-hidden@1.2.4: + aria-hidden@1.2.6: dependencies: tslib: 2.8.1 @@ -5182,15 +4673,27 @@ snapshots: dependencies: tslib: 2.8.1 + atomically@1.7.0: {} + + babel-dead-code-elimination@1.0.12: + dependencies: + '@babel/core': 7.29.0 + '@babel/parser': 7.29.7 + '@babel/traverse': 7.29.7 + '@babel/types': 7.29.7 + transitivePeerDependencies: + - supports-color + babel-plugin-react-compiler@1.0.0: dependencies: - '@babel/types': 7.28.2 + '@babel/types': 7.29.7 + optional: true balanced-match@4.0.4: {} baseline-browser-mapping@2.10.16: {} - better-auth@1.5.5(mongodb@7.1.0)(next@15.5.18(@babel/core@7.29.0)(babel-plugin-react-compiler@1.0.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + better-auth@1.5.5(@tanstack/react-start@1.168.27(crossws@0.4.9(srvx@0.11.21))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(rolldown@1.1.5)(vite@8.1.4(@types/node@22.20.1)(jiti@2.7.0)))(mongodb@7.1.0)(next@15.5.18(@babel/core@7.29.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(solid-js@1.9.14): dependencies: '@better-auth/core': 1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.1.3)(kysely@0.28.12)(nanostores@1.2.0) '@better-auth/drizzle-adapter': 1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.1.3)(kysely@0.28.12)(nanostores@1.2.0))(@better-auth/utils@0.3.1) @@ -5210,10 +4713,12 @@ snapshots: nanostores: 1.2.0 zod: 4.3.6 optionalDependencies: + '@tanstack/react-start': 1.168.27(crossws@0.4.9(srvx@0.11.21))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(rolldown@1.1.5)(vite@8.1.4(@types/node@22.20.1)(jiti@2.7.0)) mongodb: 7.1.0 - next: 15.5.18(@babel/core@7.29.0)(babel-plugin-react-compiler@1.0.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + next: 15.5.18(@babel/core@7.29.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + solid-js: 1.9.14 transitivePeerDependencies: - '@cloudflare/workers-types' @@ -5226,21 +4731,21 @@ snapshots: optionalDependencies: zod: 4.3.5 - body-parser@2.2.2: + body-parser@2.3.0: dependencies: bytes: 3.1.2 - content-type: 1.0.5 + content-type: 2.0.0 debug: 4.4.3 http-errors: 2.0.1 - iconv-lite: 0.7.2 + iconv-lite: 0.7.3 on-finished: 2.4.1 - qs: 6.15.1 + qs: 6.15.3 raw-body: 3.0.2 - type-is: 2.0.1 + type-is: 2.1.0 transitivePeerDependencies: - supports-color - brace-expansion@5.0.5: + brace-expansion@5.0.7: dependencies: balanced-match: 4.0.4 @@ -5280,6 +4785,10 @@ snapshots: chalk@5.6.2: {} + chokidar@5.0.0: + dependencies: + readdirp: 5.0.0 + class-variance-authority@0.7.1: dependencies: clsx: 2.1.1 @@ -5290,54 +4799,58 @@ snapshots: cli-spinners@2.9.2: {} - cli-width@4.1.0: {} - - client-only@0.0.1: {} - - cliui@8.0.1: - dependencies: - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 7.0.0 + client-only@0.0.1: + optional: true clsx@2.1.1: {} - cmdk@1.1.1(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + cmdk@1.1.1(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7): dependencies: - '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-dialog': 1.1.15(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-id': 1.1.0(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.17)(react@19.2.7) + '@radix-ui/react-dialog': 1.1.20(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@radix-ui/react-id': 1.1.2(@types/react@19.2.17)(react@19.2.7) + '@radix-ui/react-primitive': 2.1.7(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) transitivePeerDependencies: - '@types/react' - '@types/react-dom' code-block-writer@13.0.3: {} - color-convert@2.0.1: - dependencies: - color-name: 1.1.4 - - color-name@1.1.4: {} - commander@11.1.0: {} commander@14.0.3: {} + conf@10.2.0: + dependencies: + ajv: 8.20.0 + ajv-formats: 2.1.1(ajv@8.20.0) + atomically: 1.7.0 + debounce-fn: 4.0.0 + dot-prop: 6.0.1 + env-paths: 2.2.1 + json-schema-typed: 7.0.3 + onetime: 5.1.2 + pkg-up: 3.1.0 + semver: 7.8.2 + + consola@3.4.2: {} + content-disposition@1.1.0: {} content-type@1.0.5: {} + content-type@2.0.0: {} + convert-source-map@2.0.0: {} + cookie-es@3.1.1: {} + cookie-signature@1.2.2: {} cookie@0.7.2: {} - cookie@1.1.1: {} - copy-anything@3.0.5: dependencies: is-what: 4.1.16 @@ -5347,14 +4860,14 @@ snapshots: object-assign: 4.1.1 vary: 1.1.2 - cosmiconfig@9.0.1(typescript@5.7.3): + cosmiconfig@9.0.2(typescript@6.0.3): dependencies: env-paths: 2.2.1 import-fresh: 3.3.1 js-yaml: 4.1.1 parse-json: 5.2.0 optionalDependencies: - typescript: 5.7.3 + typescript: 6.0.3 cross-spawn@7.0.6: dependencies: @@ -5362,15 +4875,21 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 + crossws@0.4.9(srvx@0.11.21): + optionalDependencies: + srvx: 0.11.21 + cssesc@3.0.0: {} - csstype@3.1.3: {} + csstype@3.2.3: {} - data-uri-to-buffer@4.0.1: {} + date-fns@4.4.0: {} - date-fns-jalali@4.1.0-0: {} + db0@0.3.4: {} - date-fns@4.1.0: {} + debounce-fn@4.0.0: + dependencies: + mimic-fn: 3.1.0 debug@4.4.3: dependencies: @@ -5387,6 +4906,8 @@ snapshots: bundle-name: 4.1.0 default-browser-id: 5.0.1 + define-lazy-prop@2.0.0: {} + define-lazy-prop@3.0.0: {} defu@6.1.4: {} @@ -5399,7 +4920,11 @@ snapshots: diff@8.0.4: {} - dotenv@17.4.1: {} + dot-prop@6.0.1: + dependencies: + is-obj: 2.0.0 + + dotenv@17.4.2: {} dunder-proto@1.0.1: dependencies: @@ -5407,30 +4932,33 @@ snapshots: es-errors: 1.3.0 gopd: 1.2.0 - eciesjs@0.4.18: - dependencies: - '@ecies/ciphers': 0.2.6(@noble/ciphers@1.3.0) - '@noble/ciphers': 1.3.0 - '@noble/curves': 1.9.7 - '@noble/hashes': 1.8.0 - ee-first@1.1.1: {} electron-to-chromium@1.5.334: {} emoji-regex@10.6.0: {} - emoji-regex@8.0.0: {} - encodeurl@2.0.0: {} - enhanced-resolve@5.18.1: + enhanced-resolve@5.21.6: dependencies: graceful-fs: 4.2.11 - tapable: 2.2.1 + tapable: 2.3.3 + + enquirer@2.4.1: + dependencies: + ansi-colors: 4.1.3 + strip-ansi: 6.0.1 env-paths@2.2.1: {} + env-runner@0.1.16: + dependencies: + crossws: 0.4.9(srvx@0.11.21) + exsolve: 1.1.0 + httpxy: 0.5.5 + srvx: 0.11.21 + error-ex@1.3.4: dependencies: is-arrayish: 0.2.1 @@ -5439,7 +4967,7 @@ snapshots: es-errors@1.3.0: {} - es-object-atoms@1.1.1: + es-object-atoms@1.1.2: dependencies: es-errors: 1.3.0 @@ -5451,11 +4979,11 @@ snapshots: etag@1.8.1: {} - eventsource-parser@3.0.6: {} + eventsource-parser@3.1.0: {} eventsource@3.0.7: dependencies: - eventsource-parser: 3.0.6 + eventsource-parser: 3.1.0 execa@5.1.1: dependencies: @@ -5484,15 +5012,15 @@ snapshots: strip-final-newline: 4.0.0 yoctocolors: 2.1.2 - express-rate-limit@8.3.2(express@5.2.1): + express-rate-limit@8.5.2(express@5.2.1): dependencies: express: 5.2.1 - ip-address: 10.1.0 + ip-address: 10.2.0 express@5.2.1: dependencies: accepts: 2.0.0 - body-parser: 2.2.2 + body-parser: 2.3.0 content-disposition: 1.1.0 content-type: 1.0.5 cookie: 0.7.2 @@ -5511,17 +5039,19 @@ snapshots: once: 1.4.0 parseurl: 1.3.3 proxy-addr: 2.0.7 - qs: 6.15.1 - range-parser: 1.2.1 + qs: 6.15.3 + range-parser: 1.3.0 router: 2.2.0 send: 1.2.1 serve-static: 2.2.1 statuses: 2.0.2 - type-is: 2.0.1 + type-is: 2.1.0 vary: 1.1.2 transitivePeerDependencies: - supports-color + exsolve@1.1.0: {} + fast-deep-equal@3.1.3: {} fast-glob@3.3.3: @@ -5532,20 +5062,17 @@ snapshots: merge2: 1.4.1 micromatch: 4.0.8 - fast-uri@3.1.0: {} + fast-uri@3.1.3: {} fastq@1.20.1: dependencies: reusify: 1.1.0 - fdir@6.5.0(picomatch@4.0.4): + fdir@6.5.0(picomatch@4.0.5): optionalDependencies: - picomatch: 4.0.4 + picomatch: 4.0.5 - fetch-blob@3.2.0: - dependencies: - node-domexception: 1.0.0 - web-streams-polyfill: 3.3.3 + fetchdts@0.1.7: {} figures@6.1.0: dependencies: @@ -5566,45 +5093,51 @@ snapshots: transitivePeerDependencies: - supports-color - formdata-polyfill@4.0.10: + find-up@3.0.0: dependencies: - fetch-blob: 3.2.0 + locate-path: 3.0.0 forwarded@0.2.0: {} + framer-motion@12.42.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7): + dependencies: + motion-dom: 12.42.2 + motion-utils: 12.39.0 + tslib: 2.8.1 + optionalDependencies: + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + fresh@2.0.0: {} - fs-extra@11.3.4: + fs-extra@11.3.6: dependencies: graceful-fs: 4.2.11 - jsonfile: 6.2.0 + jsonfile: 6.2.1 universalify: 2.0.1 + fsevents@2.3.3: + optional: true + function-bind@1.1.2: {} fuzzysort@3.1.0: {} - geist@1.3.1(next@15.5.18(@babel/core@7.29.0)(babel-plugin-react-compiler@1.0.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)): - dependencies: - next: 15.5.18(@babel/core@7.29.0)(babel-plugin-react-compiler@1.0.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - gensync@1.0.0-beta.2: {} - get-caller-file@2.0.5: {} - - get-east-asian-width@1.5.0: {} + get-east-asian-width@1.6.0: {} get-intrinsic@1.3.0: dependencies: call-bind-apply-helpers: 1.0.2 es-define-property: 1.0.1 es-errors: 1.3.0 - es-object-atoms: 1.1.1 + es-object-atoms: 1.1.2 function-bind: 1.1.2 get-proto: 1.0.1 gopd: 1.2.0 has-symbols: 1.1.0 - hasown: 2.0.2 + hasown: 2.0.4 math-intrinsics: 1.1.0 get-nonce@1.0.1: {} @@ -5614,7 +5147,7 @@ snapshots: get-proto@1.0.1: dependencies: dunder-proto: 1.0.1 - es-object-atoms: 1.1.1 + es-object-atoms: 1.1.2 get-stream@6.0.1: {} @@ -5631,17 +5164,29 @@ snapshots: graceful-fs@4.2.11: {} - graphql@16.13.2: {} + h3@2.0.1-rc.20(crossws@0.4.9(srvx@0.11.21)): + dependencies: + rou3: 0.8.1 + srvx: 0.11.21 + optionalDependencies: + crossws: 0.4.9(srvx@0.11.21) + + h3@2.0.1-rc.22(crossws@0.4.9(srvx@0.11.21)): + dependencies: + rou3: 0.8.1 + srvx: 0.11.21 + optionalDependencies: + crossws: 0.4.9(srvx@0.11.21) has-symbols@1.1.0: {} - hasown@2.0.2: + hasown@2.0.4: dependencies: function-bind: 1.1.2 - headers-polyfill@4.0.3: {} + hono@4.12.29: {} - hono@4.12.12: {} + hookable@6.1.1: {} http-errors@2.0.1: dependencies: @@ -5651,18 +5196,13 @@ snapshots: statuses: 2.0.2 toidentifier: 1.0.1 - https-proxy-agent@7.0.6: - dependencies: - agent-base: 7.1.4 - debug: 4.4.3 - transitivePeerDependencies: - - supports-color + httpxy@0.5.5: {} human-signals@2.1.0: {} human-signals@8.0.1: {} - iconv-lite@0.7.2: + iconv-lite@0.7.3: dependencies: safer-buffer: 2.1.2 @@ -5675,23 +5215,18 @@ snapshots: inherits@2.0.4: {} - input-otp@1.4.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1): - dependencies: - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - - ip-address@10.1.0: {} + ip-address@10.2.0: {} ipaddr.js@1.9.1: {} is-arrayish@0.2.1: {} + is-docker@2.2.1: {} + is-docker@3.0.0: {} is-extglob@2.1.1: {} - is-fullwidth-code-point@3.0.0: {} - is-glob@4.0.3: dependencies: is-extglob: 2.1.1 @@ -5704,10 +5239,10 @@ snapshots: is-interactive@2.0.0: {} - is-node-process@1.2.0: {} - is-number@7.0.0: {} + is-obj@2.0.0: {} + is-obj@3.0.0: {} is-plain-obj@4.1.0: {} @@ -5726,15 +5261,21 @@ snapshots: is-what@4.1.16: {} + is-wsl@2.2.0: + dependencies: + is-docker: 2.2.1 + is-wsl@3.1.1: dependencies: is-inside-container: 1.0.0 + isbot@5.2.0: {} + isexe@2.0.0: {} isexe@3.1.5: {} - jiti@2.4.2: {} + jiti@2.7.0: {} jose@6.1.3: {} @@ -5750,11 +5291,13 @@ snapshots: json-schema-traverse@1.0.0: {} + json-schema-typed@7.0.3: {} + json-schema-typed@8.0.2: {} json5@2.2.3: {} - jsonfile@6.2.0: + jsonfile@6.2.1: dependencies: universalify: 2.0.1 optionalDependencies: @@ -5766,66 +5309,79 @@ snapshots: kysely@0.28.12: {} - lightningcss-darwin-arm64@1.29.2: + lightningcss-android-arm64@1.32.0: + optional: true + + lightningcss-darwin-arm64@1.32.0: optional: true - lightningcss-darwin-x64@1.29.2: + lightningcss-darwin-x64@1.32.0: optional: true - lightningcss-freebsd-x64@1.29.2: + lightningcss-freebsd-x64@1.32.0: optional: true - lightningcss-linux-arm-gnueabihf@1.29.2: + lightningcss-linux-arm-gnueabihf@1.32.0: optional: true - lightningcss-linux-arm64-gnu@1.29.2: + lightningcss-linux-arm64-gnu@1.32.0: optional: true - lightningcss-linux-arm64-musl@1.29.2: + lightningcss-linux-arm64-musl@1.32.0: optional: true - lightningcss-linux-x64-gnu@1.29.2: + lightningcss-linux-x64-gnu@1.32.0: optional: true - lightningcss-linux-x64-musl@1.29.2: + lightningcss-linux-x64-musl@1.32.0: optional: true - lightningcss-win32-arm64-msvc@1.29.2: + lightningcss-win32-arm64-msvc@1.32.0: optional: true - lightningcss-win32-x64-msvc@1.29.2: + lightningcss-win32-x64-msvc@1.32.0: optional: true - lightningcss@1.29.2: + lightningcss@1.32.0: dependencies: detect-libc: 2.1.2 optionalDependencies: - lightningcss-darwin-arm64: 1.29.2 - lightningcss-darwin-x64: 1.29.2 - lightningcss-freebsd-x64: 1.29.2 - lightningcss-linux-arm-gnueabihf: 1.29.2 - lightningcss-linux-arm64-gnu: 1.29.2 - lightningcss-linux-arm64-musl: 1.29.2 - lightningcss-linux-x64-gnu: 1.29.2 - lightningcss-linux-x64-musl: 1.29.2 - lightningcss-win32-arm64-msvc: 1.29.2 - lightningcss-win32-x64-msvc: 1.29.2 + lightningcss-android-arm64: 1.32.0 + lightningcss-darwin-arm64: 1.32.0 + lightningcss-darwin-x64: 1.32.0 + lightningcss-freebsd-x64: 1.32.0 + lightningcss-linux-arm-gnueabihf: 1.32.0 + lightningcss-linux-arm64-gnu: 1.32.0 + lightningcss-linux-arm64-musl: 1.32.0 + lightningcss-linux-x64-gnu: 1.32.0 + lightningcss-linux-x64-musl: 1.32.0 + lightningcss-win32-arm64-msvc: 1.32.0 + lightningcss-win32-x64-msvc: 1.32.0 lines-and-columns@1.2.4: {} + locate-path@3.0.0: + dependencies: + p-locate: 3.0.0 + path-exists: 3.0.0 + log-symbols@6.0.0: dependencies: chalk: 5.6.2 is-unicode-supported: 1.3.0 - loose-envify@1.4.0: - dependencies: - js-tokens: 4.0.0 - lru-cache@5.1.1: dependencies: yallist: 3.1.1 + lucide-react@0.545.0(react@19.2.7): + dependencies: + react: 19.2.7 + + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + math-intrinsics@1.1.0: {} media-typer@1.1.0: {} @@ -5851,11 +5407,13 @@ snapshots: mimic-fn@2.1.0: {} + mimic-fn@3.1.0: {} + mimic-function@5.0.1: {} minimatch@10.2.5: dependencies: - brace-expansion: 5.0.5 + brace-expansion: 5.0.7 minimist@1.2.8: {} @@ -5870,57 +5428,37 @@ snapshots: bson: 7.2.0 mongodb-connection-string-url: 7.0.1 - ms@2.1.3: {} + motion-dom@12.42.2: + dependencies: + motion-utils: 12.39.0 - msw@2.13.2(@types/node@20.17.19)(typescript@5.7.3): - dependencies: - '@inquirer/confirm': 5.1.21(@types/node@20.17.19) - '@mswjs/interceptors': 0.41.3 - '@open-draft/deferred-promise': 2.2.0 - '@types/statuses': 2.0.6 - cookie: 1.1.1 - graphql: 16.13.2 - headers-polyfill: 4.0.3 - is-node-process: 1.2.0 - outvariant: 1.4.3 - path-to-regexp: 6.3.0 - picocolors: 1.1.1 - rettime: 0.10.1 - statuses: 2.0.2 - strict-event-emitter: 0.5.1 - tough-cookie: 6.0.1 - type-fest: 5.5.0 - until-async: 3.0.2 - yargs: 17.7.2 + motion-utils@12.39.0: {} + + motion@12.42.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7): + dependencies: + framer-motion: 12.42.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + tslib: 2.8.1 optionalDependencies: - typescript: 5.7.3 - transitivePeerDependencies: - - '@types/node' + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) - mute-stream@2.0.0: {} + ms@2.1.3: {} nanoid@3.3.12: {} - nanoid@3.3.8: {} - nanostores@1.2.0: {} negotiator@1.0.0: {} - next-themes@0.4.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1): - dependencies: - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - - next@15.5.18(@babel/core@7.29.0)(babel-plugin-react-compiler@1.0.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + next@15.5.18(@babel/core@7.29.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7): dependencies: '@next/env': 15.5.18 '@swc/helpers': 0.5.15 caniuse-lite: 1.0.30001797 postcss: 8.4.31 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - styled-jsx: 5.1.6(@babel/core@7.29.0)(react@18.3.1) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + styled-jsx: 5.1.6(@babel/core@7.29.0)(react@19.2.7) optionalDependencies: '@next/swc-darwin-arm64': 15.5.18 '@next/swc-darwin-x64': 15.5.18 @@ -5935,14 +5473,61 @@ snapshots: transitivePeerDependencies: - '@babel/core' - babel-plugin-macros + optional: true - node-domexception@1.0.0: {} - - node-fetch@3.3.2: - dependencies: - data-uri-to-buffer: 4.0.1 - fetch-blob: 3.2.0 - formdata-polyfill: 4.0.10 + nf3@0.3.21: {} + + nitro@3.0.260610-beta(chokidar@5.0.0)(dotenv@17.4.2)(jiti@2.7.0)(mongodb@7.1.0)(vite@8.1.4(@types/node@22.20.1)(jiti@2.7.0)): + dependencies: + consola: 3.4.2 + crossws: 0.4.9(srvx@0.11.21) + db0: 0.3.4 + env-runner: 0.1.16 + h3: 2.0.1-rc.22(crossws@0.4.9(srvx@0.11.21)) + hookable: 6.1.1 + nf3: 0.3.21 + ocache: 0.1.5 + ofetch: 2.0.0-alpha.3 + ohash: 2.0.11 + rolldown: 1.1.5 + srvx: 0.11.21 + unenv: 2.0.0-rc.24 + unstorage: 2.0.0-alpha.7(chokidar@5.0.0)(db0@0.3.4)(mongodb@7.1.0)(ofetch@2.0.0-alpha.3) + optionalDependencies: + dotenv: 17.4.2 + jiti: 2.7.0 + vite: 8.1.4(@types/node@22.20.1)(jiti@2.7.0) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@electric-sql/pglite' + - '@libsql/client' + - '@netlify/blobs' + - '@netlify/runtime' + - '@planetscale/database' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - better-sqlite3 + - chokidar + - drizzle-orm + - idb-keyval + - ioredis + - lru-cache + - miniflare + - mongodb + - mysql2 + - sqlite3 + - uploadthing + - wrangler node-releases@2.0.37: {} @@ -5961,6 +5546,14 @@ snapshots: object-treeify@1.1.33: {} + ocache@0.1.5: + dependencies: + ohash: 2.0.11 + + ofetch@2.0.0-alpha.3: {} + + ohash@2.0.11: {} + on-finished@2.4.1: dependencies: ee-first: 1.1.1 @@ -5986,6 +5579,12 @@ snapshots: powershell-utils: 0.1.0 wsl-utils: 0.3.1 + open@8.4.2: + dependencies: + define-lazy-prop: 2.0.0 + is-docker: 2.2.1 + is-wsl: 2.2.0 + ora@8.2.0: dependencies: chalk: 5.6.2 @@ -5998,7 +5597,15 @@ snapshots: string-width: 7.2.0 strip-ansi: 7.2.0 - outvariant@1.4.3: {} + p-limit@2.3.0: + dependencies: + p-try: 2.2.0 + + p-locate@3.0.0: + dependencies: + p-limit: 2.3.0 + + p-try@2.2.0: {} parent-module@1.0.1: dependencies: @@ -6017,23 +5624,29 @@ snapshots: path-browserify@1.0.1: {} + path-exists@3.0.0: {} + path-key@3.1.1: {} path-key@4.0.0: {} - path-to-regexp@6.3.0: {} - path-to-regexp@8.4.2: {} + pathe@2.0.3: {} + picocolors@1.1.1: {} picomatch@2.3.2: {} - picomatch@4.0.4: {} + picomatch@4.0.5: {} pkce-challenge@5.0.1: {} - postcss-selector-parser@7.1.1: + pkg-up@3.1.0: + dependencies: + find-up: 3.0.0 + + postcss-selector-parser@7.1.4: dependencies: cssesc: 3.0.0 util-deprecate: 1.0.2 @@ -6043,33 +5656,22 @@ snapshots: nanoid: 3.3.12 picocolors: 1.1.1 source-map-js: 1.2.1 + optional: true - postcss@8.5.2: - dependencies: - nanoid: 3.3.8 - picocolors: 1.1.1 - source-map-js: 1.2.1 - - postcss@8.5.9: + postcss@8.5.16: dependencies: nanoid: 3.3.12 picocolors: 1.1.1 source-map-js: 1.2.1 - postgres@3.4.5: {} - powershell-utils@0.1.0: {} + prettier@3.9.5: {} + pretty-ms@9.3.0: dependencies: parse-ms: 4.0.0 - prism-react-renderer@2.4.1(react@18.3.1): - dependencies: - '@types/prismjs': 1.26.5 - clsx: 2.1.1 - react: 18.3.1 - prompts@2.4.2: dependencies: kleur: 3.0.3 @@ -6088,142 +5690,67 @@ snapshots: pvutils@1.1.5: {} - qs@6.15.1: + qs@6.15.3: dependencies: - side-channel: 1.1.0 + es-define-property: 1.0.1 + side-channel: 1.1.1 queue-microtask@1.2.3: {} - radix-ui@1.4.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-accessible-icon': 1.1.7(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-accordion': 1.2.12(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-alert-dialog': 1.1.15(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-arrow': 1.1.7(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-aspect-ratio': 1.1.7(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-avatar': 1.1.10(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-checkbox': 1.3.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-collapsible': 1.1.12(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-collection': 1.1.7(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-context': 1.1.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-context-menu': 2.2.16(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-dialog': 1.1.15(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-direction': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-dropdown-menu': 2.1.16(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-focus-guards': 1.1.3(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-form': 0.1.8(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-hover-card': 1.1.15(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-label': 2.1.7(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-menu': 2.1.16(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-menubar': 1.1.16(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-navigation-menu': 1.2.14(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-one-time-password-field': 0.1.8(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-password-toggle-field': 0.1.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-popover': 1.1.15(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-popper': 1.2.8(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-progress': 1.1.7(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-radio-group': 1.3.8(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-scroll-area': 1.2.10(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-select': 2.2.6(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-separator': 1.1.7(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slider': 1.3.6(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slot': 1.2.3(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-switch': 1.2.6(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-tabs': 1.1.13(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-toast': 1.2.15(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-toggle': 1.1.10(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-toggle-group': 1.1.11(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-toolbar': 1.1.11(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-tooltip': 1.2.8(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-effect-event': 0.0.2(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-is-hydrated': 0.1.0(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-use-size': 1.1.1(@types/react@18.3.18)(react@18.3.1) - '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) - - range-parser@1.2.1: {} + range-parser@1.3.0: {} raw-body@3.0.2: dependencies: bytes: 3.1.2 http-errors: 2.0.1 - iconv-lite: 0.7.2 + iconv-lite: 0.7.3 unpipe: 1.0.0 - react-day-picker@9.14.0(react@18.3.1): - dependencies: - '@date-fns/tz': 1.4.1 - '@tabby_ai/hijri-converter': 1.0.5 - date-fns: 4.1.0 - date-fns-jalali: 4.1.0-0 - react: 18.3.1 - - react-dom@18.3.1(react@18.3.1): - dependencies: - loose-envify: 1.4.0 - react: 18.3.1 - scheduler: 0.23.2 - - react-error-boundary@6.1.0(react@18.3.1): - dependencies: - react: 18.3.1 - - react-hook-form@7.55.0(react@18.3.1): + react-day-picker@10.0.1(@types/react@19.2.17)(react@19.2.7): dependencies: - react: 18.3.1 + '@date-fns/tz': 1.5.0 + date-fns: 4.4.0 + react: 19.2.7 + optionalDependencies: + '@types/react': 19.2.17 - react-icons@5.7.0(react@18.3.1): + react-dom@19.2.7(react@19.2.7): dependencies: - react: 18.3.1 + react: 19.2.7 + scheduler: 0.27.0 - react-remove-scroll-bar@2.3.8(@types/react@18.3.18)(react@18.3.1): + react-remove-scroll-bar@2.3.8(@types/react@19.2.17)(react@19.2.7): dependencies: - react: 18.3.1 - react-style-singleton: 2.2.3(@types/react@18.3.18)(react@18.3.1) + react: 19.2.7 + react-style-singleton: 2.2.3(@types/react@19.2.17)(react@19.2.7) tslib: 2.8.1 optionalDependencies: - '@types/react': 18.3.18 + '@types/react': 19.2.17 - react-remove-scroll@2.6.3(@types/react@18.3.18)(react@18.3.1): + react-remove-scroll@2.7.2(@types/react@19.2.17)(react@19.2.7): dependencies: - react: 18.3.1 - react-remove-scroll-bar: 2.3.8(@types/react@18.3.18)(react@18.3.1) - react-style-singleton: 2.2.3(@types/react@18.3.18)(react@18.3.1) + react: 19.2.7 + react-remove-scroll-bar: 2.3.8(@types/react@19.2.17)(react@19.2.7) + react-style-singleton: 2.2.3(@types/react@19.2.17)(react@19.2.7) tslib: 2.8.1 - use-callback-ref: 1.3.3(@types/react@18.3.18)(react@18.3.1) - use-sidecar: 1.1.3(@types/react@18.3.18)(react@18.3.1) + use-callback-ref: 1.3.3(@types/react@19.2.17)(react@19.2.7) + use-sidecar: 1.1.3(@types/react@19.2.17)(react@19.2.7) optionalDependencies: - '@types/react': 18.3.18 + '@types/react': 19.2.17 - react-style-singleton@2.2.3(@types/react@18.3.18)(react@18.3.1): + react-style-singleton@2.2.3(@types/react@19.2.17)(react@19.2.7): dependencies: get-nonce: 1.0.1 - react: 18.3.1 + react: 19.2.7 tslib: 2.8.1 optionalDependencies: - '@types/react': 18.3.18 + '@types/react': 19.2.17 - react@18.3.1: - dependencies: - loose-envify: 1.4.0 + react@19.2.7: {} + + readdirp@5.0.0: {} - recast@0.23.11: + recast@0.23.12: dependencies: ast-types: 0.16.1 esprima: 4.0.1 @@ -6233,11 +5760,9 @@ snapshots: reflect-metadata@0.2.2: {} - require-directory@2.1.1: {} - require-from-string@2.0.2: {} - reselect@5.1.1: {} + reselect@5.2.0: {} resolve-from@4.0.0: {} @@ -6246,12 +5771,33 @@ snapshots: onetime: 7.0.0 signal-exit: 4.1.0 - rettime@0.10.1: {} - reusify@1.1.0: {} + rolldown@1.1.5: + dependencies: + '@oxc-project/types': 0.139.0 + '@rolldown/pluginutils': 1.0.1 + optionalDependencies: + '@rolldown/binding-android-arm64': 1.1.5 + '@rolldown/binding-darwin-arm64': 1.1.5 + '@rolldown/binding-darwin-x64': 1.1.5 + '@rolldown/binding-freebsd-x64': 1.1.5 + '@rolldown/binding-linux-arm-gnueabihf': 1.1.5 + '@rolldown/binding-linux-arm64-gnu': 1.1.5 + '@rolldown/binding-linux-arm64-musl': 1.1.5 + '@rolldown/binding-linux-ppc64-gnu': 1.1.5 + '@rolldown/binding-linux-s390x-gnu': 1.1.5 + '@rolldown/binding-linux-x64-gnu': 1.1.5 + '@rolldown/binding-linux-x64-musl': 1.1.5 + '@rolldown/binding-openharmony-arm64': 1.1.5 + '@rolldown/binding-wasm32-wasi': 1.1.5 + '@rolldown/binding-win32-arm64-msvc': 1.1.5 + '@rolldown/binding-win32-x64-msvc': 1.1.5 + rou3@0.7.12: {} + rou3@0.8.1: {} + router@2.2.0: dependencies: debug: 4.4.3 @@ -6270,14 +5816,11 @@ snapshots: safer-buffer@2.1.2: {} - scheduler@0.23.2: - dependencies: - loose-envify: 1.4.0 + scheduler@0.27.0: {} semver@6.3.1: {} - semver@7.8.2: - optional: true + semver@7.8.2: {} send@1.2.1: dependencies: @@ -6290,11 +5833,17 @@ snapshots: mime-types: 3.0.2 ms: 2.1.3 on-finished: 2.4.1 - range-parser: 1.2.1 + range-parser: 1.3.0 statuses: 2.0.2 transitivePeerDependencies: - supports-color + seroval-plugins@1.5.5(seroval@1.5.5): + dependencies: + seroval: 1.5.5 + + seroval@1.5.5: {} + serve-static@2.2.1: dependencies: encodeurl: 2.0.0 @@ -6304,51 +5853,46 @@ snapshots: transitivePeerDependencies: - supports-color - server-only@0.0.1: {} - set-cookie-parser@3.0.1: {} setprototypeof@1.2.0: {} - shadcn@4.2.0(@types/node@20.17.19)(typescript@5.7.3): + shadcn@4.13.0(typescript@6.0.3): dependencies: '@babel/core': 7.29.0 '@babel/parser': 7.29.2 - '@babel/plugin-transform-typescript': 7.28.6(@babel/core@7.29.0) - '@babel/preset-typescript': 7.28.5(@babel/core@7.29.0) - '@dotenvx/dotenvx': 1.61.0 + '@babel/plugin-transform-typescript': 7.29.7(@babel/core@7.29.0) + '@babel/preset-typescript': 7.29.7(@babel/core@7.29.0) + '@dotenvx/dotenvx': 1.75.1 '@modelcontextprotocol/sdk': 1.29.0(zod@3.25.76) '@types/validate-npm-package-name': 4.0.2 browserslist: 4.28.2 commander: 14.0.3 - cosmiconfig: 9.0.1(typescript@5.7.3) + cosmiconfig: 9.0.2(typescript@6.0.3) dedent: 1.7.2 deepmerge: 4.3.1 diff: 8.0.4 execa: 9.6.1 fast-glob: 3.3.3 - fs-extra: 11.3.4 + fs-extra: 11.3.6 fuzzysort: 3.1.0 - https-proxy-agent: 7.0.6 kleur: 4.1.5 - msw: 2.13.2(@types/node@20.17.19)(typescript@5.7.3) - node-fetch: 3.3.2 open: 11.0.0 ora: 8.2.0 - postcss: 8.5.9 - postcss-selector-parser: 7.1.1 + postcss: 8.5.16 + postcss-selector-parser: 7.1.4 prompts: 2.4.2 - recast: 0.23.11 + recast: 0.23.12 stringify-object: 5.0.0 - tailwind-merge: 3.0.1 + tailwind-merge: 3.6.0 ts-morph: 26.0.0 tsconfig-paths: 4.2.0 + undici: 7.28.0 validate-npm-package-name: 7.0.2 zod: 3.25.76 zod-to-json-schema: 3.25.2(zod@3.25.76) transitivePeerDependencies: - '@cfworker/json-schema' - - '@types/node' - babel-plugin-macros - supports-color - typescript @@ -6411,7 +5955,7 @@ snapshots: object-inspect: 1.13.4 side-channel-map: 1.0.1 - side-channel@1.1.0: + side-channel@1.1.1: dependencies: es-errors: 1.3.0 object-inspect: 1.13.4 @@ -6425,35 +5969,38 @@ snapshots: sisteransi@1.0.5: {} - sonner@2.0.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + solid-js@1.9.14: + dependencies: + csstype: 3.2.3 + seroval: 1.5.5 + seroval-plugins: 1.5.5(seroval@1.5.5) + optional: true + + sonner@2.0.7(react-dom@19.2.7(react@19.2.7))(react@19.2.7): dependencies: - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) source-map-js@1.2.1: {} source-map@0.6.1: {} + source-map@0.7.6: {} + sparse-bitfield@3.0.3: dependencies: memory-pager: 1.5.0 + srvx@0.11.21: {} + statuses@2.0.2: {} stdin-discarder@0.2.2: {} - strict-event-emitter@0.5.1: {} - - string-width@4.2.3: - dependencies: - emoji-regex: 8.0.0 - is-fullwidth-code-point: 3.0.0 - strip-ansi: 6.0.1 - string-width@7.2.0: dependencies: emoji-regex: 10.6.0 - get-east-asian-width: 1.5.0 + get-east-asian-width: 1.6.0 strip-ansi: 7.2.0 stringify-object@5.0.0: @@ -6476,45 +6023,32 @@ snapshots: strip-final-newline@4.0.0: {} - styled-jsx@5.1.6(@babel/core@7.29.0)(react@18.3.1): + styled-jsx@5.1.6(@babel/core@7.29.0)(react@19.2.7): dependencies: client-only: 0.0.1 - react: 18.3.1 + react: 19.2.7 optionalDependencies: '@babel/core': 7.29.0 + optional: true superjson@2.2.2: dependencies: copy-anything: 3.0.5 - tabbable@6.4.0: {} - - tagged-tag@1.0.0: {} + systeminformation@5.31.15: {} - tailwind-merge@3.0.1: {} + tailwind-merge@3.6.0: {} - tailwind-scrollbar@4.0.2(react@18.3.1)(tailwindcss@4.1.4): - dependencies: - prism-react-renderer: 2.4.1(react@18.3.1) - tailwindcss: 4.1.4 - transitivePeerDependencies: - - react - - tailwindcss-animate@1.0.7(tailwindcss@4.1.4): - dependencies: - tailwindcss: 4.1.4 + tailwindcss@4.3.2: {} - tailwindcss@4.1.4: {} - - tapable@2.2.1: {} + tapable@2.3.3: {} tiny-invariant@1.3.3: {} - tldts-core@7.0.28: {} - - tldts@7.0.28: + tinyglobby@0.2.17: dependencies: - tldts-core: 7.0.28 + fdir: 6.5.0(picomatch@4.0.5) + picomatch: 4.0.5 to-regex-range@5.0.1: dependencies: @@ -6522,10 +6056,6 @@ snapshots: toidentifier@1.0.1: {} - tough-cookie@6.0.1: - dependencies: - tldts: 7.0.28 - tr46@5.1.1: dependencies: punycode: 2.3.1 @@ -6551,19 +6081,23 @@ snapshots: tw-animate-css@1.4.0: {} - type-fest@5.5.0: + type-is@2.1.0: dependencies: - tagged-tag: 1.0.0 - - type-is@2.0.1: - dependencies: - content-type: 1.0.5 + content-type: 2.0.0 media-typer: 1.1.0 mime-types: 3.0.2 - typescript@5.7.3: {} + typescript@6.0.3: {} + + ufo@1.6.4: {} - undici-types@6.19.8: {} + undici-types@6.21.0: {} + + undici@7.28.0: {} + + unenv@2.0.0-rc.24: + dependencies: + pathe: 2.0.3 unicorn-magic@0.3.0: {} @@ -6571,7 +6105,21 @@ snapshots: unpipe@1.0.0: {} - until-async@3.0.2: {} + unplugin@3.3.0(rolldown@1.1.5)(vite@8.1.4(@types/node@22.20.1)(jiti@2.7.0)): + dependencies: + '@jridgewell/remapping': 2.3.5 + picomatch: 4.0.5 + webpack-virtual-modules: 0.6.2 + optionalDependencies: + rolldown: 1.1.5 + vite: 8.1.4(@types/node@22.20.1)(jiti@2.7.0) + + unstorage@2.0.0-alpha.7(chokidar@5.0.0)(db0@0.3.4)(mongodb@7.1.0)(ofetch@2.0.0-alpha.3): + optionalDependencies: + chokidar: 5.0.0 + db0: 0.3.4 + mongodb: 7.1.0 + ofetch: 2.0.0-alpha.3 update-browserslist-db@1.2.3(browserslist@4.28.2): dependencies: @@ -6579,24 +6127,24 @@ snapshots: escalade: 3.2.0 picocolors: 1.1.1 - use-callback-ref@1.3.3(@types/react@18.3.18)(react@18.3.1): + use-callback-ref@1.3.3(@types/react@19.2.17)(react@19.2.7): dependencies: - react: 18.3.1 + react: 19.2.7 tslib: 2.8.1 optionalDependencies: - '@types/react': 18.3.18 + '@types/react': 19.2.17 - use-sidecar@1.1.3(@types/react@18.3.18)(react@18.3.1): + use-sidecar@1.1.3(@types/react@19.2.17)(react@19.2.7): dependencies: detect-node-es: 1.1.0 - react: 18.3.1 + react: 19.2.7 tslib: 2.8.1 optionalDependencies: - '@types/react': 18.3.18 + '@types/react': 19.2.17 - use-sync-external-store@1.6.0(react@18.3.1): + use-sync-external-store@1.6.0(react@19.2.7): dependencies: - react: 18.3.1 + react: 19.2.7 util-deprecate@1.0.2: {} @@ -6604,10 +6152,26 @@ snapshots: vary@1.1.2: {} - web-streams-polyfill@3.3.3: {} + vite@8.1.4(@types/node@22.20.1)(jiti@2.7.0): + dependencies: + lightningcss: 1.32.0 + picomatch: 4.0.5 + postcss: 8.5.16 + rolldown: 1.1.5 + tinyglobby: 0.2.17 + optionalDependencies: + '@types/node': 22.20.1 + fsevents: 2.3.3 + jiti: 2.7.0 + + vitefu@1.1.3(vite@8.1.4(@types/node@22.20.1)(jiti@2.7.0)): + optionalDependencies: + vite: 8.1.4(@types/node@22.20.1)(jiti@2.7.0) webidl-conversions@7.0.0: {} + webpack-virtual-modules@0.6.2: {} + whatwg-url@14.2.0: dependencies: tr46: 5.1.1 @@ -6621,18 +6185,6 @@ snapshots: dependencies: isexe: 3.1.5 - wrap-ansi@6.2.0: - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - - wrap-ansi@7.0.0: - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrappy@1.0.2: {} wsl-utils@0.3.1: @@ -6640,28 +6192,19 @@ snapshots: is-wsl: 3.1.1 powershell-utils: 0.1.0 - y18n@5.0.8: {} + xmlbuilder2@4.0.3: + dependencies: + '@oozcitak/dom': 2.0.2 + '@oozcitak/infra': 2.0.2 + '@oozcitak/util': 10.0.0 + js-yaml: 4.1.1 yallist@3.1.1: {} - yargs-parser@21.1.1: {} - - yargs@17.7.2: - dependencies: - cliui: 8.0.1 - escalade: 3.2.0 - get-caller-file: 2.0.5 - require-directory: 2.1.1 - string-width: 4.2.3 - y18n: 5.0.8 - yargs-parser: 21.1.1 - - yocto-spinner@1.1.0: + yocto-spinner@1.2.1: dependencies: yoctocolors: 2.1.2 - yoctocolors-cjs@2.1.3: {} - yoctocolors@2.1.2: {} zod-to-json-schema@3.25.2(zod@3.25.76): @@ -6673,3 +6216,5 @@ snapshots: zod@4.3.5: {} zod@4.3.6: {} + + zod@4.4.3: {} diff --git a/postcss.config.js b/postcss.config.js deleted file mode 100644 index fb05b56..0000000 --- a/postcss.config.js +++ /dev/null @@ -1,5 +0,0 @@ -export default { - plugins: { - "@tailwindcss/postcss": {}, - }, -} diff --git a/src/app/(auth)/layout.tsx b/src/app/(auth)/layout.tsx deleted file mode 100644 index f7109d7..0000000 --- a/src/app/(auth)/layout.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import { Shape } from "@/components/shapes" - -export default function Layout({ children }: { children: React.ReactNode }) { - return ( -
- {children} -
- - - - -
-
- ) -} diff --git a/src/app/(auth)/login/can-i-access.tsx b/src/app/(auth)/login/can-i-access.tsx deleted file mode 100644 index 00fd427..0000000 --- a/src/app/(auth)/login/can-i-access.tsx +++ /dev/null @@ -1,77 +0,0 @@ -import Image from "next/image" -import { FiAward, FiBriefcase, FiHexagon, FiLock, FiShield, FiStar } from "react-icons/fi" -import loginSvg1 from "@/assets/svg/login-1.svg" -import loginSvg2 from "@/assets/svg/login-2.svg" -import loginSvg3 from "@/assets/svg/login-3.svg" -import { Card } from "@/components/ui/card" -import { FeatureBox } from "./what-is" - -export function CanIAccess() { - return ( -
-
- -

How can I access?

-
-

You can access this dashboard if you have at least one of this role:

-
- - - - - -
-
-

When you have checked that you are eligible, these are the steps to access:

-
- -
- insert credentials -
-

1. Login with email

-

We send an OTP to your email

-
-
-
- -
- insert credentials -
-

2. Link your Telegram account

-

This allows to verify your role

-
-
-
- -
- insert credentials -
-

3. Use the dashboard

-

- If your role is not recognized,
be patient until the IT team fixes it! -

-
-
-
-
-
- ) -} diff --git a/src/app/(auth)/login/login-button.tsx b/src/app/(auth)/login/login-button.tsx deleted file mode 100644 index 748d318..0000000 --- a/src/app/(auth)/login/login-button.tsx +++ /dev/null @@ -1,18 +0,0 @@ -"use client" -import Link from "next/link" -import { FiLogIn } from "react-icons/fi" -import { Card, CardContent } from "@/components/ui/card" - -export function LoginButton() { - return ( - - -
- - -

Enter your reserved area

-
-
- - ) -} diff --git a/src/app/(auth)/login/login-form.tsx b/src/app/(auth)/login/login-form.tsx deleted file mode 100644 index c810324..0000000 --- a/src/app/(auth)/login/login-form.tsx +++ /dev/null @@ -1,196 +0,0 @@ -"use client" - -import { useRouter } from "next/navigation" -import { useState } from "react" -import { FiKey, FiLoader, FiMail } from "react-icons/fi" -import { toast } from "sonner" -import { Button } from "@/components/ui/button" -import { FieldSeparator } from "@/components/ui/field" -import { Input } from "@/components/ui/input" -import { InputOTP, InputOTPGroup, InputOTPSlot } from "@/components/ui/input-otp" -import { Label } from "@/components/ui/label" -import { auth } from "@/lib/auth" - -export default function LoginForm() { - const [email, setEmail] = useState("") - const [sent, setSent] = useState(false) - - return ( -
- {!sent ? ( - setEmail(v)} onSend={() => setSent(true)} /> - ) : ( - - )} -
- ) - // Or continue with - // -} - -function EmailCard({ - email, - onChange, - onSend, -}: { - email: string - onChange: (value: string) => void - onSend: () => void -}) { - const [loading, setLoading] = useState(false) - const [passkeyLoading, setPasskeyLoading] = useState(false) - const router = useRouter() - - async function sendOtp() { - const { data, error } = await auth.emailOtp.sendVerificationOtp({ - type: "sign-in", - email, - }) - - if (data?.success) { - onSend() - toast.success("OTP sent. Check your inbox and spam!") - return - } - - if (error?.code === "INVALID_EMAIL") { - toast.error("Invalid email") - return - } - - toast.error("There was an unexpected error") - console.error({ error }) - } - - async function passkeyLogin() { - setPasskeyLoading(true) - const { data, error } = await auth.signIn.passkey() - if (error || !data) toast.error("Unable to login with passkey") - else { - toast.success("Login successful") - router.replace("/dashboard") - } - setPasskeyLoading(false) - } - - return ( -
-
{ - e.preventDefault() - setLoading(true) - await sendOtp() - setLoading(false) - }} - > -
- - { - onChange(e.target.value) - }} - value={email} - autoComplete="email webauthn" - /> -
- -
- Or continue with - -
- ) -} - -function OTPCard({ email }: { email: string }) { - const router = useRouter() - const [loading, setLoading] = useState(false) - const [otp, setOtp] = useState("") - - async function verifyOtp() { - const { data, error } = await auth.signIn.emailOtp({ - email, - otp, - fetchOptions: { - onRequest: () => { - setLoading(true) - }, - onResponse: () => { - setLoading(false) - }, - }, - }) - - if (data) { - toast.success("Successfully logged in!") - return router.replace("/dashboard") - } - - if (error.code === "INVALID_OTP") toast.error("You entered an invalid OTP") - else { - toast.error("There was an unexpected error") - console.error({ error }) - } - } - return ( -
{ - e.preventDefault() - await verifyOtp() - }} - > -

- Check your {email} inbox and spam to get the OTP. -

-
- - setOtp(v)} - autoComplete="off" - data-1p-ignore - data-lpignore="true" - data-protonpass-ignore="true" - type="text" - > - - - - - - - - - -
- -
- ) -} diff --git a/src/app/(auth)/login/page.tsx b/src/app/(auth)/login/page.tsx deleted file mode 100644 index cd3684f..0000000 --- a/src/app/(auth)/login/page.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import { redirect } from "next/navigation" -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card" -import { getServerSession } from "@/server/auth" -import LoginForm from "./login-form" - -export default async function Page() { - const { data: session } = await getServerSession() - if (session) return redirect("/dashboard") - - return ( -
- - - Login - - Login with Email OTP or Passkey - - - - - - -
- ) -} diff --git a/src/app/(auth)/login/what-is.tsx b/src/app/(auth)/login/what-is.tsx deleted file mode 100644 index 29344d8..0000000 --- a/src/app/(auth)/login/what-is.tsx +++ /dev/null @@ -1,55 +0,0 @@ -import type { IconType } from "react-icons" -import { - FiBookOpen, - FiCheckSquare, - FiClipboard, - FiCpu, - FiEdit3, - FiHelpCircle, - FiLayout, - FiMoreHorizontal, - FiShield, - FiUsers, -} from "react-icons/fi" -import { Card } from "@/components/ui/card" - -export function WhatIs() { - return ( -
-
- -

What is this?

-
-

- This is a PoliNetwork's internal tool that allows admins and department staff to perform multiple actions - via an easy web interface. -

-

What actions you can perform depends on your role, but some remarkable ones are:

-
- - - - - - - - - -
-

- It's clear that you'll have access to different features depending on your role(s). -

-
- ) -} - -export function FeatureBox({ icon: Icon, feature }: { icon: IconType; feature: string }) { - return ( - -
- -

{feature}

-
-
- ) -} diff --git a/src/app/(auth)/onboarding/_layout.tsx b/src/app/(auth)/onboarding/_layout.tsx deleted file mode 100644 index baf33f4..0000000 --- a/src/app/(auth)/onboarding/_layout.tsx +++ /dev/null @@ -1,7 +0,0 @@ -export default function Layout({ children }: { children: React.ReactNode }) { - return ( -
- {children} -
- ) -} diff --git a/src/app/(auth)/onboarding/link/logout.tsx b/src/app/(auth)/onboarding/link/logout.tsx deleted file mode 100644 index 0b743f8..0000000 --- a/src/app/(auth)/onboarding/link/logout.tsx +++ /dev/null @@ -1,32 +0,0 @@ -"use client" - -import { useRouter } from "next/navigation" -import { toast } from "sonner" -import { auth } from "../../../../lib/auth" - -export function Logout({ email }: { email: string }) { - const router = useRouter() - - async function handleLogout() { - const { data, error } = await auth.signOut() - if (data?.success || !error) { - toast.success("Successfully logged out") - return router.replace("/") - } - - toast.error("There was an unexpected error") - console.error({ error }) - } - - return ( -
-

- Logged in as {email} -

- Wrong account?{" "} - -
- ) -} diff --git a/src/app/(auth)/onboarding/link/page.tsx b/src/app/(auth)/onboarding/link/page.tsx deleted file mode 100644 index fc3e0ce..0000000 --- a/src/app/(auth)/onboarding/link/page.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import Image from "next/image" -import { redirect } from "next/navigation" -import loginSvg2 from "@/assets/svg/login-2.svg" -import { Card } from "@/components/ui/card" -import { env } from "@/env" -import { getServerSession } from "@/server/auth" -import { Logout } from "./logout" -import { TelegramLink } from "./telegram" - -const BOT_USERNAME = env.NODE_ENV === "production" ? "pn_ts_dev_bot" : "pn_ts_devlocal_bot" - -export default async function OnboardingLink() { - const { data: session } = await getServerSession() - if (!session || session.user.telegramId) redirect("/dashboard") - - return ( -
- -
- insert credentials -
-

Link your Telegram account

-

This allows to verify your role

-
-
-
- -
- -
-
- ) -} diff --git a/src/app/(auth)/onboarding/link/telegram.tsx b/src/app/(auth)/onboarding/link/telegram.tsx deleted file mode 100644 index d6dd6bd..0000000 --- a/src/app/(auth)/onboarding/link/telegram.tsx +++ /dev/null @@ -1,225 +0,0 @@ -"use client" -import { APIError } from "better-auth/api" -import { useRouter } from "next/navigation" -import { useCallback, useEffect, useState } from "react" -import { FiCheckCircle, FiClock } from "react-icons/fi" -import { toast } from "sonner" -import { Code } from "@/components/code" -import { InputWithPrefix } from "@/components/input-prefix" -import { Button } from "@/components/ui/button" -import { Label } from "@/components/ui/label" -import { Progress, ProgressIndicator, ProgressTrack } from "@/components/ui/progress" -import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip" -import { useLocalStorage } from "@/hooks/use-local-storage" -import { auth, useSession } from "@/lib/auth" - -type SavedLink = { - username: string - code: string - ttl: number - startTime: number -} - -export function TelegramLink({ botUsername }: { botUsername: string }) { - const router = useRouter() - const { refetch } = useSession() - const { data: savedLink, update, remove } = useLocalStorage("linktg") - const timeLeft = savedLink ? savedLink.ttl - (Date.now() - savedLink.startTime) / 1000 : null - if (timeLeft !== null && timeLeft <= 0) { - remove() - } - - const [usernameInput, setUsernameInput] = useState("") - const [expired, setExpired] = useState(false) - const [success, setSuccess] = useState(false) - - const handleComplete = useCallback(() => { - setSuccess(true) - void refetch() - remove() - - setTimeout(() => { - router.push("/dashboard") - }, 5000) - }, [router, refetch, remove]) - - async function handleSubmit(e: React.FormEvent | React.MouseEvent) { - e.stopPropagation() - e.preventDefault() - if (usernameInput.length === 0) return - const res = await auth.telegram.link.start({ - telegramUsername: usernameInput, - }) - - if (res.error) return console.error("custom error", res.error) - - setExpired(false) - update({ - code: res.data.code, - startTime: Date.now(), - ttl: res.data.ttl, - username: usernameInput, - }) - } - - function reset() { - setExpired(false) - setUsernameInput("") - remove() - } - - useEffect(() => { - if (savedLink === undefined || savedLink === null) return - // eslint-disable-next-line @typescript-eslint/no-misused-promises - const interval = setInterval(async () => { - const res = await auth.telegram.link.verify({ - query: { code: savedLink.code }, - }) - - if (res.error) return console.error("custom error", res.error) - if (res.data instanceof APIError) return console.error("better-auth APIError", res.data) - if (!("verified" in res.data)) return console.error("unexpected response", res.data) - - const data = res.data as { verified: boolean; expired?: boolean } - - if (data.verified) { - clearInterval(interval) - handleComplete() - return - } - - if (data.expired) { - setExpired(true) - remove() - clearInterval(interval) - return - } - - console.log("polling... not verified or expired") - }, 5000) - return () => clearInterval(interval) - }, [savedLink, handleComplete, remove]) - - if (savedLink === undefined) return null - if (success) - return ( -
- -

Linked successfully!

-

Redirecting you in 5s...

-
- ) - - if (expired) - return ( -
- -

Code Expired!

- -
- ) - - return savedLink && timeLeft ? ( -
- - setExpired(true)} /> - -
- - - - - @{botUsername} - -

and then send

- /link -
- -

- Having troubles with this code?{" "} - -

-
- ) : ( -
-
- - setUsernameInput(e.target.value.replaceAll("@", ""))} - placeholder="example" - containerClassName="grow" - /> -
- -
- ) -} - -function Timer({ ttl, timeLeft: pTimeLeft, onEnd }: { ttl: number; timeLeft: number; onEnd: () => void }) { - const ttlMs = ttl * 1000 - const [timeLeft, setTimeLeft] = useState(pTimeLeft * 1000) - - const percentage = (timeLeft / ttlMs) * 100 - useEffect(() => { - if (timeLeft === 0) return - const interval = setInterval(() => { - setTimeLeft((prevTime) => { - if (prevTime <= 100) { - clearInterval(interval) - onEnd() - return 0 - } - return prevTime - 100 - }) - }, 100) - - return () => clearInterval(interval) - }, [onEnd, timeLeft]) - - return ( - <> - - - - - - - Time left: - {Math.floor(timeLeft / 1000)}s - - - ) -} diff --git a/src/app/(auth)/onboarding/no-role/page.tsx b/src/app/(auth)/onboarding/no-role/page.tsx deleted file mode 100644 index 7146387..0000000 --- a/src/app/(auth)/onboarding/no-role/page.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import Image from "next/image" -import { redirect } from "next/navigation" -import loginSvg2 from "@/assets/svg/login-2.svg" -import { Card } from "@/components/ui/card" -import { getUserRoles } from "@/server/actions/users" -import { getServerSession } from "@/server/auth" -import { Logout } from "../link/logout" - -export default async function OnboardingNoRole() { - const { data: session } = await getServerSession() - if (!session) redirect("/login") - if (!session.user.telegramId) redirect("/onboarding/link") - - const { roles } = await getUserRoles(session.user.telegramId) - if (roles?.includes("creator")) redirect("/onboarding/unauthorized") - if (roles && roles.length > 0) redirect("/dashboard") - - return ( -
- -
- insert credentials -
-

Your account is not enabled

-

Please contact an IT member

-
-
- - -
-
- ) -} diff --git a/src/app/dashboard/(active)/account/delete-passkey.tsx b/src/app/dashboard/(active)/account/delete-passkey.tsx deleted file mode 100644 index 56a1435..0000000 --- a/src/app/dashboard/(active)/account/delete-passkey.tsx +++ /dev/null @@ -1,51 +0,0 @@ -"use client" - -import { useRouter } from "next/navigation" -import { FiTrash2 } from "react-icons/fi" -import { toast } from "sonner" -import { - AlertDialog, - AlertDialogAction, - AlertDialogCancel, - AlertDialogContent, - AlertDialogDescription, - AlertDialogFooter, - AlertDialogHeader, - AlertDialogMedia, - AlertDialogTitle, - AlertDialogTrigger, -} from "@/components/ui/alert-dialog" -import { Button } from "@/components/ui/button" -import { auth } from "@/lib/auth" - -export function DeletePasskey({ id }: { id: string }) { - const router = useRouter() - - async function deletePasskey() { - const { data, error } = await auth.passkey.deletePasskey({ id }) - if (!data || error) return toast.error("There was an error") - toast.success("Passkey deleted!") - router.refresh() - } - - return ( - - Delete}> - - - - - - Remove passkey - Are you sure you want to delete this passkey? - - - Cancel - - Confirm - - - - - ) -} diff --git a/src/app/dashboard/(active)/account/loading.tsx b/src/app/dashboard/(active)/account/loading.tsx deleted file mode 100644 index f67b7c1..0000000 --- a/src/app/dashboard/(active)/account/loading.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import { Skeleton } from "@/components/ui/skeleton" -import { NewPasskeyButton } from "./passkey-button" - -export default function Loading() { - return ( -
-

Account

-
- - -
-
- Name: - -
- -
- Email: - -
-
- Telegram: - -
-
-
-
-

Passkeys

- - -
-
- ) -} diff --git a/src/app/dashboard/(active)/account/page.tsx b/src/app/dashboard/(active)/account/page.tsx deleted file mode 100644 index 8267448..0000000 --- a/src/app/dashboard/(active)/account/page.tsx +++ /dev/null @@ -1,67 +0,0 @@ -import { headers } from "next/headers" -import { FiAlertCircle, FiCalendar, FiKey } from "react-icons/fi" -import { auth } from "@/lib/auth" -import { getServerSession } from "@/server/auth" -import { DeletePasskey } from "./delete-passkey" -import { NewPasskeyButton } from "./passkey-button" -import { ProfilePic } from "./profile-pic" -import { SetName } from "./set-name" -import { Telegram } from "./telegram" - -export default async function Account() { - const { data: session } = await getServerSession() - if (!session) return - - const { data: passkeys } = await auth.passkey.listUserPasskeys({ - fetchOptions: { - headers: await headers(), - }, - }) - - const { user } = session - - return ( -
-

Account

-
- - -
-
- {!user.name && } - Name: - {user.name ?

{user.name}

: } -
- -
- Email: -

{user.email}

-
-
- Telegram: - -
-
-
-
-

Passkeys

- {passkeys?.map((p) => ( -
-
- -
-
-

{p.name}

-

- - Created on {p.createdAt.toLocaleDateString()} -

-
- -
- ))} - -
-
- ) -} diff --git a/src/app/dashboard/(active)/account/passkey-button.tsx b/src/app/dashboard/(active)/account/passkey-button.tsx deleted file mode 100644 index 0cd4836..0000000 --- a/src/app/dashboard/(active)/account/passkey-button.tsx +++ /dev/null @@ -1,35 +0,0 @@ -"use client" - -import { useRouter } from "next/navigation" -import { useState } from "react" -import { toast } from "sonner" -import { Button } from "@/components/ui/button" -import { auth } from "@/lib/auth" - -export function NewPasskeyButton() { - const router = useRouter() - const [isLoading, setIsLoading] = useState(false) - - return ( - - ) -} diff --git a/src/app/dashboard/(active)/account/profile-pic.tsx b/src/app/dashboard/(active)/account/profile-pic.tsx deleted file mode 100644 index bfdf238..0000000 --- a/src/app/dashboard/(active)/account/profile-pic.tsx +++ /dev/null @@ -1,108 +0,0 @@ -"use client" - -import type { User } from "better-auth" -import { useRouter } from "next/navigation" -import { forwardRef, useRef } from "react" -import { FiEdit2, FiUpload, FiUser, FiX } from "react-icons/fi" -import { toast } from "sonner" -import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar" -import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu" -import { auth, useSession } from "@/lib/auth" -import { getInitials } from "@/lib/utils" -import { updateProfilePic } from "@/server/actions/users" - -type Props = { - user: User -} - -export function ProfilePic({ user }: Props) { - const uploadRef = useRef(null) - const router = useRouter() - const { refetch } = useSession() - - async function handleRemove() { - const ok = confirm("Are you sure you want to reset your profile picture?") - if (!ok) return - - const r = await auth.updateUser({ image: null }) - if (r.error) { - toast.error("There was an error") - console.error(r.error) - return - } - - toast.success("Profile picture removed successfully'") - await refetch() - router.refresh() - } - - return ( -
- - - -
- -
-
- - uploadRef.current?.click()}> - Upload - - - Remove - - -
- - - - - - {user.name ? getInitials(user.name) : } - -
-

Max 1MB

-
- ) -} - -const UploadProfilePicture = forwardRef((_, ref) => { - const router = useRouter() - const { refetch } = useSession() - - const handleFileChange = async (event: React.ChangeEvent) => { - const files = event.target.files - if (files && files.length > 0) { - const selectedFile = files[0] - if (!selectedFile) return - - if (selectedFile.size > 1024 * 1024) { - toast.error("The image must be no larger than 1 MB") - return - } - - if (selectedFile.type !== "image/png" && selectedFile.type !== "image/jpeg") { - toast.error("The image must be jpeg or png") - return - } - - const { success } = await updateProfilePic(selectedFile) - if (success) toast.success("Image changed successfully!") - else toast.error("There was an error, try again") - await refetch() - router.refresh() - } - } - return ( - - ) -}) diff --git a/src/app/dashboard/(active)/account/set-name.tsx b/src/app/dashboard/(active)/account/set-name.tsx deleted file mode 100644 index e0c24b9..0000000 --- a/src/app/dashboard/(active)/account/set-name.tsx +++ /dev/null @@ -1,64 +0,0 @@ -"use client" - -import { useRouter } from "next/navigation" -import { type FormEvent, useState } from "react" -import { Button } from "@/components/ui/button" -import { - Dialog, - DialogClose, - DialogContent, - DialogDescription, - DialogFooter, - DialogHeader, - DialogTitle, - DialogTrigger, -} from "@/components/ui/dialog" -import { Input } from "@/components/ui/input" -import { Label } from "@/components/ui/label" -import { auth } from "@/lib/auth" - -export function SetName({ initialName }: { initialName?: string }) { - const router = useRouter() - const [name, setName] = useState(initialName ?? "") - const [open, setOpen] = useState(false) - - async function handleUpdate(e: FormEvent) { - e.preventDefault() - await auth.updateUser({ name }) - setOpen(false) - router.refresh() - } - - return ( - - Set name} /> - - - Set your name - Make changes to your profile here. Click save when you're done. - -
-
-
- - setName(e.target.value)} - /> -
-
- - - - - - -
-
-
- ) -} diff --git a/src/app/dashboard/(active)/account/telegram.tsx b/src/app/dashboard/(active)/account/telegram.tsx deleted file mode 100644 index d573433..0000000 --- a/src/app/dashboard/(active)/account/telegram.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { getUserRoles } from "@/server/actions/users" -import { getServerSession } from "@/server/auth" - -export async function Telegram() { - const { data } = await getServerSession() - if (!data || !data.user.telegramId) return null - - const { roles } = await getUserRoles(data.user.telegramId) - const length = roles?.length ?? 0 - - return ( - <> - {data.user.telegramUsername ? `@${data.user.telegramUsername}` : data.user.id} - {roles && length > 0 && (roles: {roles.join(", ")})} - - ) -} diff --git a/src/app/dashboard/(active)/azure/groups/groups-list.tsx b/src/app/dashboard/(active)/azure/groups/groups-list.tsx deleted file mode 100644 index 2bf11d5..0000000 --- a/src/app/dashboard/(active)/azure/groups/groups-list.tsx +++ /dev/null @@ -1,443 +0,0 @@ -"use client" - -import { useRouter } from "next/navigation" -import { useMemo, useState } from "react" -import { FiChevronDown, FiInfo, FiLoader, FiMail, FiUserMinus, FiUserPlus } from "react-icons/fi" -import { toast } from "sonner" -import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert" -import { Avatar, AvatarFallback, AvatarGroup, AvatarGroupCount } from "@/components/ui/avatar" -import { Badge } from "@/components/ui/badge" -import { Button } from "@/components/ui/button" -import { Card, CardContent, CardHeader } from "@/components/ui/card" -import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/components/ui/collapsible" -import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from "@/components/ui/command" -import { - Dialog, - DialogClose, - DialogContent, - DialogDescription, - DialogFooter, - DialogHeader, - DialogTitle, - DialogTrigger, -} from "@/components/ui/dialog" -import { Separator } from "@/components/ui/separator" -import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip" -import { addAzureGroupMember, removeAzureGroupMember } from "@/server/actions/azure" -import type { AzureGroup, AzureMember } from "@/server/trpc/types" - -const MAX_VISIBLE_MEMBERS = 7 - -function initials(name: string | null | undefined) { - const parts = name?.trim().split(/\s+/).filter(Boolean) ?? [] - if (parts.length === 0) return "?" - return parts - .slice(0, 2) - .map((part) => part[0]) - .join("") - .toUpperCase() -} - -function mutationErrorMessage(error: "UNAUTHORIZED" | "INTERNAL_SERVER_ERROR") { - if (error === "UNAUTHORIZED") return "You don't have permission to manage this group." - return "Microsoft 365 could not complete the change. Please try again." -} - -export function GroupsList({ groups, directoryMembers }: { groups: AzureGroup[]; directoryMembers: AzureMember[] }) { - const sortedGroups = useMemo(() => [...groups].sort((a, b) => a.displayName.localeCompare(b.displayName)), [groups]) - const multiMemberGroups = sortedGroups.filter((group) => group.members.length > 1) - const singleMemberGroups = sortedGroups.filter((group) => group.members.length <= 1) - const memberships = groups.reduce((count, group) => count + group.members.length, 0) - - return ( -
-
-

Azure directory

-
-
-
-

Microsoft 365 Groups

-
- {groups.length} groups - {memberships} memberships -
-
- - - Looking for groups with 0-1 member(s)? - - Groups with max one member are collected in a collapsed section at the bottom of the page. - - -
-
-
- - {multiMemberGroups.length > 0 && ( - - - - - - Groups with 2+ members - - {multiMemberGroups.length} {singleMemberGroups.length === 1 ? "group" : "groups"} - - - - - } - /> - - }> - {multiMemberGroups.map((group) => ( -
- - -
- ))} -
-
-
- )} - - {singleMemberGroups.length > 0 && ( - - - - - - Groups with 0-1 member - - {singleMemberGroups.length} {singleMemberGroups.length === 1 ? "group" : "groups"} - - - - - } - /> - - }> - {singleMemberGroups.map((group) => ( -
- - -
- ))} -
-
-
- )} -
- ) -} - -function GroupRow({ group, directoryMembers }: { group: AzureGroup; directoryMembers: AzureMember[] }) { - const sortedMembers = [...group.members].sort((a, b) => a.displayName.localeCompare(b.displayName)) - const visibleMembers = sortedMembers.slice(0, MAX_VISIBLE_MEMBERS) - const hiddenMembers = sortedMembers.slice(MAX_VISIBLE_MEMBERS) - - return ( -
-
-
-

{group.displayName}

- {group.mailAddress && ( -
- - {group.mailAddress} -
- )} -
- - {group.members.length} {group.members.length === 1 ? "member" : "members"} - -
- -
- {group.members.length > 0 ? ( - - {visibleMembers.map((member) => ( - - ))} - {hiddenMembers.length > 0 && } - - ) : ( -

No members yet

- )} -
- - -
-
-
- ) -} - -function MemberAvatar({ member }: { member: AzureGroup["members"][number] }) { - return ( - - - - {initials(member.displayName)} - - - {member.displayName} - - ) -} - -function HiddenMembersCount({ members }: { members: AzureGroup["members"] }) { - return ( - - - +{members.length} - - - {members.map((member) => ( -
- - {initials(member.displayName)} - - {member.displayName} -
- ))} -
-
- ) -} - -function AddMemberDialog({ group, directoryMembers }: { group: AzureGroup; directoryMembers: AzureMember[] }) { - const [open, setOpen] = useState(false) - const [pending, setPending] = useState(false) - const [selectedMember, setSelectedMember] = useState(null) - const router = useRouter() - - const availableMembers = useMemo(() => { - const currentIds = new Set(group.members.map((member) => member.id)) - return directoryMembers - .filter((member) => !currentIds.has(member.id)) - .sort((a, b) => (a.displayName ?? "").localeCompare(b.displayName ?? "")) - }, [directoryMembers, group.members]) - - function handleOpenChange(nextOpen: boolean) { - if (pending) return - setOpen(nextOpen) - if (!nextOpen) setSelectedMember(null) - } - - async function addMember() { - if (!selectedMember || pending) return - - setPending(true) - try { - const { error } = await addAzureGroupMember({ groupId: group.id, userId: selectedMember.id }) - if (error) { - toast.error(mutationErrorMessage(error)) - return - } - - toast.success(`${selectedMember.displayName ?? "Member"} added to ${group.displayName}.`) - setOpen(false) - setSelectedMember(null) - router.refresh() - } catch (error) { - console.error(error) - toast.error("There was an unexpected error while adding the member.") - } finally { - setPending(false) - } - } - - return ( - - - } - /> - } - > - - - Add member - - - - Add a group member - - Choose a directory user to add to {group.displayName}. - - - - - - - No available users found. - - {availableMembers.map((member) => ( - setSelectedMember(member)} - > - - {initials(member.displayName)} - -
- {member.displayName ?? "Unnamed user"} - {member.mail && {member.mail}} -
-
- ))} -
-
-
- - - - Cancel - - } - /> - - -
-
- ) -} - -function RemoveMemberDialog({ group, directoryMembers }: { group: AzureGroup; directoryMembers: AzureMember[] }) { - const [open, setOpen] = useState(false) - const [pending, setPending] = useState(false) - const [selectedMember, setSelectedMember] = useState(null) - const router = useRouter() - - const currentMembers = useMemo(() => { - const currentIds = new Set(group.members.map((member) => member.id)) - return directoryMembers - .filter((member) => currentIds.has(member.id)) - .sort((a, b) => (a.displayName ?? "").localeCompare(b.displayName ?? "")) - }, [directoryMembers, group.members]) - - function handleOpenChange(nextOpen: boolean) { - if (pending) return - setOpen(nextOpen) - if (!nextOpen) setSelectedMember(null) - } - - async function removeMember() { - if (!selectedMember || pending) return - - setPending(true) - try { - const { error } = await removeAzureGroupMember({ groupId: group.id, userId: selectedMember.id }) - if (error) { - toast.error(mutationErrorMessage(error)) - return - } - - toast.success(`${selectedMember.displayName ?? "Member"} removed from ${group.displayName}.`) - setOpen(false) - setSelectedMember(null) - router.refresh() - } catch (error) { - console.error(error) - toast.error("There was an unexpected error while removing the member.") - } finally { - setPending(false) - } - } - - return ( - - - - } - /> - } - > - - - Remove member - - - - - Remove a group member - - Choose a member to remove from {group.displayName}. - Their Microsoft 365 account will not be deleted. - - - - - - - No group members found. - - {currentMembers.map((member) => ( - setSelectedMember(member)} - > - - {initials(member.displayName)} - -
- {member.displayName ?? "Unnamed user"} - {member.mail && {member.mail}} -
-
- ))} -
-
-
- - - - Cancel - - } - /> - - -
-
- ) -} diff --git a/src/app/dashboard/(active)/azure/groups/loading.tsx b/src/app/dashboard/(active)/azure/groups/loading.tsx deleted file mode 100644 index cb33360..0000000 --- a/src/app/dashboard/(active)/azure/groups/loading.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import { Card, CardContent, CardHeader } from "@/components/ui/card" -import { Separator } from "@/components/ui/separator" -import { Skeleton } from "@/components/ui/skeleton" - -export default function Loading() { - return ( -
-
-
- - - -
- - - - - - - - {Array.from({ length: 4 }, (_, index) => ( -
- {index > 0 && } -
-
- - - -
-
- {Array.from({ length: 5 }, (_, avatarIndex) => ( - - ))} - -
-
-
- ))} -
-
-
-
- ) -} diff --git a/src/app/dashboard/(active)/azure/groups/page.tsx b/src/app/dashboard/(active)/azure/groups/page.tsx deleted file mode 100644 index ef7cfd2..0000000 --- a/src/app/dashboard/(active)/azure/groups/page.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import type { Metadata } from "next" -import { getAzureGroups, getAzureMembers } from "@/server/actions/azure" -import { GroupsList } from "./groups-list" - -export const metadata: Metadata = { - title: "Microsoft 365 Groups", -} - -export default async function AzureGroupsPage() { - const [groups, directoryMembers] = await Promise.all([getAzureGroups(), getAzureMembers()]) - - return ( -
- -
- ) -} diff --git a/src/app/dashboard/(active)/azure/members/columns.tsx b/src/app/dashboard/(active)/azure/members/columns.tsx deleted file mode 100644 index 0673bbf..0000000 --- a/src/app/dashboard/(active)/azure/members/columns.tsx +++ /dev/null @@ -1,50 +0,0 @@ -"use client" -import { createColumnHelper, type Row } from "@tanstack/react-table" -import { Badge } from "@/components/ui/badge" -import type { AzureMember } from "@/server/trpc/types" -import { SetAssocNumberDialog } from "./set-assoc-number-dialog" - -const ch = createColumnHelper() - -export const columns = [ - ch.accessor("employeeId", { - id: "number", - header: "#", - footer: (props) => props.column.id, - cell: ({ getValue, row }) => { - const value = getValue() - return value ? {value} : - }, - }), - ch.accessor("displayName", { - id: "displayName", - header: "Full Name", - cell: ({ getValue, row }) => ( - <> - {row.original.isMember && Socio} - {getValue()} - - ), - }), - ch.accessor("mail", { id: "mail", header: "Email" }), - ch.accessor("assignedLicensesIds", { - id: "licenses", - header: "Licenses", - cell: ({ getValue }) => { - const licenses = getValue().sort((a, b) => a.localeCompare(b)) - return licenses.map((l) => ( - - {l} - - )) - }, - }), - ch.group({ - id: "actions", - cell: (props) => , - }), -] - -function RowActions({ row: _ }: { row: Row }) { - return
-} diff --git a/src/app/dashboard/(active)/azure/members/create-assoc-member.tsx b/src/app/dashboard/(active)/azure/members/create-assoc-member.tsx deleted file mode 100644 index 3e741f4..0000000 --- a/src/app/dashboard/(active)/azure/members/create-assoc-member.tsx +++ /dev/null @@ -1,140 +0,0 @@ -"use client" -import { useRouter } from "next/navigation" -import { useState, useTransition } from "react" -import { toast } from "sonner" -import { Button } from "@/components/ui/button" -import { Input } from "@/components/ui/input" -import { Label } from "@/components/ui/label" -import { - Sheet, - SheetClose, - SheetContent, - SheetFooter, - SheetHeader, - SheetTitle, - SheetTrigger, -} from "@/components/ui/sheet" -import { createAzureMember } from "@/server/actions/azure" - -export function CreateAssocUser() { - const [open, setOpen] = useState(false) - const [firstName, setFirstName] = useState("") - const [lastName, setLastName] = useState("") - const [assocNumber, setAssocNumber] = useState("") - const [sendTo, setSendTo] = useState("") - const router = useRouter() - - function handleOpenChange(v: boolean): void { - setOpen(v) - setFirstName("") - setLastName("") - setAssocNumber("") - setSendTo("") - } - - const [pending, startTransition] = useTransition() - - async function handleSubmit() { - if (!assocNumber || Number.isNaN(parseInt(assocNumber, 10))) return - - const res = await createAzureMember({ - assocNumber: parseInt(assocNumber, 10), - firstName, - lastName, - sendEmailTo: sendTo, - }).catch(() => null) - - if (!res) { - toast.error("There was an error") - return - } - - if (res.error !== null) { - toast.error(res.error) - return - } - - console.log("Created user", res) - toast.success(`User created, email: ${res.email}`, { duration: 10_000 }) - router.refresh() - handleOpenChange(false) - } - - return ( - - New Member}> - - - Create new member account - -
startTransition(handleSubmit)}> -
-
- - setFirstName(e.target.value)} - /> -
-
- - setLastName(e.target.value)} - /> -
- -
- - setAssocNumber(e.target.value)} - /> -
- -
- - setSendTo(e.target.value)} - /> -
-
- - - - - - -
-
-
- ) -} diff --git a/src/app/dashboard/(active)/azure/members/loading.tsx b/src/app/dashboard/(active)/azure/members/loading.tsx deleted file mode 100644 index a6bd30c..0000000 --- a/src/app/dashboard/(active)/azure/members/loading.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import { SkeletonAssocTable } from "./table" - -export default function Loading() { - return ( -
- -
- ) -} diff --git a/src/app/dashboard/(active)/azure/members/page.tsx b/src/app/dashboard/(active)/azure/members/page.tsx deleted file mode 100644 index 4a4d975..0000000 --- a/src/app/dashboard/(active)/azure/members/page.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import { Suspense } from "react" -import { ErrorBoundary } from "react-error-boundary" -import { Spinner } from "@/components/spinner" -import { getAzureMembers } from "@/server/actions/azure" -import { AssocTable } from "./table" - -export default async function AssocMembers() { - const members = await getAzureMembers() - - return ( -
- Something went wrong
}> - }> - - - -
- ) -} diff --git a/src/app/dashboard/(active)/azure/members/set-assoc-number-dialog.tsx b/src/app/dashboard/(active)/azure/members/set-assoc-number-dialog.tsx deleted file mode 100644 index ae3e7dc..0000000 --- a/src/app/dashboard/(active)/azure/members/set-assoc-number-dialog.tsx +++ /dev/null @@ -1,97 +0,0 @@ -"use client" -import { useRouter } from "next/navigation" -import { useState, useTransition } from "react" -import { toast } from "sonner" -import { Button } from "@/components/ui/button" -import { - Dialog, - DialogClose, - DialogContent, - DialogDescription, - DialogFooter, - DialogHeader, - DialogTitle, - DialogTrigger, -} from "@/components/ui/dialog" -import { Input } from "@/components/ui/input" -import { Label } from "@/components/ui/label" -import { wait } from "@/lib/utils" -import { setAzureMemberNumber } from "@/server/actions/azure" - -export function SetAssocNumberDialog({ userId }: { userId: string }) { - const router = useRouter() - const [value, setValue] = useState("") - const [open, setOpen] = useState(false) - - function handleOpenChange(v: boolean): void { - setOpen(v) - setValue("") - } - - const [pending, startTransition] = useTransition() - - async function handleSubmit() { - if (pending || !value || Number.isNaN(parseInt(value, 10))) return - - const loading = toast.loading(`Updating...`) - const res = await setAzureMemberNumber({ userId, assocNumber: parseInt(value, 10) }) - handleOpenChange(false) - if (res.error !== null) { - toast.error("There was an error") - console.error(res.error) - return - } - - await wait(2000) - toast.success(`Updated successfully!`, { id: loading }) - router.refresh() - console.log("Updated user assocNumber", userId, value) - } - - return ( - - - Set - - } - /> - - - Set Assoc Number - This changes the `employeeId` field in the Azure User properties. - -
startTransition(handleSubmit)}> -
- - setValue(e.target.value)} - /> -
- - - Cancel - - } - > - - -
-
-
- ) -} diff --git a/src/app/dashboard/(active)/azure/members/table.tsx b/src/app/dashboard/(active)/azure/members/table.tsx deleted file mode 100644 index 8209cf5..0000000 --- a/src/app/dashboard/(active)/azure/members/table.tsx +++ /dev/null @@ -1,72 +0,0 @@ -"use client" - -import { useState } from "react" -import { DataTable } from "@/components/data-table" -import { Badge } from "@/components/ui/badge" -import { Skeleton } from "@/components/ui/skeleton" -import type { AzureMember } from "@/server/trpc/types" -import { columns } from "./columns" -import { CreateAssocUser } from "./create-assoc-member" - -function sortByAssocNumber(users: AzureMember[]) { - if (!users || users.length === 0) return users - if (users.every((u) => !u.employeeId)) - return users.sort((a, b) => (a.displayName ?? "").localeCompare(b.displayName ?? "")) - - return users.sort((a, b) => { - if (a.employeeId && b.employeeId) { - const aInt = parseInt(a.employeeId, 10) - const bInt = parseInt(b.employeeId, 10) - if (Number.isNaN(aInt) && Number.isNaN(bInt)) return 0 - if (Number.isNaN(aInt)) return 1 - if (Number.isNaN(bInt)) return -1 - return aInt - bInt - } - if (a.employeeId) return -1 - if (b.employeeId) return 1 - return 0 - }) -} - -export function AssocTable({ members }: { members: AzureMember[] }) { - const [sociFilter, setSociFilter] = useState(false) - const users = sociFilter ? members.filter((v) => v.isMember) : members - - return ( -
-
-

Utenti MS @polinetwork.org

- setSociFilter((v) => !v)} - > - {members.filter((d) => d.isMember).length} Soci - - {members.filter((d) => !d.isMember).length} fuori - {users.filter((u) => u.assignedLicensesIds.includes("OFFICE_365")).length} licenze Office -
- -
- - -
- ) -} - -export function SkeletonAssocTable() { - return ( -
-
-

Utenti MS @polinetwork.org

- - - -
- -
- - -
- ) -} diff --git a/src/app/dashboard/(active)/breadcrumb.tsx b/src/app/dashboard/(active)/breadcrumb.tsx deleted file mode 100644 index 17052fe..0000000 --- a/src/app/dashboard/(active)/breadcrumb.tsx +++ /dev/null @@ -1,74 +0,0 @@ -"use client" -import { usePathname } from "next/navigation" -import { Fragment, useMemo } from "react" -import { NAV_MAP } from "@/components/dashboard-sidebar/data" -import { - BreadcrumbItem as BreadcrumbItemComponent, - BreadcrumbLink, - BreadcrumbList, - BreadcrumbPage, - Breadcrumb as BreadcrumbRoot, - BreadcrumbSeparator, -} from "@/components/ui/breadcrumb" - -export type BreadcrumbItem = { - title: string - url?: string -} - -export function Breadcrumb({ className, ...props }: React.ComponentProps<"nav">) { - const pathname = usePathname() - const items = useMemo(() => getBreadcrumbs(NAV_MAP, pathname), [pathname]) - - return ( - - - {items.map((item, i) => ( - - - {i === items.length - 1 ? ( - {item.title} - ) : item.url ? ( - {item.title} - ) : ( - item.title - )} - - {i < items.length - 1 && } - - ))} - - - ) -} - -function getBreadcrumbs(navMap: Map, pathname: string): BreadcrumbItem[] { - const segments = pathname.split("/").filter(Boolean) - const breadcrumbs: BreadcrumbItem[] = [] - - let currentPath = "" - let i = 0 - - for (const segment of segments) { - currentPath += `/${segment}` - let title = navMap.get(currentPath) - if (!title) { - if (isUUIDorId(segment)) { - title = "Details" - } else { - title = segment.charAt(0).toUpperCase() + segment.slice(1) - } - } - - // note: at the moment we do not plan to make category pages. - // If such pages are made in the future, this logic can be removed - breadcrumbs.push({ title, url: i !== 1 ? currentPath : undefined }) - i++ - } - - return breadcrumbs -} - -function isUUIDorId(segment: string) { - return !Number.isNaN(Number(segment)) || segment.length > 20 // Regex custom a seconda dei tuoi ID -} diff --git a/src/app/dashboard/(active)/complete-profile.tsx b/src/app/dashboard/(active)/complete-profile.tsx deleted file mode 100644 index 10c0eb4..0000000 --- a/src/app/dashboard/(active)/complete-profile.tsx +++ /dev/null @@ -1,24 +0,0 @@ -"use client" - -import Link from "next/link" -import { FiEdit3 } from "react-icons/fi" -import { Button } from "@/components/ui/button" -import { useSession } from "@/lib/auth" - -export function CompleteProfile() { - const { data, isPending } = useSession() - - if (!data || isPending) return null - - return ( - !data.user.name && ( -
- -

Your profile is incomplete, please enter the missing information.

- - - -
- ) - ) -} diff --git a/src/app/dashboard/(active)/layout.tsx b/src/app/dashboard/(active)/layout.tsx deleted file mode 100644 index 016881d..0000000 --- a/src/app/dashboard/(active)/layout.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import { cookies } from "next/headers" -import { DashboardSidebar } from "@/components/dashboard-sidebar" -import { SidebarInset, SidebarProvider, SidebarTrigger } from "@/components/ui/sidebar" -import { COOKIES } from "@/constants" -import { Breadcrumb } from "./breadcrumb" - -function parseCookie(cookie: string) { - try { - const parsed = JSON.parse(cookie) - return parsed - } catch (_e) { - return {} - } -} - -export default async function AdminLayout({ children }: { children: React.ReactNode }) { - const sidebarCookies = await getSidebarCookies() - - return ( - - - -
- - -
-
- {children} -
-
- ) -} - -async function getSidebarCookies() { - const cookieStore = await cookies() - - const sidebarCategoryStateCookie = cookieStore.get(COOKIES.SIDEBAR_CATEGORY_STATE)?.value - const sidebarOpenCookie = cookieStore.get(COOKIES.SIDEBAR_OPEN)?.value - const state: Record = sidebarCategoryStateCookie ? parseCookie(sidebarCategoryStateCookie) : {} - const open: boolean = sidebarOpenCookie !== undefined ? parseCookie(sidebarOpenCookie) : true - - return { state, open } -} diff --git a/src/app/dashboard/(active)/not-found.tsx b/src/app/dashboard/(active)/not-found.tsx deleted file mode 100644 index e962605..0000000 --- a/src/app/dashboard/(active)/not-found.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import Link from "next/link" -import { Button } from "@/components/ui/button" - -export default function NotFound() { - return ( -
-
-

404

-

Not found

-

- The resource you're looking for doesn't exist or has been moved. -

-
- - - -
- ) -} diff --git a/src/app/dashboard/(active)/page.tsx b/src/app/dashboard/(active)/page.tsx deleted file mode 100644 index b22e159..0000000 --- a/src/app/dashboard/(active)/page.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import { FiInfo } from "react-icons/fi" -import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert" -import { CompleteProfile } from "./complete-profile" - -export default function AdminHome() { - return ( -
- - - - Page under construction - Use the sidebar to access the sections - -
- ) -} diff --git a/src/app/dashboard/(active)/telegram/grants/delete-grant.tsx b/src/app/dashboard/(active)/telegram/grants/delete-grant.tsx deleted file mode 100644 index 2eb277b..0000000 --- a/src/app/dashboard/(active)/telegram/grants/delete-grant.tsx +++ /dev/null @@ -1,83 +0,0 @@ -"use client" - -import { useRouter } from "next/navigation" -import { useState } from "react" -import { FiAlertOctagon } from "react-icons/fi" -import { toast } from "sonner" -import { - AlertDialog, - AlertDialogAction, - AlertDialogCancel, - AlertDialogContent, - AlertDialogDescription, - AlertDialogFooter, - AlertDialogHeader, - AlertDialogMedia, - AlertDialogTitle, - AlertDialogTrigger, -} from "@/components/ui/alert-dialog" -import { Button } from "@/components/ui/button" -import { interruptGrant } from "@/server/actions/grants" - -export function DeleteGrant({ - userId, - // onDelete -}: { - userId: number - // onDelete(): void -}) { - const router = useRouter() - const [open, setOpen] = useState(false) - - async function interrupt() { - try { - const { error } = await interruptGrant(userId) - - if (error === "NOT_FOUND") toast.info("The grant was expired or already interrupted") - else if (error === "UNAUTHORIZED") toast.error("You don't have enough permission") - else if (error === "INTERNAL_SERVER_ERROR") toast.error("There was an internal server error") - else { - toast.success("Grant interrupted successfully") - router.refresh() - // onDelete() - } - } catch (err) { - toast.error("There was an error") - console.error(err) - } finally { - handleOpenChange(false) - } - } - - function handleOpenChange(v: boolean) { - setOpen(v) - } - - return ( - - - - Interrupt - - } - > - - - - - - Interrupt Grant - Are you sure you want to interrupt the grant? - - - Cancel - - Confirm - - - - - ) -} diff --git a/src/app/dashboard/(active)/telegram/grants/grant-list.tsx b/src/app/dashboard/(active)/telegram/grants/grant-list.tsx deleted file mode 100644 index aeb93a0..0000000 --- a/src/app/dashboard/(active)/telegram/grants/grant-list.tsx +++ /dev/null @@ -1,42 +0,0 @@ -"use client" -import { format } from "date-fns" -import type { ApiOutput } from "@/server/trpc/types" -import { DeleteGrant } from "./delete-grant" - -type Grants = NonNullable - -export function GrantList({ grants, isScheduled }: { grants: Grants; isScheduled?: boolean }) { - return ( -
-
-

Telegram ID

-

Username

-

Start Date

-

End Date

-

Interrupt

-
- {grants.map((r) => ( - - ))} - {grants.length === 0 && ( -
- There are no {isScheduled ? "scheduled" : "ongoing"} grants -
- )} -
- ) -} - -function GrantRow({ row: r }: { row: Grants[number] }) { - return ( -
-

{r.grant.userId}

-

- {r.user?.username ? `@${r.user.username}` : ``} -

-

{format(r.grant.validSince, "yyyy/MM/dd HH:mm")}

-

{format(r.grant.validUntil, "yyyy/MM/dd HH:mm")}

- -
- ) -} diff --git a/src/app/dashboard/(active)/telegram/grants/loading.tsx b/src/app/dashboard/(active)/telegram/grants/loading.tsx deleted file mode 100644 index 3d6aca2..0000000 --- a/src/app/dashboard/(active)/telegram/grants/loading.tsx +++ /dev/null @@ -1,51 +0,0 @@ -import { Skeleton } from "@/components/ui/skeleton" -import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs" -import { NewGrant } from "./new-grant" - -export default async function Loading() { - return ( -
-
-

Telegram Grants

- -
- - - - - All - - Ongoing - Scheduled - - - - - - - - - - - - -
- ) -} - -function Content() { - return ( -
-
-

Telegram ID

-

Username

-

Start Date

-

End Date

-

Interrupt

-
- {new Array(6).fill(0).map((_, i) => ( - - ))} -
- ) -} diff --git a/src/app/dashboard/(active)/telegram/grants/new-grant.tsx b/src/app/dashboard/(active)/telegram/grants/new-grant.tsx deleted file mode 100644 index 7c709c1..0000000 --- a/src/app/dashboard/(active)/telegram/grants/new-grant.tsx +++ /dev/null @@ -1,254 +0,0 @@ -"use client" - -import { format } from "date-fns" -import { useRouter } from "next/navigation" -import { useCallback, useEffect, useState } from "react" -import { FiChevronDown, FiPlus } from "react-icons/fi" -import { toast } from "sonner" -import { Button } from "@/components/ui/button" -import { Calendar } from "@/components/ui/calendar" -import { - Dialog, - DialogClose, - DialogContent, - DialogDescription, - DialogFooter, - DialogHeader, - DialogTitle, - DialogTrigger, -} from "@/components/ui/dialog" -import { Field, FieldGroup, FieldLabel } from "@/components/ui/field" -import { Input } from "@/components/ui/input" -import { Label } from "@/components/ui/label" -import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover" -import { - Select, - SelectContent, - SelectGroup, - SelectItem, - SelectLabel, - SelectSeparator, - SelectTrigger, - SelectValue, -} from "@/components/ui/select" -import { UserSelect } from "@/components/user-select" -import { useSession } from "@/lib/auth" -import { createGrant } from "@/server/actions/grants" -import type { TgUser } from "@/server/trpc/types" - -export function NewGrant() { - const sesh = useSession() - const router = useRouter() - const adderId = sesh.data?.user.telegramId - - const [open, setOpen] = useState(false) - const [user, setUser] = useState(null) - const [startDate, setStartDate] = useState() - const [endDate, setEndDate] = useState() - const [reason, setReason] = useState("") - - const disabled = !user || !startDate || !endDate || endDate.getTime() < Date.now() - - function handleOpenChange(v: boolean) { - setOpen(v) - if (v === false) { - setUser(null) - setStartDate(undefined) - setEndDate(undefined) - setReason("") - } - } - - const handleDateSelect = useCallback((date: Date, startTime: number, duration: number) => { - const startDate = new Date(date.getTime()) - startDate.setHours(startTime) - startDate.setMinutes(0) - startDate.setSeconds(0) - setStartDate(startDate) - - const endDate = new Date(startDate.getTime()) - endDate.setTime(endDate.getTime() + duration * 1000) - endDate.setSeconds(0) - setEndDate(endDate) - }, []) - - const isPast = endDate && endDate.getTime() < Date.now() - - async function create() { - if (!user || !startDate || !endDate || !adderId) return - const res = await createGrant({ - userId: user.id, - since: startDate, - until: endDate, - reason: reason || undefined, - }) - - if (res.error === "UNAUTHORIZED") toast.error("You don't have permission to create grants.") - else if (res.error === "ALREADY_EXISTING") toast.error("This user already has an ongoing grant.") - else if (res.error === "INTERNAL_SERVER_ERROR") toast.error("There was a server error.") - else { - toast.success("Grant created successfully!") - router.refresh() - } - - handleOpenChange(false) - } - - return ( - - - New Grant - - } - /> - - - New Grant - Create a grant to allow user to skip the auto moderation stack. - - - setUser(user)} onReset={() => setUser(null)} /> - - - -
-

Start Date: {startDate && format(startDate, "yyyy/MM/dd HH:mm")}

-

End Date: {endDate && format(endDate, "yyyy/MM/dd HH:mm")}

- - {isPast &&

The end datetime is in the past

} -
- -
- - setReason(v.target.value)} - placeholder="Reason for the grant..." - /> -
- - - Cancel} /> - - -
-
- ) -} - -function DatePicker({ onSelect }: { onSelect: (date: Date, startTime: number, duration: number) => void }) { - const [date, setDate] = useState(new Date()) - const [startTime, setStartTime] = useState(null) - const [duration, setDuration] = useState(null) - const [open, setOpen] = useState(false) - - const hours = [ - { label: "1h", value: 3600 }, - { label: "2h", value: 7200 }, - { label: "6h", value: 21600 }, - { label: "12h", value: 43200 }, - ] - const days = [ - { label: "1d", value: 86400 }, - { label: "2d", value: 172800 }, - { label: "7d", value: 604800 }, - ] - const durations = [{ label: "Select...", value: null }, ...hours, ...days] - - const times = [ - { label: "Select...", value: null }, - ...Array.from({ length: 13 }, (_, i) => ({ - label: `${String(i + 8).padStart(2, "0")}:00`, - value: i + 8, - })), - ] - - useEffect(() => { - if (date !== undefined && startTime !== null && duration !== null) { - onSelect(date, startTime, duration) - } - }, [date, duration, onSelect, startTime]) - - return ( - - - Date - - - {date ? format(date, "PPP") : "Select date"} - - - } - /> - - { - setDate(date) - setOpen(false) - }} - /> - - - - - Start Time - - - - Duration - - - - ) -} diff --git a/src/app/dashboard/(active)/telegram/grants/page.tsx b/src/app/dashboard/(active)/telegram/grants/page.tsx deleted file mode 100644 index 0ca8cb4..0000000 --- a/src/app/dashboard/(active)/telegram/grants/page.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs" -import { trpc } from "@/server/trpc" -import { GrantList } from "./grant-list" -import { NewGrant } from "./new-grant" - -export default async function GrantsPage() { - const { grants: ongoing } = await trpc.tg.grants.getOngoing.query() - const { grants: scheduled } = await trpc.tg.grants.getScheduled.query() - - return ( -
-
-

Telegram Grants

- -
- - - - - All - - Ongoing - Scheduled - - - - - - - - - - - -
- ) -} diff --git a/src/app/dashboard/(active)/telegram/groups/group-row.tsx b/src/app/dashboard/(active)/telegram/groups/group-row.tsx deleted file mode 100644 index e17328d..0000000 --- a/src/app/dashboard/(active)/telegram/groups/group-row.tsx +++ /dev/null @@ -1,76 +0,0 @@ -"use client" -import { useRouter } from "next/navigation" -import { FiCopy } from "react-icons/fi" -import { toast } from "sonner" -import { Badge } from "@/components/ui/badge" -import { Button } from "@/components/ui/button" -import { setGroupHide } from "@/server/actions/groups" -import type { TgGroup } from "@/server/trpc/types" -import { LeaveChat } from "./leave-chat" - -export function GroupRow({ row: r }: { row: TgGroup }) { - const router = useRouter() - - async function toggleHide() { - const ok = await setGroupHide(r.telegramId, !r.hide).catch(() => false) - if (!ok) { - toast.error("The field cannot be modified") - } else { - toast.success("Hide option toggled!") - router.refresh() - } - } - - return ( -
-

{r.telegramId}

-

{r.title}

-

{r.tag ? `@${r.tag}` : ``}

-
- {r.link && ( - - {r.link} - - )} - -
-
-

- {r.hide ? ( - - HIDDEN - - ) : ( - - Visibile - - )} -

- -
-
- ) -} diff --git a/src/app/dashboard/(active)/telegram/groups/leave-chat.tsx b/src/app/dashboard/(active)/telegram/groups/leave-chat.tsx deleted file mode 100644 index 221564b..0000000 --- a/src/app/dashboard/(active)/telegram/groups/leave-chat.tsx +++ /dev/null @@ -1,84 +0,0 @@ -"use client" - -import { useRouter } from "next/navigation" -import { useState } from "react" -import { FiAlertOctagon, FiTrash2 } from "react-icons/fi" -import { toast } from "sonner" -import { Spinner } from "@/components/spinner" -import { - AlertDialog, - AlertDialogAction, - AlertDialogCancel, - AlertDialogContent, - AlertDialogDescription, - AlertDialogFooter, - AlertDialogHeader, - AlertDialogMedia, - AlertDialogTitle, - AlertDialogTrigger, -} from "@/components/ui/alert-dialog" -import { Button } from "@/components/ui/button" -import { leaveChat } from "@/server/actions/groups" - -export function LeaveChat({ chatId }: { chatId: number }) { - const router = useRouter() - const [open, setOpen] = useState(false) - const [pending, setPending] = useState(false) - - async function submit() { - setPending(true) - try { - const { error } = await leaveChat(chatId) - - if (error === "UNAUTHORIZED") toast.error("You don't have enough permission") - else if (error === "BOT_ERROR") { - toast.error("Cannot leave the group") - } else if (error === "NOT_FOUND") { - toast.warning("Group left BUT not found in db") - } else { - toast.success("Group left and deleted") - router.refresh() - } - } catch (err) { - toast.error("There was an error") - console.error(err) - } finally { - setPending(false) - handleOpenChange(false) - } - } - - function handleOpenChange(v: boolean) { - setOpen(v) - } - - return ( - - - - Leave - - } - > - - - - - - Leave chat - - This will make the bot leave the chat and the backend delete the group from the table. - - - - Cancel - - {pending ? : "Confirm"} - - - - - ) -} diff --git a/src/app/dashboard/(active)/telegram/groups/loading.tsx b/src/app/dashboard/(active)/telegram/groups/loading.tsx deleted file mode 100644 index b66a765..0000000 --- a/src/app/dashboard/(active)/telegram/groups/loading.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import { SearchInput } from "@/components/search-input" -import { Skeleton } from "@/components/ui/skeleton" - -export default async function Loading() { - return ( -
- -
-

Count:

- -
-
-
-

Telegram ID

-

Title

-

Tag

-

Invite Link

-

Actions

-
- {new Array(12).fill(0).map((_, i) => ( - - ))} -
-
- ) -} diff --git a/src/app/dashboard/(active)/telegram/groups/page.tsx b/src/app/dashboard/(active)/telegram/groups/page.tsx deleted file mode 100644 index 47ba9cd..0000000 --- a/src/app/dashboard/(active)/telegram/groups/page.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import { SearchInput } from "@/components/search-input" -import { trpc } from "@/server/trpc" -import { GroupRow } from "./group-row" - -export default async function TgGroups({ searchParams }: { searchParams: Promise<{ q?: string }> }) { - const { q } = await searchParams - - const rows = q - ? (await trpc.tg.groups.search.query({ limit: 20, query: q, showHidden: true })).groups - : await trpc.tg.groups.getAll.query() - - const sorted = rows.sort((a, b) => a.title.localeCompare(b.title)) - - return ( -
- -

- Count: {rows.length} -

-
-
-

Telegram ID

-

Title

-

Tag

-

Invite Link

-

Actions

-
- {sorted.map((r) => ( - - ))} -
-
- ) -} diff --git a/src/app/dashboard/(active)/telegram/users/[id]/add-role.tsx b/src/app/dashboard/(active)/telegram/users/[id]/add-role.tsx deleted file mode 100644 index c702ab1..0000000 --- a/src/app/dashboard/(active)/telegram/users/[id]/add-role.tsx +++ /dev/null @@ -1,148 +0,0 @@ -"use client" -import { USER_ROLE } from "@polinetwork/backend" -import { useRouter } from "next/navigation" -import { useState } from "react" -import { FiPlus } from "react-icons/fi" -import { toast } from "sonner" -import { Spinner } from "@/components/spinner" -import { Badge } from "@/components/ui/badge" -import { Button } from "@/components/ui/button" -import { - Dialog, - DialogClose, - DialogContent, - DialogDescription, - DialogFooter, - DialogHeader, - DialogTitle, - DialogTrigger, -} from "@/components/ui/dialog" -import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select" -import { addUserRole } from "@/server/actions/users" -import type { TgUser, TgUserRole } from "@/server/trpc/types" - -const ARRAY_USER_ROLES = [ - USER_ROLE.ADMIN, - USER_ROLE.HR, - USER_ROLE.OWNER, - USER_ROLE.CREATOR, - USER_ROLE.DIRETTIVO, - USER_ROLE.PRESIDENT, -] as const - -export function AddRole({ - user, - alreadyRoles, - // onAdd -}: { - user: TgUser - alreadyRoles: TgUserRole[] - // onAdd(): void -}) { - const availableRoles = ARRAY_USER_ROLES.filter((r) => !alreadyRoles.includes(r)).map((g) => ({ - value: g, - label: `${g.slice(0, 1).toUpperCase()}${g.slice(1)}`, - })) - - const [open, setOpen] = useState(false) - const [pending, setPending] = useState(false) - const [selectedRole, setSelectedRole] = useState(null) - - const router = useRouter() - - async function submit() { - if (!selectedRole) return toast.warning("No group selected, cannot proceed") - if (!user) return toast.warning("Invalid user, try restarting the dialog") - - setPending(true) - - try { - const { error } = await addUserRole(user.id, selectedRole) - - if (error === "UNAUTHORIZED") toast.error("You don't have enough permission") - else if (error === "INTERNAL_SERVER_ERROR") toast.error("There was an internal server error") - else if (error === "UNAUTHORIZED_SELF_ASSIGN") toast.error("You cannot add roles to yourself") - else { - toast.success(`Role added!`) - router.refresh() - // onAdd() - } - handleOpenChange(false) - } catch (err) { - console.error(err) - toast.error("There was an error, check logs") - } finally { - setPending(false) - handleOpenChange(false) - } - } - - function handleOpenChange(v: boolean) { - setOpen(v) - if (v === false) { - setSelectedRole(null) - } - } - - return ( - - - Add Role - - } - /> - - - Add Role - Add a new role to a telegram user - - {user && ( -

- Target: {user.firstName} {user.username && `@${user.username}`} [{user.id}] -

- )} -
- User roles: - {alreadyRoles.map((r) => ( - {r} - ))} -
- - - - - - Cancel - - } - /> - - -
-
- ) -} diff --git a/src/app/dashboard/(active)/telegram/users/[id]/card-audit-log.tsx b/src/app/dashboard/(active)/telegram/users/[id]/card-audit-log.tsx deleted file mode 100644 index 4c412d8..0000000 --- a/src/app/dashboard/(active)/telegram/users/[id]/card-audit-log.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card" -import { fmtUser } from "@/lib/utils/telegram" -import type { getUserDetails } from "@/server/actions/users" - -type Data = Awaited> -type Log = NonNullable["audits"][number] - -export function AuditLogCard({ log: m }: { log: Log }) { - return ( - - - {m.type} - - - Chat: -

- {m.groupTitle && {m.groupTitle}} [{m.groupId}] -

- Admin ID: -

{m.admin && fmtUser(m.admin)}

- - {m.createdAt && ( - <> - Created: -

{m.createdAt.toLocaleString()}

- - )} - - {m.until && ( - <> - Until: -

{m.until.toLocaleString()}

- - )} - Reason: - {m.reason ?

{m.reason}

:

N/A

} -
-
- ) -} diff --git a/src/app/dashboard/(active)/telegram/users/[id]/card-group-admin.tsx b/src/app/dashboard/(active)/telegram/users/[id]/card-group-admin.tsx deleted file mode 100644 index ea70a93..0000000 --- a/src/app/dashboard/(active)/telegram/users/[id]/card-group-admin.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import { Code } from "@/components/code" -import { Card, CardContent, CardFooter, CardHeader, CardTitle } from "@/components/ui/card" -import { stripChatId } from "@/lib/utils/telegram" -import type { ApiOutput } from "@/server/trpc/types" -import { DeleteGroupAdmin } from "./delete-group-admin" - -type User = ApiOutput["tg"]["users"]["getByUsername"]["user"] -type GroupAdminSingle = NonNullable - -export function GroupAdminCard({ - user, - groupAdminInfo: m, - // onDelete, -}: { - user: NonNullable - groupAdminInfo: GroupAdminSingle - // onDelete(): void -}) { - return ( - - - {m.group.title} - - -

- Chat ID: - {m.group.id} / {stripChatId(m.group.id)} -

-

- Added By: - {m.addedBy.firstName} {m.addedBy.username ? `@${m.addedBy.username}` : ""} -

-
- - - -
- ) -} diff --git a/src/app/dashboard/(active)/telegram/users/[id]/card-message.tsx b/src/app/dashboard/(active)/telegram/users/[id]/card-message.tsx deleted file mode 100644 index 4f60cda..0000000 --- a/src/app/dashboard/(active)/telegram/users/[id]/card-message.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import { FiExternalLink } from "react-icons/fi" -import { Button } from "@/components/ui/button" -import { Card, CardContent, CardFooter } from "@/components/ui/card" -import { stripChatId } from "@/lib/utils/telegram" -import type { ApiOutput } from "@/server/trpc/types" - -type Message = NonNullable[number] -export function MessageCard({ message: m }: { message: Message }) { - return ( - - -

- Chat: - {m.group && {m.group.title}} [{m.chatId}] -

-

- Message ID: - {m.messageId} -

-

- Timestamp: - {m.timestamp.toLocaleString()} -

- Content: -

- {m.message.slice(0, 40)} {m.message.length >= 40 && "[...]"} -

-
- - {m.group?.inviteLink && ( - - - - )} - - - - -
- ) -} diff --git a/src/app/dashboard/(active)/telegram/users/[id]/card-user-grant.tsx b/src/app/dashboard/(active)/telegram/users/[id]/card-user-grant.tsx deleted file mode 100644 index 8e8de0e..0000000 --- a/src/app/dashboard/(active)/telegram/users/[id]/card-user-grant.tsx +++ /dev/null @@ -1,34 +0,0 @@ -"use client" -import { format } from "date-fns" -import { FiZap } from "react-icons/fi" -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card" -import type { TgGrant, TgUser } from "@/server/trpc/types" -import { DeleteGrant } from "../../grants/delete-grant" - -export function UserGrantCard({ - user, - grant, - //onDelete -}: { - user: TgUser - grant: TgGrant - //onDelete(): void -}) { - return ( - - - - Ongoing Grant - - This user has an ongoing grant - - -

Start: {format(grant.validSince, "yyyy/MM/dd HH:mm")}

-

End: {format(grant.validUntil, "yyyy/MM/dd HH:mm")}

-
- - - -
- ) -} diff --git a/src/app/dashboard/(active)/telegram/users/[id]/card-user-info.tsx b/src/app/dashboard/(active)/telegram/users/[id]/card-user-info.tsx deleted file mode 100644 index 8a44e6b..0000000 --- a/src/app/dashboard/(active)/telegram/users/[id]/card-user-info.tsx +++ /dev/null @@ -1,58 +0,0 @@ -"use client" -import { FiStar } from "react-icons/fi" -import { Badge } from "@/components/ui/badge" -import { Card, CardContent, CardFooter, CardHeader, CardTitle } from "@/components/ui/card" -import { useSession } from "@/lib/auth" -import type { ApiOutput } from "@/server/trpc/types" -import { AddRole } from "./add-role" -import { RemoveRole } from "./remove-role" - -type User = ApiOutput["tg"]["users"]["getByUsername"]["user"] -type UserRoles = ApiOutput["tg"]["permissions"]["getRoles"]["roles"] - -export function UserInfoCard({ - user, - roles, - // onUpdate, -}: { - user: NonNullable - roles: UserRoles - // onUpdate(): void -}) { - const sesh = useSession() - const seshUserId = sesh.data?.user.telegramId - const isSelf = seshUserId && seshUserId === user.id - - return ( - - - - # User ID: {user.id}{" "} - {isSelf && ( - - You - - )} - - - -

- Name: - {user.firstName} {user.lastName ?? ""} -

-

- Username: - {user.username} -

-
- Roles: - {roles ? roles.map((r) => {r}) : "N/A"} -
-
- - - - -
- ) -} diff --git a/src/app/dashboard/(active)/telegram/users/[id]/delete-group-admin.tsx b/src/app/dashboard/(active)/telegram/users/[id]/delete-group-admin.tsx deleted file mode 100644 index cfcd50b..0000000 --- a/src/app/dashboard/(active)/telegram/users/[id]/delete-group-admin.tsx +++ /dev/null @@ -1,88 +0,0 @@ -"use client" - -import { useRouter } from "next/navigation" -import { useState } from "react" -import { FiTrash2 } from "react-icons/fi" -import { toast } from "sonner" -import { Spinner } from "@/components/spinner" -import { - AlertDialog, - AlertDialogAction, - AlertDialogCancel, - AlertDialogContent, - AlertDialogDescription, - AlertDialogFooter, - AlertDialogHeader, - AlertDialogMedia, - AlertDialogTitle, - AlertDialogTrigger, -} from "@/components/ui/alert-dialog" -import { Button } from "@/components/ui/button" -import { delGroupAdmin } from "@/server/actions/users" - -export function DeleteGroupAdmin({ - userId, - chatId, - // onDelete -}: { - userId: number - chatId: number - // onDelete(): void -}) { - const [open, setOpen] = useState(false) - const [pending, setPending] = useState(false) - - const router = useRouter() - - async function deleteGroupAdmin() { - setPending(true) - - try { - const { error } = await delGroupAdmin(userId, chatId) - - if (error === "NOT_FOUND") toast.info("User or group admin not found") - else if (error === "UNAUTHORIZED") toast.error("You don't have enough permission") - else if (error === "INTERNAL_SERVER_ERROR") toast.error("There was an internal server error") - else if (error === "UNAUTHORIZED_SELF_ASSIGN") toast.error("You cannot delete on yourself") - else { - toast.success("Group Admin deleted!") - router.refresh() - // onDelete() - } - } catch (err) { - toast.error("There was an error") - console.error(err) - } finally { - setOpen(false) - setPending(false) - } - } - - return ( - - - - Delete - - } - > - - - - - - Remove Group Admin - Are you sure you want to remove the group admin? - - - Cancel - - {pending ? : "Confirm"} - - - - - ) -} diff --git a/src/app/dashboard/(active)/telegram/users/[id]/loading.tsx b/src/app/dashboard/(active)/telegram/users/[id]/loading.tsx deleted file mode 100644 index be3d0ae..0000000 --- a/src/app/dashboard/(active)/telegram/users/[id]/loading.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import { Skeleton } from "@/components/ui/skeleton" - -export default async function Loading() { - return ( -
-
- - -
- -
-

Admin in groups:

-
- - -
-
- -
-

Last messages (max 12):

-
- - -
-
- -
-

Audit log:

-
- {new Array(9).fill(0).map((_, i) => ( - - ))} -
-
-
- ) -} diff --git a/src/app/dashboard/(active)/telegram/users/[id]/new-group-admin.tsx b/src/app/dashboard/(active)/telegram/users/[id]/new-group-admin.tsx deleted file mode 100644 index fc7f5e5..0000000 --- a/src/app/dashboard/(active)/telegram/users/[id]/new-group-admin.tsx +++ /dev/null @@ -1,163 +0,0 @@ -"use client" -import { useRouter } from "next/navigation" -import { useState } from "react" -import { FiPlus, FiSearch, FiX } from "react-icons/fi" -import { toast } from "sonner" -import { Button } from "@/components/ui/button" -import { - Dialog, - DialogClose, - DialogContent, - DialogDescription, - DialogFooter, - DialogHeader, - DialogTitle, - DialogTrigger, -} from "@/components/ui/dialog" -import { Input } from "@/components/ui/input" -import { Label } from "@/components/ui/label" -import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger } from "@/components/ui/select" -import { searchGroup } from "@/server/actions/groups" -import { addGroupAdmin } from "@/server/actions/users" -import type { ApiOutput } from "@/server/trpc/types" - -type Groups = ApiOutput["tg"]["groups"]["search"]["groups"] -type User = ApiOutput["tg"]["users"]["getByUsername"]["user"] - -export function NewGroupAdmin({ - user, - alreadyIn, - // onConfirm -}: { - user: User - alreadyIn: number[] - // onConfirm(): void -}) { - const [open, setOpen] = useState(false) - const [groupQuery, setGroupQuery] = useState("") - const [groups, setGroups] = useState([]) - const [selectedGroup, setSelectedGroup] = useState(null) - - const router = useRouter() - - async function search() { - const { groups } = await searchGroup(groupQuery) - setGroups(groups.filter((g) => !alreadyIn.includes(g.telegramId))) - } - - async function submit() { - if (!selectedGroup) return toast.warning("No group selected, cannot proceed") - if (!user) return toast.warning("Invalid user, try restarting the dialog") - - try { - const { error } = await addGroupAdmin(user.id, selectedGroup.telegramId) - if (error) { - toast.error("You don't have enough permissions") - } else { - toast.info(`Group admin added`) - router.refresh() - // onConfirm() - } - } catch (err) { - console.error(err) - toast.error("There was an error, check logs") - } finally { - handleOpenChange(false) - } - } - - function reset() { - setGroups([]) - setGroupQuery("") - setSelectedGroup(null) - } - - function handleOpenChange(v: boolean) { - setOpen(v) - if (v === false) { - reset() - } - } - - return ( - - - New - - } - /> - - - New Group Admin - Make the user admin in a group. - - {user && ( -

- Target: {user.firstName} {user.username && `@${user.username}`} [{user.id}] -

- )} - -
-
- -
- 0} - required - onChange={(e) => { - setGroupQuery(e.target.value) - }} - value={groupQuery} - /> - -
- {groups.length > 0 && ( - - )} -
-
- - - {groups && ( - - )} - - Cancel} /> - - - -
- ) -} diff --git a/src/app/dashboard/(active)/telegram/users/[id]/page.tsx b/src/app/dashboard/(active)/telegram/users/[id]/page.tsx deleted file mode 100644 index ec6649e..0000000 --- a/src/app/dashboard/(active)/telegram/users/[id]/page.tsx +++ /dev/null @@ -1,83 +0,0 @@ -import { notFound } from "next/navigation" -import { Suspense } from "react" -import { getUserDetails } from "@/server/actions/users" -import { AuditLogCard } from "./card-audit-log" -import { GroupAdminCard } from "./card-group-admin" -import { MessageCard } from "./card-message" -import { UserGrantCard } from "./card-user-grant" -import { UserInfoCard } from "./card-user-info" -import { NewGroupAdmin } from "./new-group-admin" - -export default async function TgUserDetails({ params }: { params: Promise<{ id: string }> }) { - const { id } = await params - const parsedInt = Number(id) - if (!Number.isInteger(parsedInt) || !Number.isSafeInteger(parsedInt)) notFound() - const data = await getUserDetails(parsedInt) - - if (!data) notFound() - - return ( -
- {data && ( - <> -
- - {data.grant && } -
- -
-
-

Admin in groups:

- g?.group.id ?? 0) ?? []} /> -
- -
- {data.groupAdmin - .filter((m) => m !== null && m !== undefined) - .map((m) => ( - - ))} - - {data.groupAdmin.length === 0 && ( -

- This user is not group admin in any group. -

- )} -
-
- -
-

Last messages (max 15):

-
- {data.messages?.map((m) => ( - - ))} - - {data.messages?.length === 0 && ( -

- No recent messages sent by this user -

- )} -
-
- -
-

Audit log:

-
- {data.audits.map((m) => ( - - - - ))} - {data.audits.length === 0 && ( -

- No audit log found for this user -

- )} -
-
- - )} -
- ) -} diff --git a/src/app/dashboard/(active)/telegram/users/[id]/remove-role.tsx b/src/app/dashboard/(active)/telegram/users/[id]/remove-role.tsx deleted file mode 100644 index 261a6b4..0000000 --- a/src/app/dashboard/(active)/telegram/users/[id]/remove-role.tsx +++ /dev/null @@ -1,152 +0,0 @@ -"use client" -import { USER_ROLE } from "@polinetwork/backend" -import { useRouter } from "next/navigation" -import { useState } from "react" -import { FiMinus } from "react-icons/fi" -import { toast } from "sonner" -import { Spinner } from "@/components/spinner" -import { Badge } from "@/components/ui/badge" -import { Button } from "@/components/ui/button" -import { - Dialog, - DialogClose, - DialogContent, - DialogDescription, - DialogFooter, - DialogHeader, - DialogTitle, - DialogTrigger, -} from "@/components/ui/dialog" -import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select" -import { useSession } from "@/lib/auth" -import { delUserRole } from "@/server/actions/users" -import type { TgUser, TgUserRole } from "@/server/trpc/types" - -const ARRAY_USER_ROLES = [ - USER_ROLE.ADMIN, - USER_ROLE.HR, - USER_ROLE.OWNER, - USER_ROLE.CREATOR, - USER_ROLE.DIRETTIVO, - USER_ROLE.PRESIDENT, -] as const - -export function RemoveRole({ - user, - alreadyRoles, - // onDelete, -}: { - user: TgUser - alreadyRoles: TgUserRole[] - // onDelete(): void -}) { - const sesh = useSession() - const removerId = sesh.data?.user.telegramId - - const userRoles = ARRAY_USER_ROLES.filter((r) => alreadyRoles.includes(r)).map((g) => ({ - value: g, - label: `${g.slice(0, 1).toUpperCase()}${g.slice(1)}`, - })) - - const [open, setOpen] = useState(false) - const [pending, setPending] = useState(false) - const [selectedRole, setSelectedRole] = useState(null) - - const router = useRouter() - - async function submit() { - if (!removerId) return toast.warning("Invalid session, try reloading the page") - if (!selectedRole) return toast.warning("No group selected, cannot proceed") - if (!user) return toast.warning("Invalid user, try restarting the dialog") - setPending(true) - - try { - const { error } = await delUserRole(user.id, selectedRole) - - if (error === "NOT_FOUND") toast.info("User or role not found") - else if (error === "UNAUTHORIZED") toast.error("You don't have enough permission") - else if (error === "INTERNAL_SERVER_ERROR") toast.error("There was an internal server error") - else if (error === "UNAUTHORIZED_SELF_ASSIGN") toast.error("You cannot delete on yourself") - else { - toast.success("Role removed!") - router.refresh() - // onDelete() - } - } catch (err) { - console.error(err) - toast.error("There was an error, check logs") - } finally { - setPending(false) - handleOpenChange(false) - } - } - - function handleOpenChange(v: boolean) { - setOpen(v) - if (v === false) { - setSelectedRole(null) - } - } - - return ( - - - Remove Role - - } - /> - - - Remove Role - Remove a role from the telegram user - - {user && ( -

- Target: {user.firstName} {user.username && `@${user.username}`} [{user.id}] -

- )} -
- User roles: - {alreadyRoles.map((r) => ( - {r} - ))} -
- - - - - - Cancel - - } - /> - - -
-
- ) -} diff --git a/src/app/dashboard/(active)/telegram/users/loading.tsx b/src/app/dashboard/(active)/telegram/users/loading.tsx deleted file mode 100644 index e289840..0000000 --- a/src/app/dashboard/(active)/telegram/users/loading.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import { SearchInput } from "@/components/search-input" -import { Skeleton } from "@/components/ui/skeleton" - -export default async function Loading() { - return ( -
- -
-

Count:

- -
-
-
-

Telegram ID

-

Username

-

Name

-

Actions

-
- {new Array(12).fill(0).map((_, i) => ( - - ))} -
-
- ) -} diff --git a/src/app/dashboard/(active)/telegram/users/page.tsx b/src/app/dashboard/(active)/telegram/users/page.tsx deleted file mode 100644 index 79d7a71..0000000 --- a/src/app/dashboard/(active)/telegram/users/page.tsx +++ /dev/null @@ -1,56 +0,0 @@ -import Link from "next/link" -import { FiEye } from "react-icons/fi" -import { SearchInput } from "@/components/search-input" -import { Button } from "@/components/ui/button" -import { trpc } from "@/server/trpc" -import type { ApiOutput } from "@/server/trpc/types" - -type Users = NonNullable - -export default async function TgUsers({ searchParams }: { searchParams: Promise<{ q?: string }> }) { - const { q } = await searchParams - const { users } = await trpc.tg.users.getAll.query() - - const data = (!q ? users : users?.filter((u) => u.username?.toLowerCase().replace("@", "").startsWith(q))) ?? [] - - return ( -
- -

- Count: {users?.length} -

-
-
-

Telegram ID

-

Username

-

Name

-

Actions

-
- {data.length > 0 ? ( - data.map((r) => ) - ) : ( -
No users found
- )} -
-
- ) -} - -function UserRow({ row: r }: { row: Users[number] }) { - return ( -
-

{r.id}

-

{r.username ? `@${r.username}` : ``}

-

- {r.firstName ?? ""} {r.lastName ?? ""} -

-
- - - -
-
- ) -} diff --git a/src/app/dashboard/(active)/web/guide/columns.tsx b/src/app/dashboard/(active)/web/guide/columns.tsx deleted file mode 100644 index 3e3ba00..0000000 --- a/src/app/dashboard/(active)/web/guide/columns.tsx +++ /dev/null @@ -1,35 +0,0 @@ -"use client" -import { createColumnHelper } from "@tanstack/react-table" -import { format } from "date-fns" -import { DeleteGuide } from "./delete-guide" -import type { Guide } from "./types" - -const ch = createColumnHelper() - -export const columns = (onDeleted: (id: number) => void) => [ - ch.accessor("version", { - id: "version", - header: "Version", - cell: ({ getValue }) => {getValue()}, - }), - ch.accessor("date", { - id: "date", - header: "Date", - cell: ({ getValue }) => format(new Date(getValue()), "dd/MM/yyyy"), - }), - ch.accessor("file", { - id: "file", - header: "File", - cell: ({ getValue }) => ( - - Download - - ), - }), - ch.group({ - id: "actions", - cell: (props) => ( - - ), - }), -] diff --git a/src/app/dashboard/(active)/web/guide/create-guide.tsx b/src/app/dashboard/(active)/web/guide/create-guide.tsx deleted file mode 100644 index 5845298..0000000 --- a/src/app/dashboard/(active)/web/guide/create-guide.tsx +++ /dev/null @@ -1,169 +0,0 @@ -"use client" - -import { format } from "date-fns" -import { useState } from "react" -import { FiChevronDown, FiPlus, FiUpload } from "react-icons/fi" -import { toast } from "sonner" -import { Button } from "@/components/ui/button" -import { Calendar } from "@/components/ui/calendar" -import { - Dialog, - DialogClose, - DialogContent, - DialogDescription, - DialogFooter, - DialogHeader, - DialogTitle, - DialogTrigger, -} from "@/components/ui/dialog" -import { Field, FieldLabel } from "@/components/ui/field" -import { Input } from "@/components/ui/input" -import { Label } from "@/components/ui/label" -import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover" -import { createGuide } from "@/server/actions/guides" -import type { Guide } from "./types" - -export function CreateGuide({ - existingVersions, - latestVersion, - onCreated, -}: { - existingVersions: string[] - latestVersion?: string - onCreated: (guide: Guide) => void -}) { - const [open, setOpen] = useState(false) - const [version, setVersion] = useState(latestVersion ?? "") - const [date, setDate] = useState(new Date()) - const [datePickerOpen, setDatePickerOpen] = useState(false) - const [file, setFile] = useState(null) - const [pending, setPending] = useState(false) - - const trimmedVersion = version.trim() - const isDuplicate = trimmedVersion.length > 0 && existingVersions.includes(trimmedVersion) - const disabled = !trimmedVersion || !date || !file || isDuplicate || pending - - function handleOpenChange(v: boolean) { - setOpen(v) - if (v) { - setVersion(latestVersion ?? "") - setDate(new Date()) - setFile(null) - } - } - - async function handleSubmit() { - if (!date || !file || isDuplicate) return - setPending(true) - - try { - const formData = new FormData() - formData.set("version", trimmedVersion) - formData.set("date", date.toISOString()) - formData.set("file", file) - const { guide, error } = await createGuide(formData) - - if (error === "UNAUTHORIZED") toast.error("You don't have permission to add guides.") - else if (error === "DUPLICATE_VERSION") toast.error("This version already exists.") - else if (!guide) toast.error("There was an error creating the guide.") - else { - toast.success("Guide created successfully") - onCreated(guide) - handleOpenChange(false) - } - } catch (err) { - toast.error("There was an error") - console.error(err) - } finally { - setPending(false) - } - } - - return ( - - - Add Guide - - } - /> - - - Add Guide - Upload a new version of the Guida della Matricola. - - -
-
- - setVersion(e.target.value)} - /> - {isDuplicate &&

This version already exists.

} -
- - - Date - - - {date ? format(date, "dd/MM/yyyy") : "Select date"} - - - } - /> - - { - setDate(d) - setDatePickerOpen(false) - }} - /> - - - - -
- - - setFile(e.target.files?.[0] ?? null)} - className="sr-only" - /> -
-
- - - Cancel} /> - - -
-
- ) -} diff --git a/src/app/dashboard/(active)/web/guide/delete-guide.tsx b/src/app/dashboard/(active)/web/guide/delete-guide.tsx deleted file mode 100644 index 9597629..0000000 --- a/src/app/dashboard/(active)/web/guide/delete-guide.tsx +++ /dev/null @@ -1,79 +0,0 @@ -"use client" - -import { useState } from "react" -import { FiAlertOctagon, FiTrash } from "react-icons/fi" -import { toast } from "sonner" -import { - AlertDialog, - AlertDialogAction, - AlertDialogCancel, - AlertDialogContent, - AlertDialogDescription, - AlertDialogFooter, - AlertDialogHeader, - AlertDialogMedia, - AlertDialogTitle, - AlertDialogTrigger, -} from "@/components/ui/alert-dialog" -import { Button } from "@/components/ui/button" -import { deleteGuide } from "@/server/actions/guides" - -export function DeleteGuide({ - id, - version, - onDeleted, -}: { - id: number - version: string - onDeleted: (id: number) => void -}) { - const [open, setOpen] = useState(false) - - async function handleDelete() { - try { - const { error } = await deleteGuide(id) - - if (error === "UNAUTHORIZED") toast.error("You don't have permission to delete guides.") - else if (error === "NOT_FOUND") toast.info("This guide was already deleted.") - else { - toast.success("Guide deleted successfully") - onDeleted(id) - } - } catch (err) { - toast.error("There was an error") - console.error(err) - } finally { - setOpen(false) - } - } - - return ( - - - - - } - /> - - - - - - Delete Guide - - Are you sure you want to delete version {version}?
- This action cannot be undone. -
-
- - Cancel - - Confirm - - -
-
- ) -} diff --git a/src/app/dashboard/(active)/web/guide/page.tsx b/src/app/dashboard/(active)/web/guide/page.tsx deleted file mode 100644 index 8746554..0000000 --- a/src/app/dashboard/(active)/web/guide/page.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import { getAllGuides } from "@/server/actions/guides" -import { GuideTable } from "./table" - -export default async function GuideMatricolaPage() { - const guides = await getAllGuides() - - return ( -
- -
- ) -} diff --git a/src/app/dashboard/(active)/web/guide/table.tsx b/src/app/dashboard/(active)/web/guide/table.tsx deleted file mode 100644 index 860b9cc..0000000 --- a/src/app/dashboard/(active)/web/guide/table.tsx +++ /dev/null @@ -1,39 +0,0 @@ -"use client" - -import { useRouter } from "next/navigation" -import { useState } from "react" -import { DataTable } from "@/components/data-table" -import { columns } from "./columns" -import { CreateGuide } from "./create-guide" -import type { Guide } from "./types" - -export function GuideTable({ guides }: { guides: Guide[] }) { - const router = useRouter() - const [items, setItems] = useState(guides) - - function handleCreated(guide: Guide) { - setItems((prev) => [guide, ...prev]) - router.refresh() - } - - function handleDeleted(id: number) { - setItems((prev) => prev.filter((g) => g.id !== id)) - router.refresh() - } - - return ( -
-
-

Guida della Matricola

-
- g.version)} - latestVersion={items[0]?.version} - onCreated={handleCreated} - /> -
- - -
- ) -} diff --git a/src/app/dashboard/(active)/web/guide/types.ts b/src/app/dashboard/(active)/web/guide/types.ts deleted file mode 100644 index fdc74b2..0000000 --- a/src/app/dashboard/(active)/web/guide/types.ts +++ /dev/null @@ -1,6 +0,0 @@ -export type Guide = { - id: number - version: string - date: string - file: string -} diff --git a/src/app/dashboard/disabled/page.tsx b/src/app/dashboard/disabled/page.tsx deleted file mode 100644 index b0c7cba..0000000 --- a/src/app/dashboard/disabled/page.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import Image from "next/image" -import { redirect } from "next/navigation" -import accountSvg from "@/assets/svg/account_disabled.svg" -import { LogoutButton } from "@/components/logout-button" -import { getServerSession } from "@/server/auth" -// import { USER_ROLE } from "@/constants"; - -export default async function AdminInactive() { - const { data: session } = await getServerSession() - // if (session?.user.role !== USER_ROLE.DISABLED) redirect("/dashboard"); - // TODO - if (!session) return redirect("/login") - - return ( - session && ( -
-
- illustration of disabled account -

- Il tuo account è stato disabilitato -
-

-

- Il tuo account è stato disabilitato in quanto non sei un membro riconosciuto di PoliNetwork. -

-

Se credi che sia un errore, manda una richiesta di rivalutazione.

-
- -
-

- {session.user.name} - {` <${session.user.email}>`} -

{" "} - -
-
- ) - ) -} diff --git a/src/app/dashboard/inactive/logout.tsx b/src/app/dashboard/inactive/logout.tsx deleted file mode 100644 index e69de29..0000000 diff --git a/src/app/dashboard/inactive/page.tsx b/src/app/dashboard/inactive/page.tsx deleted file mode 100644 index 9b36247..0000000 --- a/src/app/dashboard/inactive/page.tsx +++ /dev/null @@ -1,53 +0,0 @@ -import Image from "next/image" -import { redirect } from "next/navigation" -import accountSvg from "@/assets/svg/account_inactive.svg" -import { LogoutButton } from "@/components/logout-button" -import { getServerSession } from "@/server/auth" -// import { USER_ROLE } from "@/constants"; - -export default async function AdminInactive() { - const { data: session } = await getServerSession() - if (!session) return redirect("/login") - // if (session?.user.role !== USER_ROLE.INACTIVE) redirect("/dashboard"); - // TODO - - return ( - session && ( -
-
- illustration of account management -

- Il tuo account deve
- essere abilitato da un dashboard IT -

-

- Per accedere con GitHub, è necessario che l'account venga abilitato da un dashboard IT, in quanto si - tratta di una dashboard interna di PoliNetwork. -

-

- Se sei già un socio di PoliNetwork, puoi accedere direttamente con il tuo indirizzo - nome.cognome@polinetwork.org tramite "Microsoft Entra ID" e il tuo account sarà automaticamente - verificato. -

-

- Se sei entrato con il tuo indirizzo nome.cognome@polinetwork.org e il tuo account risulta inattivo, potrebbe - essere stato disabilitato. Contatta un dashboard IT per ottenere più informazioni. -

-
- -
-

- {session.user.name} - {` <${session.user.email}>`} -

{" "} - -
-
- ) - ) -} diff --git a/src/app/dashboard/layout.tsx b/src/app/dashboard/layout.tsx deleted file mode 100644 index 54aee61..0000000 --- a/src/app/dashboard/layout.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import { redirect } from "next/navigation" -import { getServerSession } from "@/server/auth" -import { trpc } from "@/server/trpc" - -export default async function AdminLayout({ children }: { children: React.ReactNode }) { - const session = await getServerSession() - // console.log(session) - if (!session.data) redirect("/login") - - const tgId = session.data.user.telegramId - if (!tgId) redirect("/onboarding/link") - // if (session?.user.role === USER_ROLE.INACTIVE) ; - // if (session?.user.role === USER_ROLE.DISABLED) redirect("/dashboard/disabled"); - - const { roles } = await trpc.tg.permissions.getRoles.query({ userId: tgId }) - if (!roles || roles.length === 0) redirect("/onboarding/no-role") - if (roles.includes("creator")) redirect("/onboarding/unauthorized") - - // temp until we have route-based permissions check - if (!roles.includes("owner") && !roles.includes("direttivo") && !roles.includes("president")) - redirect("/onboarding/unauthorized") - - return children -} diff --git a/src/app/layout.tsx b/src/app/layout.tsx deleted file mode 100644 index 02c7f72..0000000 --- a/src/app/layout.tsx +++ /dev/null @@ -1,53 +0,0 @@ -import type { Metadata } from "next" -import { Geist, Poppins } from "next/font/google" -import "@/index.css" -import { HEADER_HEIGHT } from "@/components/header" -import { ThemeProvider } from "@/components/theme-provider" -import { Toaster } from "@/components/ui/sonner" -import { TooltipProvider } from "@/components/ui/tooltip" -import { cn } from "@/lib/utils/shadcn" - -const geist = Geist({ subsets: ["latin"], variable: "--font-sans" }) - -const desc = "PoliNetwork Admin Dashboard" - -export const metadata: Metadata = { - title: { - default: "PoliNetwork Admin", - template: "%s | PoliNetwork Admin", - }, - description: desc, - icons: [{ rel: "icon", url: "/favicon.ico" }], -} - -const poppins = Poppins({ weight: ["100", "200", "300", "400", "500", "600", "700", "800", "900"], subsets: ["latin"] }) - -export default function RootLayout({ children }: Readonly<{ children: React.ReactNode }>) { - return ( - - - - -
{children}
- -
-
- - - ) -} diff --git a/src/app/page.tsx b/src/app/page.tsx deleted file mode 100644 index a658b62..0000000 --- a/src/app/page.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import { redirect } from "next/navigation" -import { Header } from "@/components/header" -import { getServerSession } from "@/server/auth" -import { CanIAccess } from "./(auth)/login/can-i-access" -import { WhatIs } from "./(auth)/login/what-is" - -export default async function IndexPage() { - const session = await getServerSession() - if (session.data?.user) redirect("/dashboard") - - return ( -
-
-
- - -
-
- ) -} diff --git a/src/app/testtrpc/page.tsx b/src/app/testtrpc/page.tsx deleted file mode 100644 index 7e284b7..0000000 --- a/src/app/testtrpc/page.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import { testDb } from "@/server/actions/test" -export const dynamic = "force-dynamic" - -export default async function TestTRPCPage() { - const data = await testDb() - - return ( -
-

Test with tRPC. Get the table `test.tg`

-
    - {data.map((r, i) => ( -
  1. - {r} -
  2. - ))} -
-
- ) -} diff --git a/src/assets/logo.svg b/src/assets/logo.svg deleted file mode 100644 index 1b0d8fc..0000000 --- a/src/assets/logo.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/src/assets/svg/account_disabled.svg b/src/assets/svg/account_disabled.svg deleted file mode 100644 index e671b24..0000000 --- a/src/assets/svg/account_disabled.svg +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/assets/svg/account_inactive.svg b/src/assets/svg/account_inactive.svg deleted file mode 100644 index 4df3d97..0000000 --- a/src/assets/svg/account_inactive.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/assets/svg/login-1.svg b/src/assets/svg/login-1.svg deleted file mode 100644 index 47c1c18..0000000 --- a/src/assets/svg/login-1.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/assets/svg/login-2.svg b/src/assets/svg/login-2.svg deleted file mode 100644 index 4be8d70..0000000 --- a/src/assets/svg/login-2.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/assets/svg/login-3.svg b/src/assets/svg/login-3.svg deleted file mode 100644 index f2e900e..0000000 --- a/src/assets/svg/login-3.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/assets/svg/logo.svg b/src/assets/svg/logo.svg deleted file mode 100644 index fe4f0fb..0000000 --- a/src/assets/svg/logo.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/assets/svg/shapes/big-blue.svg b/src/assets/svg/shapes/big-blue.svg deleted file mode 100644 index 354ec86..0000000 --- a/src/assets/svg/shapes/big-blue.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/assets/svg/shapes/big-teal.svg b/src/assets/svg/shapes/big-teal.svg deleted file mode 100644 index ffce061..0000000 --- a/src/assets/svg/shapes/big-teal.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/assets/svg/shapes/looper.svg b/src/assets/svg/shapes/looper.svg deleted file mode 100644 index 9b118d2..0000000 --- a/src/assets/svg/shapes/looper.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/assets/svg/shapes/small-blue.svg b/src/assets/svg/shapes/small-blue.svg deleted file mode 100644 index feedfff..0000000 --- a/src/assets/svg/shapes/small-blue.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/components/app-mark.tsx b/src/components/app-mark.tsx new file mode 100644 index 0000000..62302ea --- /dev/null +++ b/src/components/app-mark.tsx @@ -0,0 +1,44 @@ +import { Link } from "@tanstack/react-router" +import logoUrl from "@/assets/logo.png" +import { cn } from "@/lib/utils" + +export function AppMark({ + compact = false, + sidebarResponsive = false, + className, + onClick, +}: { + compact?: boolean + sidebarResponsive?: boolean + className?: string + onClick?: React.MouseEventHandler +}) { + return ( + + + {!compact && ( + + PoliNetwork + + Admin dashboard + + + )} + + ) +} diff --git a/src/components/code.tsx b/src/components/code.tsx deleted file mode 100644 index b0a60f8..0000000 --- a/src/components/code.tsx +++ /dev/null @@ -1,77 +0,0 @@ -"use client" - -import { type MouseEvent, type ReactNode, useCallback, useRef } from "react" -import { toast } from "sonner" -import { cn } from "@/lib/utils/shadcn" - -type Props = React.HTMLAttributes & { - block?: boolean - copyOnClick?: boolean - children: ReactNode -} - -export function Code({ block = false, copyOnClick = false, children, className, ...rest }: Props) { - const ref = useRef(null) - - const copy = useCallback(async (e: MouseEvent) => { - e.preventDefault() - try { - if (!ref.current) return - await navigator.clipboard.writeText(ref.current.innerText) - toast.success("Copied to clipboard") - } catch (err) { - console.error("Failed to copy code:", err) - toast.error("Failed to copy code") - } - }, []) - - const InteractiveWrapper = copyOnClick - ? ({ children: content }: { children: ReactNode }) => ( - - ) - : ({ children: content }: { children: ReactNode }) => <>{content} - - if (block) { - return ( - -
-          
-            {children}
-          
-        
-
- ) - } - - return ( - - - {children} - - - ) -} diff --git a/src/components/dashboard-breadcrumb.tsx b/src/components/dashboard-breadcrumb.tsx new file mode 100644 index 0000000..9c3f13e --- /dev/null +++ b/src/components/dashboard-breadcrumb.tsx @@ -0,0 +1,78 @@ +import { Link, useRouterState } from "@tanstack/react-router" +import { Fragment, useMemo } from "react" +import { + Breadcrumb, + BreadcrumbItem, + BreadcrumbLink, + BreadcrumbList, + BreadcrumbPage, + BreadcrumbSeparator, +} from "@/components/ui/breadcrumb" +import { DASHBOARD_NAV_MAP, type DashboardPath, isDashboardPath } from "./dashboard-navigation" + +type DashboardBreadcrumbItem = { + title: string + url?: DashboardPath +} + +export function DashboardBreadcrumb({ className, ...props }: React.ComponentProps<"nav">) { + const pathname = useRouterState({ select: (state) => state.location.pathname }) + const items = useMemo(() => getBreadcrumbs(pathname), [pathname]) + + return ( + + + {items.map((item, index) => { + const current = index === items.length - 1 + + return ( + + + {current ? ( + {item.title} + ) : item.url ? ( + }>{item.title} + ) : ( + {item.title} + )} + + {!current && } + + ) + })} + + + ) +} + +function getBreadcrumbs(pathname: string): DashboardBreadcrumbItem[] { + const segments = pathname.split("/").filter(Boolean) + const breadcrumbs: DashboardBreadcrumbItem[] = [] + let currentPath = "" + + for (const [index, segment] of segments.entries()) { + currentPath += `/${segment}` + const mappedTitle = isDashboardPath(currentPath) ? DASHBOARD_NAV_MAP.get(currentPath) : undefined + const title = mappedTitle ?? (isIdentifier(segment) ? "Details" : formatSegment(segment)) + + breadcrumbs.push({ + title, + // Service categories are organizational labels rather than destinations. + url: index !== 1 && isDashboardPath(currentPath) ? currentPath : undefined, + }) + } + + return breadcrumbs +} + +function formatSegment(segment: string) { + return segment + .split("-") + .filter(Boolean) + .map((part) => part.charAt(0).toUpperCase() + part.slice(1)) + .join(" ") +} + +function isIdentifier(segment: string) { + return /^\d+$/.test(segment) || segment.length > 20 +} diff --git a/src/components/dashboard-frame.tsx b/src/components/dashboard-frame.tsx new file mode 100644 index 0000000..a39941f --- /dev/null +++ b/src/components/dashboard-frame.tsx @@ -0,0 +1,61 @@ +import { Outlet, useRouter } from "@tanstack/react-router" +import { useEffect, useState } from "react" +import { toast } from "sonner" +import { DashboardBreadcrumb } from "@/components/dashboard-breadcrumb" +import { DashboardSidebar } from "@/components/dashboard-sidebar" +import { SidebarInset, SidebarProvider, SidebarTrigger } from "@/components/ui/sidebar" +import type { AdminSession } from "@/lib/auth" +import { auth, useSession } from "@/lib/auth" +import { ThemeToggle } from "./theme-toggle" + +export function DashboardFrame({ initialSession }: { initialSession: AdminSession }) { + const [sidebarOpen, setSidebarOpen] = useState(true) + const [loggingOut, setLoggingOut] = useState(false) + const router = useRouter() + const sessionQuery = useSession() + const liveSession = sessionQuery.data + const session = liveSession === undefined ? initialSession : liveSession + const user = session?.user + + useEffect(() => { + const storedState = document.cookie + .split("; ") + .find((cookie) => cookie.startsWith("sidebar_state=")) + ?.split("=")[1] + if (storedState === "false") setSidebarOpen(false) + }, []) + + async function logout() { + if (loggingOut) return + setLoggingOut(true) + try { + const result = await auth.signOut() + if (result.error) throw new Error(result.error.message) + await router.invalidate() + await router.navigate({ to: "/login", replace: true }) + } catch { + toast.error("Could not sign out. Please try again.") + setLoggingOut(false) + } + } + + return ( + + void logout()} /> + +
+ + + +
+
+ +
+
+
+ ) +} diff --git a/src/components/dashboard-navigation.ts b/src/components/dashboard-navigation.ts new file mode 100644 index 0000000..428c2ae --- /dev/null +++ b/src/components/dashboard-navigation.ts @@ -0,0 +1,84 @@ +import { + BookOpen, + Database, + Globe, + LayoutDashboard, + type LucideIcon, + Settings, + ShieldCheck, + UsersRound, +} from "lucide-react" +import azureIcon from "@/assets/svg/azure.svg" +import telegramIcon from "@/assets/svg/telegram.svg" + +export type DashboardNavigationItem = { + title: string + url: string + icon: LucideIcon +} + +export type DashboardNavigationCategory = { + title: string + icon: LucideIcon + iconSrc?: string + items: readonly DashboardNavigationItem[] +} + +export const overviewNavigation = { + title: "Overview", + url: "/dashboard", + icon: LayoutDashboard, +} as const satisfies DashboardNavigationItem + +export const dashboardNavigation = [ + { + title: "Telegram", + icon: UsersRound, + iconSrc: telegramIcon, + items: [ + { title: "Users", url: "/dashboard/telegram/users", icon: UsersRound }, + { title: "Groups", url: "/dashboard/telegram/groups", icon: Database }, + { title: "Grants", url: "/dashboard/telegram/grants", icon: ShieldCheck }, + ], + }, + { + title: "Azure", + icon: UsersRound, + iconSrc: azureIcon, + items: [ + { title: "Groups", url: "/dashboard/azure/groups", icon: Database }, + { title: "Members", url: "/dashboard/azure/members", icon: UsersRound }, + ], + }, + { + title: "Web", + icon: Globe, + iconSrc: undefined, + items: [{ title: "Guides", url: "/dashboard/web/guides", icon: BookOpen }], + }, +] as const satisfies readonly DashboardNavigationCategory[] + +export const accountNavigation = { + title: "Account", + url: "/dashboard/account", + icon: Settings, +} as const satisfies DashboardNavigationItem + +type CategoryNavigationItem = (typeof dashboardNavigation)[number]["items"][number] + +export type DashboardPath = typeof overviewNavigation.url | CategoryNavigationItem["url"] | typeof accountNavigation.url + +const navigationEntries: [DashboardPath, string][] = [ + [overviewNavigation.url, overviewNavigation.title], + [accountNavigation.url, accountNavigation.title], +] + +for (const category of dashboardNavigation) { + for (const item of category.items) navigationEntries.push([item.url, item.title]) +} + +export const DASHBOARD_NAV_MAP = new Map(navigationEntries) + +export function isDashboardPath(path: string): path is DashboardPath { + return DASHBOARD_NAV_MAP.has(path as DashboardPath) +} diff --git a/src/components/dashboard-sidebar.tsx b/src/components/dashboard-sidebar.tsx new file mode 100644 index 0000000..4173632 --- /dev/null +++ b/src/components/dashboard-sidebar.tsx @@ -0,0 +1,264 @@ +import { Link, useRouterState } from "@tanstack/react-router" +import { ChevronRight, LogOut } from "lucide-react" +import { useEffect, useState } from "react" +import type { AdminSession } from "@/lib/auth" +import { cn } from "@/lib/utils" +import { AppMark } from "./app-mark" +import { accountNavigation, dashboardNavigation, overviewNavigation } from "./dashboard-navigation" +import { Avatar, AvatarFallback, AvatarImage } from "./ui/avatar" +import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "./ui/collapsible" +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuGroup, + DropdownMenuItem, + DropdownMenuTrigger, +} from "./ui/dropdown-menu" +import { + Sidebar, + SidebarContent, + SidebarFooter, + SidebarGroup, + SidebarHeader, + SidebarMenu, + SidebarMenuButton, + SidebarMenuItem, + SidebarMenuSub, + SidebarMenuSubButton, + SidebarMenuSubItem, + SidebarRail, + useSidebar, +} from "./ui/sidebar" + +const categoryStorageKey = "polinetwork-sidebar-categories" + +// Shared height and visual treatment for every primary nav row. +const navItemClass = "h-10 gap-2.5 rounded-lg px-2.5" + +// The single strong "selected page" treatment: a controlled PoliNetwork-blue surface. +const selectedPageClass = + "data-active:bg-sidebar-primary/15 data-active:font-medium data-active:text-sidebar-accent-foreground data-active:hover:bg-sidebar-primary/20" + +type DashboardSidebarProps = React.ComponentProps & { + user: AdminSession["user"] | undefined + loggingOut: boolean + onLogout: () => void +} + +export function DashboardSidebar({ user, loggingOut, onLogout, ...props }: DashboardSidebarProps) { + const pathname = useRouterState({ + select: (state) => state.location.pathname, + }) + const { setOpenMobile } = useSidebar() + const [categoryState, setCategoryState] = useState>({}) + + useEffect(() => { + try { + const stored = window.localStorage.getItem(categoryStorageKey) + if (stored) setCategoryState(JSON.parse(stored)) + } catch { + // Ignore malformed or unavailable local storage and use route-based defaults. + } + }, []) + + function persistCategory(title: string, open: boolean) { + setCategoryState((current) => { + const next = { ...current, [title]: open } + try { + window.localStorage.setItem(categoryStorageKey, JSON.stringify(next)) + } catch { + // The in-memory state still works when storage is unavailable. + } + return next + }) + } + + const accountActive = isPathActive(pathname, accountNavigation.url) + + return ( + + + setOpenMobile(false)} className="min-w-0" /> + + + + + + + setOpenMobile(false)} />} + className={cn(navItemClass, selectedPageClass)} + > + + {overviewNavigation.title} + + + + {dashboardNavigation.map((category) => { + const itemActiveStates = category.items.map((item) => isPathActive(pathname, item.url)) + const routeIsActive = itemActiveStates.some(Boolean) + const open = categoryState[category.title] ?? routeIsActive + const connectorHeight = category.items.length * 38 + 2 + const itemCenters = category.items.map((_, index) => 20 + index * 38) + const lastItemIndex = category.items.length - 1 + const lastItemCenter = itemCenters[lastItemIndex] + const inactiveBranches = itemCenters + .map((center, index) => + !itemActiveStates[index] && index !== lastItemIndex ? `M 0 ${center} H 10` : "" + ) + .filter(Boolean) + .join(" ") + const railPath = [ + `M 0 2 V ${lastItemCenter}`, + !itemActiveStates[lastItemIndex] ? "H 10" : "", + inactiveBranches, + ] + .filter(Boolean) + .join(" ") + + return ( + persistCategory(category.title, nextOpen)} + className="group/collapsible" + > + + } + className={cn( + navItemClass, + "text-sidebar-foreground/80", + routeIsActive && "bg-sidebar-accent/40 text-sidebar-accent-foreground" + )} + > + {category.iconSrc ? ( + + ) : ( + + )} + {category.title} + + + + + + {category.items.map((item, index) => { + const itemIsActive = itemActiveStates[index] + + return ( + + setOpenMobile(false)} />} + className={cn( + "h-9 gap-2.5 rounded-lg pl-2.5 text-sidebar-foreground/70", + "data-active:bg-sidebar-primary/15 data-active:font-medium data-active:text-sidebar-accent-foreground data-active:hover:bg-sidebar-primary/20", + "[&>svg]:text-sidebar-foreground/50 data-active:[&>svg]:text-sidebar-primary" + )} + > + + {item.title} + + + ) + })} + + + + + ) + })} + + + + + + + + + + } + > + + {user?.image && } + + {initials(user?.name, user?.email)} + + + + {user?.name || "PoliNetwork member"} + + + + + setOpenMobile(false)} />} + className="h-10 gap-2.5 px-2.5 py-0" + > + + Settings + + + + {loggingOut ? "Signing out…" : "Sign out"} + + + + + + + + + + ) +} + +function initials(name?: string | null, email?: string) { + const source = name?.trim() || email?.split("@")[0] || "User" + return source + .split(/[\s._-]+/) + .slice(0, 2) + .map((part) => part[0]?.toUpperCase()) + .join("") +} + +function isPathActive(pathname: string, url: string, exact = false) { + const normalizedPathname = pathname.length > 1 ? pathname.replace(/\/+$/, "") : pathname + const normalizedUrl = url.length > 1 ? url.replace(/\/+$/, "") : url + + return normalizedPathname === normalizedUrl || (!exact && normalizedPathname.startsWith(`${normalizedUrl}/`)) +} diff --git a/src/components/dashboard-sidebar/data.tsx b/src/components/dashboard-sidebar/data.tsx deleted file mode 100644 index 0fa52ae..0000000 --- a/src/components/dashboard-sidebar/data.tsx +++ /dev/null @@ -1,49 +0,0 @@ -import Image from "next/image" -import { FiBookOpen, FiGlobe, FiMessageSquare, FiUsers, FiZap } from "react-icons/fi" -import azureSvg from "@/assets/svg/azure.svg" -import telegramSvg from "@/assets/svg/telegram.svg" - -export const DSData = { - mainNav: [ - { - title: "Telegram", - icon: telegram logo, - items: [ - { title: "Grants", url: "/dashboard/telegram/grants", icon: }, - { title: "Groups", url: "/dashboard/telegram/groups", icon: }, - { title: "Users", url: "/dashboard/telegram/users", icon: }, - ], - }, - { - title: "Azure", - icon: azure logo, - items: [ - { title: "Groups", url: "/dashboard/azure/groups", icon: }, - { title: "Members", url: "/dashboard/azure/members", icon: }, - ], - }, - { - title: "Web", - icon: , - items: [{ title: "Guide", url: "/dashboard/web/guide", icon: }], - }, - ], -} - -const flattenNavigation = (): Map => { - const map = new Map() - const traverse = (list: { title: string; url?: string }[]) => { - for (const item of list) { - if (!item.url) continue - map.set(item.url, item.title) - } - } - Object.entries(DSData).forEach(([_k, nav]) => { - nav.forEach((category) => { - traverse(category.items) - }) - }) - return map -} - -export const NAV_MAP = flattenNavigation() diff --git a/src/components/dashboard-sidebar/index.tsx b/src/components/dashboard-sidebar/index.tsx deleted file mode 100644 index 4fb0080..0000000 --- a/src/components/dashboard-sidebar/index.tsx +++ /dev/null @@ -1,45 +0,0 @@ -"use client" - -import Link from "next/link" -import type * as React from "react" -import { - Sidebar, - SidebarContent, - SidebarFooter, - SidebarHeader, - SidebarMenu, - SidebarMenuButton, - SidebarMenuItem, -} from "@/components/ui/sidebar" -import { Logo } from "../logo" -import { DSMainNav } from "./main-nav" -import { DSUserNav } from "./user-nav" - -export function DashboardSidebar({ - categoryState, - ...props -}: React.ComponentProps & { categoryState: Record }) { - return ( - - - - - }> - -
- PoliNetwork APS - Admin Dashboard -
-
-
-
-
- - - - - - -
- ) -} diff --git a/src/components/dashboard-sidebar/main-nav.tsx b/src/components/dashboard-sidebar/main-nav.tsx deleted file mode 100644 index b61f719..0000000 --- a/src/components/dashboard-sidebar/main-nav.tsx +++ /dev/null @@ -1,103 +0,0 @@ -"use client" -import Link from "next/link" -import { usePathname } from "next/navigation" -import { useState } from "react" -import { FiChevronRight } from "react-icons/fi" -import { COOKIES } from "@/constants" -import { useCookieStorage } from "@/hooks/use-cookie-storage" -import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "../ui/collapsible" -import { - SidebarGroup, - SidebarMenu, - SidebarMenuButton, - SidebarMenuItem, - SidebarMenuSub, - SidebarMenuSubButton, - SidebarMenuSubItem, -} from "../ui/sidebar" -import { DSData } from "./data" - -export function DSMainNav({ categoryState }: { categoryState: Record }) { - const [_, setCategoryState] = useCookieStorage>( - COOKIES.SIDEBAR_CATEGORY_STATE, - {}, - { expires: 60 * 60 * 24 * 7 } - ) - - return ( - - - {DSData.mainNav.map((category) => ( - { - setCategoryState((state) => ({ ...state, [category.title]: open })) - }} - /> - ))} - - - ) -} - -function DSMenuCategory({ - category, - initialOpen, - onPersistOpen, -}: { - category: (typeof DSData)["mainNav"][0] - initialOpen?: boolean - onPersistOpen: (open: boolean) => void -}) { - const pathname = usePathname() - const categoryUrl = category.items[0]?.url.split("/").slice(0, 3).join("/") - const [open, setOpen] = useState(initialOpen ?? (categoryUrl ? pathname.startsWith(categoryUrl) : false)) - - function handleOpenChange(open: boolean) { - setOpen(open) - onPersistOpen(open) - } - - return ( - } open={open} onOpenChange={handleOpenChange} className="group/collapsible"> - - {category.icon} - {category.title} - - - } - /> - - {category.items?.length ? ( - - {category.items.map((item) => ( - - ))} - - ) : null} - - - ) -} - -function DSMenuItem({ item }: { item: (typeof DSData)["mainNav"][0]["items"][0] }) { - const path = usePathname() - - // NOTE: as of now, we have only 1 level depth of submenu, so using startsWith to - // match also subroutes is ok. - // If we go with multiple levels of depth it should be changed accordingly. - const isActive = path.startsWith(item.url) - - return ( - - }> - {item.icon} - {item.title} - - - ) -} diff --git a/src/components/dashboard-sidebar/user-nav.tsx b/src/components/dashboard-sidebar/user-nav.tsx deleted file mode 100644 index ca07cdc..0000000 --- a/src/components/dashboard-sidebar/user-nav.tsx +++ /dev/null @@ -1,108 +0,0 @@ -"use client" - -import Link from "next/link" -import { useRouter } from "next/navigation" -import { FiBell, FiChevronsDown, FiLogOut, FiUser } from "react-icons/fi" -import { toast } from "sonner" -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/ui/sidebar" -import { signOut, useSession } from "@/lib/auth" -import { getInitials } from "@/lib/utils" -import { Skeleton } from "../ui/skeleton" - -export function DSUserNav() { - const { data } = useSession() - const { isMobile } = useSidebar() - const router = useRouter() - - const user = data?.user - - if (!user) return - - return ( - - - - - - - {user.name ? getInitials(user.name) : } - -
- {user.name} - {user.email} -
- - - } - /> - - - -
- - - {user.name ? getInitials(user.name) : } - -
- {user.name} - {user.email} -
-
-
-
- - - - - - Account - - - - - Notifications - - - - - signOut({ - fetchOptions: { - onSuccess: () => { - toast.success("Logged out!") - router.refresh() - }, - }, - }) - } - > - - Log out - -
-
-
-
- ) -} diff --git a/src/components/data-table.tsx b/src/components/data-table.tsx deleted file mode 100644 index c97f7bc..0000000 --- a/src/components/data-table.tsx +++ /dev/null @@ -1,64 +0,0 @@ -"use client" - -import { - type ColumnDef, - flexRender, - getCoreRowModel, - getSortedRowModel, - type RowData, - useReactTable, -} from "@tanstack/react-table" - -import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table" - -interface DataTableProps { - // biome-ignore lint/suspicious/noExplicitAny: columns commonly mix accessor value types (string, number, group columns...) - columns: ColumnDef[] - data: TData[] -} - -export function DataTable({ columns, data }: DataTableProps) { - const table = useReactTable({ - data, - columns, - getCoreRowModel: getCoreRowModel(), - getSortedRowModel: getSortedRowModel(), - }) - - return ( -
- - - {table.getHeaderGroups().map((headerGroup) => ( - - {headerGroup.headers.map((header) => { - return ( - - {header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())} - - ) - })} - - ))} - - - {table.getRowModel().rows.length ? ( - table.getRowModel().rows.map((row) => ( - - {row.getVisibleCells().map((cell) => ( - {flexRender(cell.column.columnDef.cell, cell.getContext())} - ))} - - )) - ) : ( - - - No results. - - - )} - -
-
- ) -} diff --git a/src/components/data-toolbar.tsx b/src/components/data-toolbar.tsx new file mode 100644 index 0000000..c61b4d0 --- /dev/null +++ b/src/components/data-toolbar.tsx @@ -0,0 +1,86 @@ +import { Search, X } from "lucide-react" +import { type ReactNode, useDeferredValue, useEffect, useId, useRef, useState } from "react" +import { PageHeader } from "@/components/page-header" +import { Button } from "@/components/ui/button" +import { Input } from "@/components/ui/input" + +export function DataToolbar({ + title, + description, + count, + total, + onSearch, + searchPlaceholder, + action, + children, + eyebrow = "Directory", +}: { + title: string + description: string + count: number + total?: number + onSearch?: (value: string) => void + searchPlaceholder?: string + action?: ReactNode + children?: ReactNode + eyebrow?: string +}) { + const searchId = useId() + const [searchValue, setSearchValue] = useState("") + const deferredSearchValue = useDeferredValue(searchValue) + const onSearchRef = useRef(onSearch) + onSearchRef.current = onSearch + + useEffect(() => { + onSearchRef.current?.(deferredSearchValue) + }, [deferredSearchValue]) + + const resultLabel = + total !== undefined && total !== count + ? `${count.toLocaleString()} of ${total.toLocaleString()}` + : count.toLocaleString() + + return ( + <> + +
+ {onSearch && ( +
+ + + setSearchValue(event.target.value)} + placeholder={searchPlaceholder ?? `Search ${title.toLocaleLowerCase()}…`} + /> + {searchValue && ( + + )} +
+ )} + {children} +

+ {resultLabel} {count === 1 ? "result" : "results"} +

+
+ + ) +} diff --git a/src/components/empty-state.tsx b/src/components/empty-state.tsx new file mode 100644 index 0000000..3e106b0 --- /dev/null +++ b/src/components/empty-state.tsx @@ -0,0 +1,28 @@ +import type { LucideIcon } from "lucide-react" +import type { ReactNode } from "react" +import { Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle } from "@/components/ui/empty" + +export function EmptyState({ + icon: Icon, + title, + text, + action, +}: { + icon: LucideIcon + title: string + text: string + action?: ReactNode +}) { + return ( + + + + + + {title} + {text} + + {action && {action}} + + ) +} diff --git a/src/components/header-login-button.tsx b/src/components/header-login-button.tsx deleted file mode 100644 index 62057da..0000000 --- a/src/components/header-login-button.tsx +++ /dev/null @@ -1,44 +0,0 @@ -"use client" -import Link from "next/link" -import { usePathname, useRouter } from "next/navigation" -import { FiLogIn, FiLogOut } from "react-icons/fi" -import { useIsMobile } from "@/hooks/use-mobile" -import { auth, useSession } from "@/lib/auth" -import { Button } from "./ui/button" -import { Skeleton } from "./ui/skeleton" - -export function HeaderLoginButton() { - const { data, isPending } = useSession() - const pathname = usePathname() - const isMobile = useIsMobile() - const router = useRouter() - - if (isPending) return - if (data) - return ( - - ) - - return ( - - - - ) -} diff --git a/src/components/header.tsx b/src/components/header.tsx deleted file mode 100644 index d007f74..0000000 --- a/src/components/header.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import Link from "next/link" -import { FiGlobe } from "react-icons/fi" -import { ThemeButton } from "@/components/theme-button" -import { HeaderLoginButton } from "./header-login-button" -import { Logo } from "./logo" -import { Button } from "./ui/button" - -export const HEADER_HEIGHT = "3.3rem" - -export async function Header() { - return ( -
- -
- -

- PoliNetwork Admin -

-
- - - -
- ) -} diff --git a/src/components/input-prefix.tsx b/src/components/input-prefix.tsx deleted file mode 100644 index cf3c422..0000000 --- a/src/components/input-prefix.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import * as React from "react" -import { cn } from "@/lib/utils/shadcn" -import { Input } from "./ui/input" - -export interface InputWithPrefixProps extends React.InputHTMLAttributes { - prefix: string - containerClassName?: string -} - -const InputWithPrefix = React.forwardRef( - ({ className, type, prefix, containerClassName, ...props }, ref) => { - return ( -
-
- {prefix} -
- -
- ) - } -) -InputWithPrefix.displayName = "InputWithPrefix" - -export { InputWithPrefix } diff --git a/src/components/loading-skeleton.tsx b/src/components/loading-skeleton.tsx new file mode 100644 index 0000000..5a187d3 --- /dev/null +++ b/src/components/loading-skeleton.tsx @@ -0,0 +1,93 @@ +import { Skeleton } from "@/components/ui/skeleton" + +export function DataPageSkeleton({ + columns = 4, + rows = 7, + withTabs = false, +}: { + columns?: number + rows?: number + withTabs?: boolean +}) { + return ( +
+ Loading page data… +
+ + + +
+
+ + +
+ {withTabs && ( +
+ + + +
+ )} +
+
+ {Array.from({ length: columns }, (_, index) => ( + + ))} +
+ {Array.from({ length: rows }, (_, row) => ( +
+ {Array.from({ length: columns }, (_, column) => ( + + ))} +
+ ))} +
+
+ ) +} + +export function DetailPageSkeleton() { + return ( +
+ Loading user details… + +
+ +
+ + + +
+
+
+ {Array.from({ length: 3 }, (_, index) => ( +
+ + + + +
+ ))} +
+ {Array.from({ length: 3 }, (_, section) => ( +
+
+ + +
+
+ + +
+
+ ))} +
+ ) +} diff --git a/src/components/logo.tsx b/src/components/logo.tsx deleted file mode 100644 index f51fb95..0000000 --- a/src/components/logo.tsx +++ /dev/null @@ -1,6 +0,0 @@ -import Image, { type ImageProps } from "next/image" -import logo from "@/assets/logo.svg" - -export function Logo({ size, ...props }: { size?: number } & Omit) { - return PoliNetwork Logo -} diff --git a/src/components/logout-button.tsx b/src/components/logout-button.tsx deleted file mode 100644 index de99534..0000000 --- a/src/components/logout-button.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import { redirect } from "next/navigation" -import { FiLogOut } from "react-icons/fi" -import { Button } from "@/components/ui/button" -import { signOut } from "@/lib/auth" - -export function LogoutButton() { - return ( - - ) -} diff --git a/src/components/navigate-back.tsx b/src/components/navigate-back.tsx deleted file mode 100644 index febb551..0000000 --- a/src/components/navigate-back.tsx +++ /dev/null @@ -1,21 +0,0 @@ -"use client" - -import { useRouter } from "next/navigation" -import { FiArrowLeft } from "react-icons/fi" -import { Button } from "./ui/button" - -export function NavigateBack() { - const router = useRouter() - - return ( - - ) -} diff --git a/src/components/page-header.tsx b/src/components/page-header.tsx new file mode 100644 index 0000000..eb93b99 --- /dev/null +++ b/src/components/page-header.tsx @@ -0,0 +1,26 @@ +import type { ReactNode } from "react" + +export function PageHeader({ + eyebrow, + title, + description, + action, +}: { + eyebrow: string + title: string + description: string + action?: ReactNode +}) { + return ( +
+
+

{eyebrow}

+

+ {title} +

+

{description}

+
+ {action &&
{action}
} +
+ ) +} diff --git a/src/components/pagination.tsx b/src/components/pagination.tsx new file mode 100644 index 0000000..0985a02 --- /dev/null +++ b/src/components/pagination.tsx @@ -0,0 +1,131 @@ +import { ChevronLeft, ChevronRight, ChevronsLeft, ChevronsRight, MoreHorizontal } from "lucide-react" +import { Fragment } from "react" +import { Button } from "@/components/ui/button" + +export function Pagination({ + page, + pageCount, + onPageChange, + pageSize, + total, + pageSizeOptions = [10, 20, 25, 50, 100], + onPageSizeChange, +}: { + page: number + pageCount: number + onPageChange: (page: number) => void + pageSize: number + total?: number + pageSizeOptions?: number[] + onPageSizeChange: (pageSize: number) => void +}) { + const pages = [...new Set([1, page - 1, page, page + 1, pageCount])] + .filter((value) => value >= 1 && value <= pageCount) + .sort((a, b) => a - b) + const rangeStart = total ? (page - 1) * pageSize + 1 : 0 + const rangeEnd = total ? Math.min(page * pageSize, total) : 0 + + return ( +
+
+ + {total !== undefined && ( +

+ Showing {rangeStart.toLocaleString()}–{rangeEnd.toLocaleString()} of {total.toLocaleString()} +

+ )} +
+ {pageCount > 1 && ( + + )} +
+ ) +} + +function PageButton({ + label, + disabled, + onClick, + children, +}: { + label: string + disabled: boolean + onClick: () => void + children: React.ReactNode +}) { + return ( + + ) +} diff --git a/src/components/reui/stepper.tsx b/src/components/reui/stepper.tsx new file mode 100644 index 0000000..720f4fc --- /dev/null +++ b/src/components/reui/stepper.tsx @@ -0,0 +1,421 @@ +import { mergeProps } from "@base-ui/react/merge-props" +import { useRender } from "@base-ui/react/use-render" +import { + Children, + createContext, + type HTMLAttributes, + isValidElement, + type ReactElement, + useCallback, + useContext, + useEffect, + useMemo, + useRef, + useState, +} from "react" + +import { cn } from "@/lib/utils" + +// Types +type StepperOrientation = "horizontal" | "vertical" +type StepState = "active" | "completed" | "inactive" | "loading" +type StepIndicators = { + active?: React.ReactNode + completed?: React.ReactNode + inactive?: React.ReactNode + loading?: React.ReactNode +} + +interface StepperContextValue { + activeStep: number + setActiveStep: (step: number) => void + stepsCount: number + orientation: StepperOrientation + registerTrigger: (node: HTMLButtonElement) => void + unregisterTrigger: (node: HTMLButtonElement) => void + triggerNodes: HTMLButtonElement[] + focusNext: (currentIdx: number) => void + focusPrev: (currentIdx: number) => void + focusFirst: () => void + focusLast: () => void + indicators: StepIndicators +} + +interface StepItemContextValue { + step: number + state: StepState + isDisabled: boolean + isLoading: boolean +} + +const StepperContext = createContext(undefined) +const StepItemContext = createContext(undefined) + +function useStepper() { + const ctx = useContext(StepperContext) + if (!ctx) throw new Error("useStepper must be used within a Stepper") + return ctx +} + +function useStepItem() { + const ctx = useContext(StepItemContext) + if (!ctx) throw new Error("useStepItem must be used within a StepperItem") + return ctx +} + +interface StepperProps extends HTMLAttributes { + defaultValue?: number + value?: number + onValueChange?: (value: number) => void + orientation?: StepperOrientation + indicators?: StepIndicators +} + +function Stepper({ + defaultValue = 1, + value, + onValueChange, + orientation = "horizontal", + className, + children, + indicators = {}, + ...props +}: StepperProps) { + const [activeStep, setActiveStep] = useState(defaultValue) + const [triggerNodes, setTriggerNodes] = useState([]) + + // Register/unregister triggers + const registerTrigger = useCallback((node: HTMLButtonElement) => { + setTriggerNodes((prev) => { + if (prev.includes(node)) return prev + return [...prev, node] + }) + }, []) + const unregisterTrigger = useCallback((node: HTMLButtonElement) => { + setTriggerNodes((prev) => prev.filter((trigger) => trigger !== node)) + }, []) + + const handleSetActiveStep = useCallback( + (step: number) => { + if (value === undefined) { + setActiveStep(step) + } + onValueChange?.(step) + }, + [value, onValueChange] + ) + + const currentStep = value ?? activeStep + + // Keyboard navigation logic + const focusTrigger = (idx: number) => { + if (triggerNodes[idx]) triggerNodes[idx].focus() + } + const focusNext = (currentIdx: number) => focusTrigger((currentIdx + 1) % triggerNodes.length) + const focusPrev = (currentIdx: number) => focusTrigger((currentIdx - 1 + triggerNodes.length) % triggerNodes.length) + const focusFirst = () => focusTrigger(0) + const focusLast = () => focusTrigger(triggerNodes.length - 1) + + // Context value + const contextValue = useMemo( + () => ({ + activeStep: currentStep, + setActiveStep: handleSetActiveStep, + stepsCount: Children.toArray(children).filter( + (child): child is ReactElement => + isValidElement(child) && (child.type as { displayName?: string }).displayName === "StepperItem" + ).length, + orientation, + registerTrigger, + unregisterTrigger, + focusNext, + focusPrev, + focusFirst, + focusLast, + triggerNodes, + indicators, + }), + [currentStep, handleSetActiveStep, children, orientation, registerTrigger, unregisterTrigger, triggerNodes] + ) + + return ( + +
+ {children} +
+
+ ) +} + +interface StepperItemProps extends React.HTMLAttributes { + step: number + completed?: boolean + disabled?: boolean + loading?: boolean +} + +function StepperItem({ + step, + completed = false, + disabled = false, + loading = false, + className, + children, + ...props +}: StepperItemProps) { + const { activeStep } = useStepper() + + const state: StepState = completed || step < activeStep ? "completed" : activeStep === step ? "active" : "inactive" + + const isLoading = loading && step === activeStep + + return ( + +
+ {children} +
+
+ ) +} + +type StepperTriggerProps = useRender.ComponentProps<"button"> + +function StepperTrigger({ className, children, tabIndex, render, ...props }: StepperTriggerProps) { + const { state, isLoading } = useStepItem() + const stepperCtx = useStepper() + const { + setActiveStep, + activeStep, + registerTrigger, + unregisterTrigger, + triggerNodes, + focusNext, + focusPrev, + focusFirst, + focusLast, + } = stepperCtx + const { step, isDisabled } = useStepItem() + const isSelected = activeStep === step + const id = `stepper-tab-${step}` + const panelId = `stepper-panel-${step}` + + // Register this trigger for keyboard navigation + const btnRef = useRef(null) + useEffect(() => { + const node = btnRef.current + if (!node) return + registerTrigger(node) + return () => unregisterTrigger(node) + }, [registerTrigger, unregisterTrigger]) + + // Find our index among triggers for navigation + const myIdx = useMemo(() => triggerNodes.findIndex((n: HTMLButtonElement) => n === btnRef.current), [triggerNodes]) + + const handleKeyDown = (e: React.KeyboardEvent) => { + switch (e.key) { + case "ArrowRight": + case "ArrowDown": + e.preventDefault() + if (myIdx !== -1 && focusNext) focusNext(myIdx) + break + case "ArrowLeft": + case "ArrowUp": + e.preventDefault() + if (myIdx !== -1 && focusPrev) focusPrev(myIdx) + break + case "Home": + e.preventDefault() + if (focusFirst) focusFirst() + break + case "End": + e.preventDefault() + if (focusLast) focusLast() + break + case "Enter": + case " ": + e.preventDefault() + setActiveStep(step) + break + } + } + + const defaultProps = { + role: "tab", + id, + "aria-selected": isSelected, + "aria-controls": panelId, + tabIndex: typeof tabIndex === "number" ? tabIndex : isSelected ? 0 : -1, + "data-slot": "stepper-trigger", + "data-state": state, + "data-loading": isLoading, + className: cn( + "focus-visible:border-ring focus-visible:ring-ring/50 inline-flex cursor-pointer items-center outline-none focus-visible:z-10 focus-visible:ring-3 disabled:pointer-events-none disabled:opacity-60", + "gap-2.5 rounded-full", + className + ), + onClick: () => setActiveStep(step), + onKeyDown: handleKeyDown, + disabled: isDisabled, + children, + } + + return useRender({ + defaultTagName: "button", + render, + ref: btnRef, + props: mergeProps<"button">(defaultProps, props), + }) +} + +function StepperIndicator({ children, className }: React.ComponentProps<"div">) { + const { state, isLoading } = useStepItem() + const { indicators } = useStepper() + + return ( +
+
+ {indicators && + ((isLoading && indicators.loading) || + (state === "completed" && indicators.completed) || + (state === "active" && indicators.active) || + (state === "inactive" && indicators.inactive)) + ? (isLoading && indicators.loading) || + (state === "completed" && indicators.completed) || + (state === "active" && indicators.active) || + (state === "inactive" && indicators.inactive) + : children} +
+
+ ) +} + +function StepperSeparator({ className }: React.ComponentProps<"div">) { + const { state } = useStepItem() + + return ( +
+ ) +} + +function StepperTitle({ children, className }: React.ComponentProps<"h3">) { + const { state } = useStepItem() + + return ( +

+ {children} +

+ ) +} + +function StepperDescription({ children, className }: React.ComponentProps<"div">) { + const { state } = useStepItem() + + return ( +
+ {children} +
+ ) +} + +function StepperNav({ children, className }: React.ComponentProps<"nav">) { + const { activeStep, orientation } = useStepper() + + return ( + + ) +} + +function StepperPanel({ children, className }: React.ComponentProps<"div">) { + const { activeStep } = useStepper() + + return ( +
+ {children} +
+ ) +} + +interface StepperContentProps extends React.ComponentProps<"div"> { + value: number + forceMount?: boolean +} + +function StepperContent({ value, forceMount, children, className }: StepperContentProps) { + const { activeStep } = useStepper() + const isActive = value === activeStep + + if (!forceMount && !isActive) { + return null + } + + return ( + + ) +} + +export { + useStepper, + useStepItem, + Stepper, + StepperItem, + StepperTrigger, + StepperIndicator, + StepperSeparator, + StepperTitle, + StepperDescription, + StepperPanel, + StepperContent, + StepperNav, + type StepperProps, + type StepperItemProps, + type StepperTriggerProps, + type StepperContentProps, +} diff --git a/src/components/route-error.tsx b/src/components/route-error.tsx new file mode 100644 index 0000000..30ce741 --- /dev/null +++ b/src/components/route-error.tsx @@ -0,0 +1,49 @@ +import { type ErrorComponentProps, Link, useRouter } from "@tanstack/react-router" +import { AlertTriangle, RefreshCw } from "lucide-react" +import { Button } from "@/components/ui/button" +import { Card, CardContent } from "@/components/ui/card" + +export function RouteError({ error, reset }: ErrorComponentProps) { + const router = useRouter() + const message = + import.meta.env.DEV && error instanceof Error + ? error.message + : "The requested data could not be loaded. Try again or return to the overview." + + async function retry() { + reset() + await router.invalidate({ sync: true }) + } + + return ( + + + +

This area could not be loaded

+

{message}

+
+ + +
+
+
+ ) +} + +export function RouteNotFound() { + return ( + + +

Page not found

+

The requested page or record does not exist.

+ +
+
+ ) +} diff --git a/src/components/search-input.tsx b/src/components/search-input.tsx deleted file mode 100644 index 43b9009..0000000 --- a/src/components/search-input.tsx +++ /dev/null @@ -1,47 +0,0 @@ -"use client" - -import { useRouter, useSearchParams } from "next/navigation" -import { useEffect, useState } from "react" -import { FiRefreshCcw, FiSearch } from "react-icons/fi" -import { Button } from "@/components/ui/button" -import { Input } from "@/components/ui/input" - -export function SearchInput({ disabled }: { disabled?: boolean }) { - const router = useRouter() - const searchParams = useSearchParams() - const q = searchParams.get("q") ?? "" - const [value, setValue] = useState(q) - - const handleSearch = () => { - const params = new URLSearchParams(searchParams.toString()) - if (value) { - params.set("q", value) - } else { - params.delete("q") - } - router.replace(`?${params.toString()}`) - } - useEffect(() => { - setValue(q) - }, [q]) - - return ( -
- setValue(e.target.value)} - onKeyDown={(e) => e.key === "Enter" && handleSearch()} - placeholder="Search..." - /> - - -
- ) -} diff --git a/src/components/shapes.tsx b/src/components/shapes.tsx deleted file mode 100644 index 3841c6a..0000000 --- a/src/components/shapes.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import Image from "next/image" -import bigBlueSvg from "@/assets/svg/shapes/big-blue.svg" -import bigTealSvg from "@/assets/svg/shapes/big-teal.svg" -import looperSvg from "@/assets/svg/shapes/looper.svg" -import smallBlueSvg from "@/assets/svg/shapes/small-blue.svg" -import { cn } from "@/lib/utils/shadcn" - -export type ShapeVariant = "big-blue" | "big-teal" | "small-blue" | "looper" - -export type ShapeProps = { - variant: ShapeVariant - className?: string -} - -export const Shape: React.FC = ({ variant, className }) => { - const getShapeSrc = () => { - switch (variant) { - case "big-blue": - return bigBlueSvg - case "big-teal": - return bigTealSvg - case "small-blue": - return smallBlueSvg - case "looper": - return looperSvg - default: - return "" - } - } - - return -} diff --git a/src/components/spinner.tsx b/src/components/spinner.tsx deleted file mode 100644 index 97e5baf..0000000 --- a/src/components/spinner.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import { cn } from "@/lib/utils/shadcn" - -export function Spinner({ className }: React.HtmlHTMLAttributes) { - return ( - // biome-ignore lint/a11y/useSemanticElements: incorrect change suggestion -
- - Loading... -
- ) -} diff --git a/src/components/telegram/create-grant-dialog.tsx b/src/components/telegram/create-grant-dialog.tsx new file mode 100644 index 0000000..f101aa9 --- /dev/null +++ b/src/components/telegram/create-grant-dialog.tsx @@ -0,0 +1,462 @@ +import { useRouter } from "@tanstack/react-router" +import { useServerFn } from "@tanstack/react-start" +import { ArrowLeft, CalendarPlus, LoaderCircle, Search, UserRound, X } from "lucide-react" +import { useState } from "react" +import { toast } from "sonner" +import { + Stepper, + StepperIndicator, + StepperItem, + StepperNav, + StepperTitle, + StepperTrigger, +} from "@/components/reui/stepper" +import { createTelegramGrant } from "@/features/telegram/grants.functions" +import { findTelegramUser } from "@/features/telegram/users.functions" +import type { TgUser } from "@/lib/api/types" +import { Alert, AlertAction, AlertDescription, AlertTitle } from "../ui/alert" +import { Button } from "../ui/button" +import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from "../ui/dialog" +import { Field, FieldError, FieldGroup, FieldLabel } from "../ui/field" +import { Input } from "../ui/input" +import { Textarea } from "../ui/textarea" +import { ToggleGroup, ToggleGroupItem } from "../ui/toggle-group" +import { GrantDateTimeFields } from "./grant-date-time-fields" + +export type GrantDialogUser = Pick + +type CreateGrantDialogProps = { + user?: GrantDialogUser +} + +const DISCARD_TOAST_ID = "discard-grant-dialog-changes" + +function toDateTimeInput(date: Date) { + const local = new Date(date.getTime() - date.getTimezoneOffset() * 60_000) + return local.toISOString().slice(0, 16) +} + +function earliestGrantStart() { + const start = new Date() + start.setHours(0, 0, 0, 0) + return start +} + +function displayName(user: GrantDialogUser) { + return [user.firstName, user.lastName].filter(Boolean).join(" ") || "Unnamed account" +} + +function grantMutationError(error: string) { + if (error === "UNAUTHORIZED") return "You do not have permission to create grants." + if (error === "ALREADY_EXISTING") return "This user already has an ongoing grant." + return "The grant could not be created." +} + +function UserInformation({ + user, + clearable, + onClear, +}: { + user: GrantDialogUser + clearable?: boolean + onClear?: () => void +}) { + return ( + + + {displayName(user)} + + {user.username ? `@${user.username}` : "No Telegram username"} · Telegram ID {user.id} + + {clearable && onClear && ( + + + + )} + + ) +} + +function GrantStepper({ + step, + canOpenDetails, + onStepChange, +}: { + step: "user" | "details" + canOpenDetails: boolean + onStepChange: (step: "user" | "details") => void +}) { + const steps = [ + { title: "Target user", value: 1 }, + { title: "Details", value: 2 }, + ] + + return ( + { + if (value === 1) onStepChange("user") + if (value === 2 && canOpenDetails) onStepChange("details") + }} + className="p-5" + aria-label="Grant creation progress" + > + + {steps.map((item) => ( + + + + Step {item.value} + + + {item.title} + + + + ))} + + + ) +} + +export function CreateGrantDialog({ user: fixedUser }: CreateGrantDialogProps) { + const [open, setOpen] = useState(false) + const [step, setStep] = useState<"user" | "details">(fixedUser ? "details" : "user") + const [lookupBy, setLookupBy] = useState<"username" | "id">("username") + const [query, setQuery] = useState("") + const [selectedUser, setSelectedUser] = useState(fixedUser ?? null) + const [lookupStatus, setLookupStatus] = useState<"idle" | "loading" | "not-found" | "error">("idle") + const [lookupMessage, setLookupMessage] = useState("") + const [validSince, setValidSince] = useState("") + const [validUntil, setValidUntil] = useState("") + const [reason, setReason] = useState("") + const [dirty, setDirty] = useState(false) + const [pending, setPending] = useState(false) + const router = useRouter() + const createGrant = useServerFn(createTelegramGrant) + const findUser = useServerFn(findTelegramUser) + + const resetForm = () => { + setStep(fixedUser ? "details" : "user") + setLookupBy("username") + setQuery("") + setSelectedUser(fixedUser ?? null) + setLookupStatus("idle") + setLookupMessage("") + setValidSince("") + setValidUntil("") + setReason("") + setDirty(false) + } + + const closeAndReset = () => { + toast.dismiss(DISCARD_TOAST_ID) + setOpen(false) + resetForm() + } + + const requestClose = () => { + if (pending) return + if (!dirty) { + closeAndReset() + return + } + + toast.warning("Discard grant changes?", { + id: DISCARD_TOAST_ID, + description: "Your edits will be lost.", + position: "bottom-center", + duration: Number.POSITIVE_INFINITY, + className: "grant-discard-toast", + action: { + label: "Discard", + onClick: closeAndReset, + }, + cancel: { + label: "Keep editing", + onClick: () => undefined, + }, + }) + } + + const handleOpenChange = (nextOpen: boolean) => { + if (nextOpen) { + resetForm() + setOpen(true) + return + } + requestClose() + } + + const changeLookupBy = (value: string[]) => { + const next = value[0] + if (next !== "username" && next !== "id") return + setLookupBy(next) + setQuery("") + setSelectedUser(null) + setLookupStatus("idle") + setLookupMessage("") + setDirty(true) + } + + const lookup = async () => { + const normalized = query.trim() + const numericId = Number(normalized) + if (!normalized || (lookupBy === "id" && (!Number.isInteger(numericId) || numericId <= 0))) { + setLookupStatus("error") + setLookupMessage(lookupBy === "id" ? "Enter a positive numeric Telegram ID." : "Enter a Telegram username.") + return + } + + setSelectedUser(null) + setLookupStatus("loading") + setLookupMessage("") + try { + const result = await findUser({ + data: lookupBy === "username" ? { by: "username", username: normalized } : { by: "id", userId: numericId }, + }) + if (result.status === "found" && result.user) { + setSelectedUser(result.user) + setLookupStatus("idle") + } else { + setLookupStatus(result.status === "not-found" ? "not-found" : "error") + setLookupMessage( + result.status === "not-found" + ? `No Telegram user was found for this ${lookupBy === "id" ? "ID" : "username"}.` + : (result.message ?? "Telegram user lookup failed.") + ) + } + } catch (error) { + console.error(error) + setLookupStatus("error") + setLookupMessage("Telegram user lookup failed. Check your connection and try again.") + } + } + + const submit = async (event: React.FormEvent) => { + event.preventDefault() + const since = new Date(validSince) + const until = new Date(validUntil) + if ( + !selectedUser || + !validSince || + !validUntil || + Number.isNaN(since.getTime()) || + Number.isNaN(until.getTime()) || + since < earliestGrantStart() || + until <= since || + pending + ) + return + + setPending(true) + try { + const result = await createGrant({ + data: { userId: selectedUser.id, since, until, reason: reason.trim() || undefined }, + }) + if (result.error) { + toast.error(grantMutationError(result.error)) + return + } + toast.success(`Grant created for ${displayName(selectedUser)}.`) + closeAndReset() + try { + await router.invalidate({ sync: true }) + } catch { + toast.warning("The grant was created, but the latest grants could not be refreshed.") + } + } catch (error) { + console.error(error) + toast.error("The grant could not be created. Check your permissions and try again.") + } finally { + setPending(false) + } + } + + const sinceTime = new Date(validSince).getTime() + const untilTime = new Date(validUntil).getTime() + const minimumSince = toDateTimeInput(earliestGrantStart()) + const invalidStart = Boolean(validSince) && (Number.isNaN(sinceTime) || sinceTime < earliestGrantStart().getTime()) + const invalidEnd = Boolean(validUntil) && (Number.isNaN(untilTime) || (Boolean(validSince) && untilTime <= sinceTime)) + const detailsUser = fixedUser ?? selectedUser + + return ( + + }> + Add grant + + + + New Grant + + + {!fixedUser && } + + {step === "user" ? ( +
{ + event.preventDefault() + void lookup() + }} + > + + + Find Telegram user + + Username + Telegram ID + + + + + {lookupBy === "username" ? "Telegram username" : "Numeric Telegram ID"} + +
+ { + setQuery(event.target.value) + setSelectedUser(null) + setLookupStatus("idle") + setLookupMessage("") + setDirty(true) + }} + type={lookupBy === "id" ? "text" : "search"} + inputMode={lookupBy === "id" ? "numeric" : undefined} + placeholder={lookupBy === "username" ? "@username" : "123456789"} + autoComplete="off" + disabled={lookupStatus === "loading"} + aria-invalid={lookupStatus === "error"} + aria-describedby="grant-user-status" + /> + +
+ {lookupStatus === "error" && {lookupMessage}} +
+
+ {(lookupStatus === "not-found" || selectedUser) && ( +
+ {lookupStatus === "not-found" && ( + + + User not found + {lookupMessage} + + )} + {selectedUser && ( + { + setSelectedUser(null) + setQuery("") + setDirty(true) + }} + /> + )} +
+ )} + + + + +
+ ) : ( +
void submit(event)} + > + {!fixedUser && ( + + )} + {detailsUser && } + { + setValidSince(value) + setDirty(true) + }} + onValidUntilChange={(value) => { + setValidUntil(value) + setDirty(true) + }} + minimumSince={minimumSince} + minimumUntil={validSince || minimumSince} + invalidStart={invalidStart} + invalidEnd={invalidEnd} + /> + + + Motivation (optional) + +