From c2d514f01ce3c6278da14a1544b20c9aec4842b0 Mon Sep 17 00:00:00 2001 From: Cali Castle Date: Mon, 12 Jun 2023 17:14:25 +0800 Subject: [PATCH] feat: add a quick admin dashboard --- app/admin/layout.tsx | 15 ++ app/admin/page.tsx | 113 ++++++++ lib/string.ts | 9 + package.json | 2 + pnpm-lock.yaml | 627 +++++++++++++++++++++++++++++++++++++++++-- tailwind.config.cjs | 120 ++++++++- 6 files changed, 868 insertions(+), 18 deletions(-) create mode 100644 app/admin/layout.tsx create mode 100644 app/admin/page.tsx diff --git a/app/admin/layout.tsx b/app/admin/layout.tsx new file mode 100644 index 00000000..8f17d9c6 --- /dev/null +++ b/app/admin/layout.tsx @@ -0,0 +1,15 @@ +import { currentUser } from '@clerk/nextjs' +import { redirect } from 'next/navigation' + +export default async function AdminLayout({ + children, +}: { + children: React.ReactNode +}) { + const user = await currentUser() + if (!user || !user.publicMetadata.siteOwner) { + redirect('/') + } + + return
{children}
+} diff --git a/app/admin/page.tsx b/app/admin/page.tsx new file mode 100644 index 00000000..65acc302 --- /dev/null +++ b/app/admin/page.tsx @@ -0,0 +1,113 @@ +import { + Card, + Grid, + Metric, + Table, + TableBody, + TableCell, + TableHead, + TableHeaderCell, + TableRow, + Text, + Title, +} from '@tremor/react' +import { desc, sql } from 'drizzle-orm' +import Link from 'next/link' +import React from 'react' + +import { Container } from '~/components/ui/Container' +import { db } from '~/db' +import { comments } from '~/db/schema' +import { url } from '~/lib' +import { truncate } from '~/lib/string' +import { clientFetch } from '~/sanity/lib/client' + +export default async function AdminPage() { + const { + rows: [commentsCount], + } = await db.execute<{ today_count: number }>( + sql`SELECT + (SELECT COUNT(*) FROM comments WHERE DATE(created_at) = CURDATE()) as today_count, + (SELECT COUNT(*) FROM comments WHERE YEARWEEK(created_at, 1) = YEARWEEK(CURDATE(), 1)) as this_week_count, + (SELECT COUNT(*) FROM comments WHERE YEAR(created_at) = YEAR(CURDATE()) AND MONTH(created_at) = MONTH(CURDATE())) as this_month_count` + ) + + const latestComments = await db + .select() + .from(comments) + .orderBy(desc(comments.createdAt)) + .limit(15) + // get unique post IDs from comments + const postIds = [...new Set(latestComments.map((comment) => comment.postId))] + const posts = await clientFetch< + { _id: string; title: string; slug: string }[] + >( + `*[_type == "post" && (_id in [${postIds + .map((v) => `"${v}"`) + .join(',')}])]{ _id, title, "slug":slug.current }` + ) + // define a map with key of post IDs to posts + const postMap = new Map(posts.map((post) => [post._id, post])) + + return ( + + 后台数据中心 + + + + 今日评论数 + + {commentsCount && 'today_count' in commentsCount && ( + {commentsCount.today_count} + )} + + + 本周评论数 + {commentsCount && 'this_week_count' in commentsCount && ( + {commentsCount.this_week_count} + )} + + + + 本月评论数 + {commentsCount && 'this_month_count' in commentsCount && ( + {commentsCount.this_month_count} + )} + + +
+ + + + + 文章 + 评论内容 + + + + {latestComments.map((comment) => ( + + + + {postMap.get(comment.postId)?.title} + + + + + {/* eslint-disable-next-line @typescript-eslint/no-explicit-any */} + {truncate((comment.body as any).text as string)} + + + + ))} + +
+
+
+
+ ) +} diff --git a/lib/string.ts b/lib/string.ts index 86302e9e..cb834716 100644 --- a/lib/string.ts +++ b/lib/string.ts @@ -22,3 +22,12 @@ export function parseDisplayName({ return '匿名用户' } + +export function truncate(str: string, maxLength = 50): string { + if (str.length <= maxLength) { + return str + } + + const truncatedStr = str.slice(0, maxLength) + return truncatedStr + '...' +} diff --git a/package.json b/package.json index 242bcd9f..859205fc 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,7 @@ "@sanity/ui": "^1.5.0", "@sanity/vision": "^3.12.0", "@splinetool/react-spline": "^2.2.6", + "@tremor/react": "^3.0.1", "@upstash/ratelimit": "^0.4.3", "@upstash/redis": "^1.21.0", "@vercel/analytics": "^1.0.1", @@ -79,6 +80,7 @@ "zod": "^3.21.4" }, "devDependencies": { + "@headlessui/tailwindcss": "^0.1.3", "@tailwindcss/typography": "^0.5.9", "@types/eslint": "^8.40.1", "@types/node": "^18.16.15", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 09889429..7d83c328 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -95,6 +95,9 @@ dependencies: '@splinetool/react-spline': specifier: ^2.2.6 version: 2.2.6(@splinetool/runtime@0.9.366)(react-dom@18.2.0)(react@18.2.0) + '@tremor/react': + specifier: ^3.0.1 + version: 3.0.1(prop-types@15.8.1)(react-dom@18.2.0)(react@18.2.0)(tailwindcss@3.3.2) '@upstash/ratelimit': specifier: ^0.4.3 version: 0.4.3 @@ -199,6 +202,9 @@ dependencies: version: 3.21.4 devDependencies: + '@headlessui/tailwindcss': + specifier: ^0.1.3 + version: 0.1.3(tailwindcss@3.3.2) '@tailwindcss/typography': specifier: ^0.5.9 version: 0.5.9(tailwindcss@3.3.2) @@ -280,7 +286,6 @@ packages: /@alloc/quick-lru@5.2.0: resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} engines: {node: '>=10'} - dev: true /@ampproject/remapping@2.2.1: resolution: {integrity: sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==} @@ -1088,6 +1093,14 @@ packages: resolution: {integrity: sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==} dev: false + /@emotion/use-insertion-effect-with-fallbacks@1.0.1(react@18.2.0): + resolution: {integrity: sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==} + peerDependencies: + react: '>=16.8.0' + dependencies: + react: 18.2.0 + dev: false + /@esbuild/android-arm64@0.16.17: resolution: {integrity: sha512-MIGl6p5sc3RDTLLkYL1MyL8BMRN4tLMRCn+yRJJmEDvYZ2M7tmAf80hx1kbNEUX2KJ50RRtxZ4JHLvCfuB6kBg==} engines: {node: '>=12'} @@ -1760,6 +1773,17 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: false + /@floating-ui/react-dom@1.3.0(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-htwHm67Ji5E/pROEAr7f8IKFShuiCKHwUC/UY4vC3I5jiSvGFAYnSYiZO5MlGmads+QqvUkR9ANHEguGrDv72g==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + dependencies: + '@floating-ui/dom': 1.2.9 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + /@floating-ui/react-dom@2.0.0(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-Ke0oU3SeuABC2C4OFu2mSAwHIP5WUiV98O9YWoHV4Q5aT6E9k06DV0Khi5uYspR8xmmBk08t8ZDcz3TR3ARkEg==} peerDependencies: @@ -1771,6 +1795,19 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: false + /@floating-ui/react@0.19.2(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-JyNk4A0Ezirq8FlXECvRtQOX/iBe5Ize0W/pLkrZjfHW9GUV7Xnq6zm6fyZuQzaHHqEnVizmvlA96e1/CkZv+w==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + dependencies: + '@floating-ui/react-dom': 1.3.0(react-dom@18.2.0)(react@18.2.0) + aria-hidden: 1.2.3 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + tabbable: 6.1.2 + dev: false + /@headlessui/react@1.7.15(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-OTO0XtoRQ6JPB1cKNFYBZv2Q0JMqMGNhYP1CjPvcJvjz8YGokz8oAj89HIYZGN0gZzn/4kk9iUpmMF4Q21Gsqw==} engines: {node: '>=10'} @@ -1783,6 +1820,14 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: false + /@headlessui/tailwindcss@0.1.3(tailwindcss@3.3.2): + resolution: {integrity: sha512-3aMdDyYZx9A15euRehpppSyQnb2gIw2s/Uccn2ELIoLQ9oDy0+9oRygNWNjXCD5Dt+w1pxo7C+XoiYvGcqA4Kg==} + engines: {node: '>=10'} + peerDependencies: + tailwindcss: ^3.0 + dependencies: + tailwindcss: 3.3.2 + /@hookform/resolvers@3.1.0(react-hook-form@7.44.3): resolution: {integrity: sha512-z0A8K+Nxq+f83Whm/ajlwE6VtQlp/yPHZnXw7XWVPIGm1Vx0QV8KThU3BpbBRfAZ7/dYqCKKBNnQh85BkmBKkA==} peerDependencies: @@ -3619,6 +3664,180 @@ packages: react: 18.2.0 dev: false + /@storybook/addon-storysource@7.0.20(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-cBKFICYseeWB7cCxs0lCkkrLI64JJx3UEYxiusxGCoiS6yb8mUI8YbxYmOibODPKvozjl0+CMJn5EXMRPs0TlA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + react: + optional: true + react-dom: + optional: true + dependencies: + '@storybook/client-logger': 7.0.20 + '@storybook/components': 7.0.20(react-dom@18.2.0)(react@18.2.0) + '@storybook/manager-api': 7.0.20(react-dom@18.2.0)(react@18.2.0) + '@storybook/preview-api': 7.0.20 + '@storybook/router': 7.0.20(react-dom@18.2.0)(react@18.2.0) + '@storybook/source-loader': 7.0.20(react-dom@18.2.0)(react@18.2.0) + '@storybook/theming': 7.0.20(react-dom@18.2.0)(react@18.2.0) + estraverse: 5.3.0 + prop-types: 15.8.1 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-syntax-highlighter: 15.5.0(react@18.2.0) + dev: false + + /@storybook/channel-postmessage@7.0.20: + resolution: {integrity: sha512-GhVI40gbCnq20+Wjk/f8RD/T4gruLNKCjuwTnCAoKIQpMOVAB6ddx0469f9lF5tAha6alZn0MLk5CXPK8LAn5w==} + dependencies: + '@storybook/channels': 7.0.20 + '@storybook/client-logger': 7.0.20 + '@storybook/core-events': 7.0.20 + '@storybook/global': 5.0.0 + qs: 6.11.2 + telejson: 7.1.0 + dev: false + + /@storybook/channels@7.0.20: + resolution: {integrity: sha512-AL5GGSQ8WTDUoh3gitKEzo3fu7Vq5okXq2pAknAZlQA2Oio+HHO5nMeXvOfGdvo/tzbpNE3n5utmCJz006xrCA==} + dev: false + + /@storybook/client-logger@7.0.20: + resolution: {integrity: sha512-h0maWgvrhoDVALrbQ6ZFF0/7koVAazMbqWLmV/SF4JB2cBSgfgO0gmrCmKzUAe+KOABK/TMQTEQc1S1js0Dorw==} + dependencies: + '@storybook/global': 5.0.0 + dev: false + + /@storybook/components@7.0.20(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-eoEtby/yVkvUKpXfktibxPOhR5UBsWnKRWQUNSxN0vYTG4iBBh3HdjgxFJYfSXV13J+6OfvpBPLlPC+enXrbrQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + dependencies: + '@storybook/client-logger': 7.0.20 + '@storybook/csf': 0.1.1 + '@storybook/global': 5.0.0 + '@storybook/theming': 7.0.20(react-dom@18.2.0)(react@18.2.0) + '@storybook/types': 7.0.20 + memoizerific: 1.11.3 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + use-resize-observer: 9.1.0(react-dom@18.2.0)(react@18.2.0) + util-deprecate: 1.0.2 + dev: false + + /@storybook/core-events@7.0.20: + resolution: {integrity: sha512-gUBQsbcDmRufmg8LdH7D57c/9BQ+cPi2vBcXdudmxeJFafGwDmLRu1mlv9rxlW4kicn/LZWJjKXtq4XXzF4OGg==} + dev: false + + /@storybook/csf@0.1.1: + resolution: {integrity: sha512-4hE3AlNVxR60Wc5KSC68ASYzUobjPqtSKyhV6G+ge0FIXU55N5nTY7dXGRZHQGDBPq+XqchMkIdlkHPRs8nTHg==} + dependencies: + type-fest: 2.19.0 + dev: false + + /@storybook/global@5.0.0: + resolution: {integrity: sha512-FcOqPAXACP0I3oJ/ws6/rrPT9WGhu915Cg8D02a9YxLo0DE9zI+a9A5gRGvmQ09fiWPukqI8ZAEoQEdWUKMQdQ==} + dev: false + + /@storybook/manager-api@7.0.20(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-/f4L63SWcj4OCck8hdKItnlq/QDZAF6fn4QDLdqXNhPsoi+G6YUMVBX23bW0ygyTM0nrOoAPLVP934H33Xb9Bg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + dependencies: + '@storybook/channels': 7.0.20 + '@storybook/client-logger': 7.0.20 + '@storybook/core-events': 7.0.20 + '@storybook/csf': 0.1.1 + '@storybook/global': 5.0.0 + '@storybook/router': 7.0.20(react-dom@18.2.0)(react@18.2.0) + '@storybook/theming': 7.0.20(react-dom@18.2.0)(react@18.2.0) + '@storybook/types': 7.0.20 + dequal: 2.0.3 + lodash: 4.17.21 + memoizerific: 1.11.3 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + semver: 7.5.1 + store2: 2.14.2 + telejson: 7.1.0 + ts-dedent: 2.2.0 + dev: false + + /@storybook/preview-api@7.0.20: + resolution: {integrity: sha512-obtzMnI8X1GkOFivHUHsvXu8B0Lr/EECF+y35La1puGKbugviKj/k5vip2rlXmTDuqlxjexHZQOFz4n9NIeHiw==} + dependencies: + '@storybook/channel-postmessage': 7.0.20 + '@storybook/channels': 7.0.20 + '@storybook/client-logger': 7.0.20 + '@storybook/core-events': 7.0.20 + '@storybook/csf': 0.1.1 + '@storybook/global': 5.0.0 + '@storybook/types': 7.0.20 + '@types/qs': 6.9.7 + dequal: 2.0.3 + lodash: 4.17.21 + memoizerific: 1.11.3 + qs: 6.11.2 + synchronous-promise: 2.0.17 + ts-dedent: 2.2.0 + util-deprecate: 1.0.2 + dev: false + + /@storybook/router@7.0.20(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-Nzyy62hlP4QR3Dub2/PBqi2E7NjKUd1HBEMXFg2ggWF7ak2h9M1iPI0gGk6sUuC5NBVzYP20eF9wrz3Fe9eq8Q==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + dependencies: + '@storybook/client-logger': 7.0.20 + memoizerific: 1.11.3 + qs: 6.11.2 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@storybook/source-loader@7.0.20(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-IXboBXQkYrSMVbvjn0iT+4m3H6sJkA8SpKyJZSt2p5s7y1mkI6Wkyi+a7pH/BCwz08c1N9O0MlpTaNQJDyBnow==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + dependencies: + '@storybook/csf': 0.1.1 + '@storybook/types': 7.0.20 + estraverse: 5.3.0 + lodash: 4.17.21 + prettier: 2.8.8 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@storybook/theming@7.0.20(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-qmo/RKygt7W+NoHCfszChhSOFKe7eNeGzax4YR7yeX3brTzUQqGnb0onGv7MPtoCPhMFpbktK80u4biZtC7XhQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + dependencies: + '@emotion/use-insertion-effect-with-fallbacks': 1.0.1(react@18.2.0) + '@storybook/client-logger': 7.0.20 + '@storybook/global': 5.0.0 + memoizerific: 1.11.3 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@storybook/types@7.0.20: + resolution: {integrity: sha512-Z7RhHRnhrPd2jXPZtjbOILj1QgylqlsD3cFIYMcSz3yvUvxLRx3BKCftXyFbIuxr0QoCJE38adRp7YGO9uJnQQ==} + dependencies: + '@storybook/channels': 7.0.20 + '@types/babel__core': 7.20.1 + '@types/express': 4.17.14 + file-system-cache: 2.3.0 + dev: false + /@swc/helpers@0.4.14: resolution: {integrity: sha512-4C7nX/dvpzB7za4Ql9K81xK3HPxCpHMgwTZVyf+9JQ6VUbn9jjZVN7/Nkdz/Ugzs2CSjqnL/UPXroiVBVHUWUw==} dependencies: @@ -3661,12 +3880,62 @@ packages: engines: {node: '>= 10'} dev: false + /@tremor/react@3.0.1(prop-types@15.8.1)(react-dom@18.2.0)(react@18.2.0)(tailwindcss@3.3.2): + resolution: {integrity: sha512-se+k/6H69qD9zjsdjG0X63YYmSrahKa54nC9ygh7JlR49XjPtrDbTXjiTHzUDkE36ENeHKoYjLls3KY3Uab+DA==} + peerDependencies: + react: ^18.0.0 + react-dom: '>=16.6.0' + dependencies: + '@floating-ui/react': 0.19.2(react-dom@18.2.0)(react@18.2.0) + '@headlessui/react': 1.7.15(react-dom@18.2.0)(react@18.2.0) + '@headlessui/tailwindcss': 0.1.3(tailwindcss@3.3.2) + date-fns: 2.30.0 + react: 18.2.0 + react-day-picker: 8.7.1(date-fns@2.30.0)(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) + react-transition-group: 4.4.5(react-dom@18.2.0)(react@18.2.0) + recharts: 2.7.0-alpha.0(prop-types@15.8.1)(react-dom@18.2.0)(react@18.2.0) + tailwind-merge: 1.12.0 + transitivePeerDependencies: + - prop-types + - tailwindcss + dev: false + /@types/acorn@4.0.6: resolution: {integrity: sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ==} dependencies: '@types/estree': 1.0.1 dev: false + /@types/babel__core@7.20.1: + resolution: {integrity: sha512-aACu/U/omhdk15O4Nfb+fHgH/z3QsfQzpnvRZhYhThms83ZnAOZz7zZAWO7mn2yyNQaA4xTO8GLK3uqFU4bYYw==} + dependencies: + '@babel/parser': 7.22.5 + '@babel/types': 7.22.5 + '@types/babel__generator': 7.6.4 + '@types/babel__template': 7.4.1 + '@types/babel__traverse': 7.20.1 + dev: false + + /@types/babel__generator@7.6.4: + resolution: {integrity: sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==} + dependencies: + '@babel/types': 7.22.5 + dev: false + + /@types/babel__template@7.4.1: + resolution: {integrity: sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==} + dependencies: + '@babel/parser': 7.22.5 + '@babel/types': 7.22.5 + dev: false + + /@types/babel__traverse@7.20.1: + resolution: {integrity: sha512-MitHFXnhtgwsGZWtT68URpOvLN4EREih1u3QtQiN4VdAxWKRVvGCSvw/Qth0M0Qq3pJpnGOu5JaM/ydK7OGbqg==} + dependencies: + '@babel/types': 7.22.5 + dev: false + /@types/body-parser@1.19.2: resolution: {integrity: sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==} dependencies: @@ -3689,6 +3958,48 @@ packages: '@types/node': 18.16.15 dev: false + /@types/d3-array@3.0.5: + resolution: {integrity: sha512-Qk7fpJ6qFp+26VeQ47WY0mkwXaiq8+76RJcncDEfMc2ocRzXLO67bLFRNI4OX1aGBoPzsM5Y2T+/m1pldOgD+A==} + dev: false + + /@types/d3-color@3.1.0: + resolution: {integrity: sha512-HKuicPHJuvPgCD+np6Se9MQvS6OCbJmOjGvylzMJRlDwUXjKTTXs6Pwgk79O09Vj/ho3u1ofXnhFOaEWWPrlwA==} + dev: false + + /@types/d3-ease@3.0.0: + resolution: {integrity: sha512-aMo4eaAOijJjA6uU+GIeW018dvy9+oH5Y2VPPzjjfxevvGQ/oRDs+tfYC9b50Q4BygRR8yE2QCLsrT0WtAVseA==} + dev: false + + /@types/d3-interpolate@3.0.1: + resolution: {integrity: sha512-jx5leotSeac3jr0RePOH1KdR9rISG91QIE4Q2PYTu4OymLTZfA3SrnURSLzKH48HmXVUru50b8nje4E79oQSQw==} + dependencies: + '@types/d3-color': 3.1.0 + dev: false + + /@types/d3-path@3.0.0: + resolution: {integrity: sha512-0g/A+mZXgFkQxN3HniRDbXMN79K3CdTpLsevj+PXiTcb2hVyvkZUBg37StmgCQkaD84cUJ4uaDAWq7UJOQy2Tg==} + dev: false + + /@types/d3-scale@4.0.3: + resolution: {integrity: sha512-PATBiMCpvHJSMtZAMEhc2WyL+hnzarKzI6wAHYjhsonjWJYGq5BXTzQjv4l8m2jO183/4wZ90rKvSeT7o72xNQ==} + dependencies: + '@types/d3-time': 3.0.0 + dev: false + + /@types/d3-shape@3.1.1: + resolution: {integrity: sha512-6Uh86YFF7LGg4PQkuO2oG6EMBRLuW9cbavUW46zkIO5kuS2PfTqo2o9SkgtQzguBHbLgNnU90UNsITpsX1My+A==} + dependencies: + '@types/d3-path': 3.0.0 + dev: false + + /@types/d3-time@3.0.0: + resolution: {integrity: sha512-sZLCdHvBUcNby1cB6Fd3ZBrABbjz3v1Vm90nysCQ6Vt7vd6e/h9Lt7SiJUoEX0l4Dzc7P5llKyhqSi1ycSf1Hg==} + dev: false + + /@types/d3-timer@3.0.0: + resolution: {integrity: sha512-HNB/9GHqu7Fo8AQiugyJbv6ZxYz58wef0esl4Mv828w1ZKpAshw/uFWVDUcIB9KKFeFKoxS3cHY07FFgtTRZ1g==} + dev: false + /@types/debug@4.1.8: resolution: {integrity: sha512-/vPO1EPOs306Cvhwv7KfVfYvOJqA/S/AXjaHQiJboCZzcNDb+TIJFN9/2C9DZ//ijSKWioNyUxD792QmDJ+HKQ==} dependencies: @@ -4648,7 +4959,6 @@ packages: /any-promise@1.3.0: resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} - dev: true /anymatch@3.1.3: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} @@ -5254,7 +5564,6 @@ packages: /commander@4.1.1: resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} engines: {node: '>= 6'} - dev: true /commander@5.1.0: resolution: {integrity: sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==} @@ -5415,6 +5724,10 @@ packages: postcss-value-parser: 4.2.0 dev: false + /css-unit-converter@1.1.2: + resolution: {integrity: sha512-IiJwMC8rdZE0+xiEZHeru6YoONC4rfPMqGm2W85jMIbkFvv5nFTwJVFHam2eFrN6txmoUYFAFXiv8ICVeTO0MA==} + dev: false + /css-what@6.1.0: resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} engines: {node: '>= 6'} @@ -5451,6 +5764,77 @@ packages: resolution: {integrity: sha512-0sVXIohTfLqVIW3kb/0n6IiWF3Ifj5nm2XaSrLq2DI6fKIGa2fYAZdk917rUneaeLVpYfFcyXE2ft0fe3remsA==} dev: false + /d3-array@3.2.4: + resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==} + engines: {node: '>=12'} + dependencies: + internmap: 2.0.3 + dev: false + + /d3-color@3.1.0: + resolution: {integrity: sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==} + engines: {node: '>=12'} + dev: false + + /d3-ease@3.0.1: + resolution: {integrity: sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==} + engines: {node: '>=12'} + dev: false + + /d3-format@3.1.0: + resolution: {integrity: sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==} + engines: {node: '>=12'} + dev: false + + /d3-interpolate@3.0.1: + resolution: {integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==} + engines: {node: '>=12'} + dependencies: + d3-color: 3.1.0 + dev: false + + /d3-path@3.1.0: + resolution: {integrity: sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==} + engines: {node: '>=12'} + dev: false + + /d3-scale@4.0.2: + resolution: {integrity: sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==} + engines: {node: '>=12'} + dependencies: + d3-array: 3.2.4 + d3-format: 3.1.0 + d3-interpolate: 3.0.1 + d3-time: 3.1.0 + d3-time-format: 4.1.0 + dev: false + + /d3-shape@3.2.0: + resolution: {integrity: sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==} + engines: {node: '>=12'} + dependencies: + d3-path: 3.1.0 + dev: false + + /d3-time-format@4.1.0: + resolution: {integrity: sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==} + engines: {node: '>=12'} + dependencies: + d3-time: 3.1.0 + dev: false + + /d3-time@3.1.0: + resolution: {integrity: sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==} + engines: {node: '>=12'} + dependencies: + d3-array: 3.2.4 + dev: false + + /d3-timer@3.0.1: + resolution: {integrity: sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==} + engines: {node: '>=12'} + dev: false + /d@1.0.1: resolution: {integrity: sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==} dependencies: @@ -5532,6 +5916,10 @@ packages: ms: 2.1.2 supports-color: 5.5.0 + /decimal.js-light@2.5.1: + resolution: {integrity: sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==} + dev: false + /decimal.js@10.4.3: resolution: {integrity: sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==} dev: false @@ -5726,6 +6114,19 @@ packages: dependencies: esutils: 2.0.3 + /dom-helpers@3.4.0: + resolution: {integrity: sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA==} + dependencies: + '@babel/runtime': 7.22.5 + dev: false + + /dom-helpers@5.2.1: + resolution: {integrity: sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==} + dependencies: + '@babel/runtime': 7.22.5 + csstype: 3.1.2 + dev: false + /dom-serializer@2.0.0: resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} dependencies: @@ -6840,6 +7241,10 @@ packages: resolution: {integrity: sha512-4IJSItgS/41IxN5UVAVuAyczwZF7ZIEsM1XAoUzIHA6A+xzusEZUutdXz2Nr+MQPLxfTiCvqE79/C8HT8fKFvA==} dev: false + /eventemitter3@4.0.7: + resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} + dev: false + /events@3.3.0: resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} engines: {node: '>=0.8.x'} @@ -6921,6 +7326,11 @@ packages: resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} dev: true + /fast-equals@5.0.1: + resolution: {integrity: sha512-WF1Wi8PwwSY7/6Kx0vKXtw8RwuSGoM1bvDaJbu7MxDlR1vovZjIAKrnzyrThgAjm6JDTu0fVgWXDlMGspodfoQ==} + engines: {node: '>=6.0.0'} + dev: false + /fast-folder-size@1.6.1: resolution: {integrity: sha512-F3tRpfkAzb7TT2JNKaJUglyuRjRa+jelQD94s9OSqkfEeytLmupCqQiD+H2KoIXGtp4pB5m4zNmv5m2Ktcr+LA==} hasBin: true @@ -6962,6 +7372,13 @@ packages: dependencies: flat-cache: 3.0.4 + /file-system-cache@2.3.0: + resolution: {integrity: sha512-l4DMNdsIPsVnKrgEXbJwDJsA5mB8rGwHYERMgqQx/xAUtChPJMre1bXBzDEqqVbWv9AIbFezXMxeEkZDSrXUOQ==} + dependencies: + fs-extra: 11.1.1 + ramda: 0.29.0 + dev: false + /file-uri-to-path@1.0.0: resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} dev: false @@ -7098,6 +7515,15 @@ packages: universalify: 2.0.0 dev: false + /fs-extra@11.1.1: + resolution: {integrity: sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==} + engines: {node: '>=14.14'} + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.0 + dev: false + /fs-extra@8.1.0: resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} engines: {node: '>=6 <7 || >=8'} @@ -7267,7 +7693,6 @@ packages: minimatch: 3.1.2 once: 1.4.0 path-is-absolute: 1.0.1 - dev: true /glob@7.1.7: resolution: {integrity: sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==} @@ -7668,6 +8093,11 @@ packages: has: 1.0.3 side-channel: 1.0.4 + /internmap@2.0.3: + resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==} + engines: {node: '>=12'} + dev: false + /interpret@1.4.0: resolution: {integrity: sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==} engines: {node: '>= 0.10'} @@ -8013,7 +8443,6 @@ packages: /jiti@1.18.2: resolution: {integrity: sha512-QAdOptna2NYiSSpv0O/BwoHBSmz4YhpzJHyi+fnMRTXFjp7B8i/YG5Z8IfusxB1ufjcD2Sre1F3R+nX3fvy7gg==} hasBin: true - dev: true /jju@1.4.0: resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==} @@ -8377,6 +8806,10 @@ packages: engines: {node: '>=8'} dev: false + /map-or-similar@1.5.0: + resolution: {integrity: sha512-0aF7ZmVon1igznGI4VS30yugpduQW3y3GkcgGJOp7d8x8QrizhigUxjI/m2UojsXXto+jLAH3KSz+xOJTiORjg==} + dev: false + /markdown-extensions@1.1.1: resolution: {integrity: sha512-WWC0ZuMzCyDHYCasEGs4IPvLyTGftYwh6wIEOULOF0HXcqZlhwRzrK0w2VUlxWA98xnvb/jszw4ZSkJ6ADpM6Q==} engines: {node: '>=0.10.0'} @@ -8600,6 +9033,12 @@ packages: timers-ext: 0.1.7 dev: true + /memoizerific@1.11.3: + resolution: {integrity: sha512-/EuHYwAPdLtXwAwSZkh/Gutery6pD2KYd44oQLhAvQp/50mpyduZh8Q7PYHXTCJ+wuXxt7oij2LXyIJOOYFPog==} + dependencies: + map-or-similar: 1.5.0 + dev: false + /mendoza@2.1.1: resolution: {integrity: sha512-8f3Se8HDfobXCsdESXZBSSYcVzIRi+cMIEmz/SR4bjgFEjHJaXzrsBYr+vyrFGEtK5xTpCcU+DiwxWJV6hCuhQ==} engines: {node: '>=10'} @@ -9075,7 +9514,6 @@ packages: any-promise: 1.3.0 object-assign: 4.1.1 thenify-all: 1.6.0 - dev: true /nano-pubsub@2.0.1: resolution: {integrity: sha512-RWgGP2TdeKZLx+guR5a7/BzYs85sj6yrXXyj0o/znbgzPlz/Ez9wQuKDpwUZ8q+u2RxXpqZ1iTkPXCIU+GHhpA==} @@ -9686,7 +10124,6 @@ packages: postcss-value-parser: 4.2.0 read-cache: 1.0.0 resolve: 1.22.2 - dev: true /postcss-js@4.0.1(postcss@8.4.21): resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==} @@ -9706,7 +10143,6 @@ packages: dependencies: camelcase-css: 2.0.1 postcss: 8.4.24 - dev: true /postcss-load-config@3.1.4(postcss@8.4.21): resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==} @@ -9740,7 +10176,6 @@ packages: lilconfig: 2.1.0 postcss: 8.4.24 yaml: 2.3.1 - dev: true /postcss-nested@6.0.0(postcss@8.4.21): resolution: {integrity: sha512-0DkamqrPcmkBDsLn+vQDIrtkSbNkv5AD/M322ySo9kqFkCIYklym2xEmWkwo+Y3/qZo34tzEPNUw4y7yMCdv5w==} @@ -9760,7 +10195,6 @@ packages: dependencies: postcss: 8.4.24 postcss-selector-parser: 6.0.13 - dev: true /postcss-selector-parser@6.0.10: resolution: {integrity: sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==} @@ -9777,6 +10211,10 @@ packages: cssesc: 3.0.0 util-deprecate: 1.0.2 + /postcss-value-parser@3.3.1: + resolution: {integrity: sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==} + dev: false + /postcss-value-parser@4.2.0: resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} @@ -10011,6 +10449,13 @@ packages: engines: {node: '>=6.0.0'} dev: false + /qs@6.11.2: + resolution: {integrity: sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==} + engines: {node: '>=0.6'} + dependencies: + side-channel: 1.0.4 + dev: false + /querystringify@2.2.0: resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} dev: false @@ -10034,6 +10479,10 @@ packages: performance-now: 2.1.0 dev: false + /ramda@0.29.0: + resolution: {integrity: sha512-BBea6L67bYLtdbOqfp8f58fPMqEwx0doL+pAi8TZyp2YWz8R9G8z9x75CZI8W+ftqhFHCpEX2cRnUUXK130iKA==} + dev: false + /randombytes@2.1.0: resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} dependencies: @@ -10059,6 +10508,16 @@ packages: react: 18.2.0 dev: false + /react-day-picker@8.7.1(date-fns@2.30.0)(react@18.2.0): + resolution: {integrity: sha512-Gv426AW8b151CZfh3aP5RUGztLwHB/EyJgWZ5iMgtzbFBkjHfG6Y66CIQFMWGLnYjsQ9DYSJRmJ5S0Pg5HWKjA==} + peerDependencies: + date-fns: ^2.28.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + dependencies: + date-fns: 2.30.0 + react: 18.2.0 + dev: false + /react-dom@18.2.0(react@18.2.0): resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==} peerDependencies: @@ -10243,6 +10702,17 @@ packages: use-sidecar: 1.1.2(@types/react@18.2.7)(react@18.2.0) dev: false + /react-resize-detector@8.1.0(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-S7szxlaIuiy5UqLhLL1KY3aoyGHbZzsTpYal9eYMwCyKqoqoVLCmIgAgNyIM1FhnP2KyBygASJxdhejrzjMb+w==} + peerDependencies: + react: ^16.0.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0 + dependencies: + lodash: 4.17.21 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + /react-rewards@2.0.4(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-Lw7gIhD8yPDzC6boaVmcXwuTHRLSLAdqB3kZc+29YWvdHWsuc3fdAZlxI8Cm8fvD8fhP+3JkZBtzX224czw15w==} peerDependencies: @@ -10265,6 +10735,20 @@ packages: use-sync-external-store: 1.2.0(react@18.2.0) dev: false + /react-smooth@2.0.3(prop-types@15.8.1)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-yl4y3XiMorss7ayF5QnBiSprig0+qFHui8uh7Hgg46QX5O+aRMRKlfGGNGLHno35JkQSvSYY8eCWkBfHfrSHfg==} + peerDependencies: + prop-types: ^15.6.0 + react: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 + react-dom: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 + dependencies: + fast-equals: 5.0.1 + prop-types: 15.8.1 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-transition-group: 2.9.0(react-dom@18.2.0)(react@18.2.0) + dev: false + /react-style-proptype@3.2.2: resolution: {integrity: sha512-ywYLSjNkxKHiZOqNlso9PZByNEY+FTyh3C+7uuziK0xFXu9xzdyfHwg4S9iyiRRoPCR4k2LqaBBsWVmSBwCWYQ==} dependencies: @@ -10315,6 +10799,34 @@ packages: - '@types/react' dev: false + /react-transition-group@2.9.0(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg==} + peerDependencies: + react: '>=15.0.0' + react-dom: '>=15.0.0' + dependencies: + dom-helpers: 3.4.0 + loose-envify: 1.4.0 + prop-types: 15.8.1 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-lifecycles-compat: 3.0.4 + dev: false + + /react-transition-group@4.4.5(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==} + peerDependencies: + react: '>=16.6.0' + react-dom: '>=16.6.0' + dependencies: + '@babel/runtime': 7.22.5 + dom-helpers: 5.2.1 + loose-envify: 1.4.0 + prop-types: 15.8.1 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + /react-tweet@2.0.1(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-r8Yrv+cW8ajpCcT2AJCIji9crbbVxiaYSagqU4IW4Btsm3b3Ui65pFOV9gZmnt2xorn8L98kqj8REEuGxwnaeA==} peerDependencies: @@ -10424,6 +10936,35 @@ packages: resolution: {integrity: sha512-onYyVhBNr4CmAxFsKS7bz+uTLRakypIe4R+5A824vBSkQy/hB3fZepoVEf8OVAxzLvK+H/jm9TzpI3ETSm64Kg==} dev: false + /recharts-scale@0.4.5: + resolution: {integrity: sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w==} + dependencies: + decimal.js-light: 2.5.1 + dev: false + + /recharts@2.7.0-alpha.0(prop-types@15.8.1)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-eEJBzRaHe5U2dKXT3ZQrI0C69R+XxU5EGJJQ3xiDn2JYPbleBlwCjRnRe31/tet0gSotpBUrzG/B/z1d1hKdnA==} + engines: {node: '>=12'} + peerDependencies: + prop-types: ^15.6.0 + react: ^16.0.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0 + dependencies: + '@storybook/addon-storysource': 7.0.20(react-dom@18.2.0)(react@18.2.0) + classnames: 2.3.2 + eventemitter3: 4.0.7 + lodash: 4.17.21 + prop-types: 15.8.1 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-is: 16.13.1 + react-resize-detector: 8.1.0(react-dom@18.2.0)(react@18.2.0) + react-smooth: 2.0.3(prop-types@15.8.1)(react-dom@18.2.0)(react@18.2.0) + recharts-scale: 0.4.5 + reduce-css-calc: 2.1.8 + victory-vendor: 36.6.10 + dev: false + /rechoir@0.6.2: resolution: {integrity: sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==} engines: {node: '>= 0.10'} @@ -10431,6 +10972,13 @@ packages: resolve: 1.22.2 dev: false + /reduce-css-calc@2.1.8: + resolution: {integrity: sha512-8liAVezDmUcH+tdzoEGrhfbGcP7nOV4NkGE3a74+qqvE7nt9i4sKLGBuZNOnpI4WiGksiNPklZxva80061QiPg==} + dependencies: + css-unit-converter: 1.1.2 + postcss-value-parser: 3.3.1 + dev: false + /refractor@3.6.0: resolution: {integrity: sha512-MY9W41IOWxxk31o+YvFCNyNzdkc9M20NoZK5vq6jkv4I/uh2zkWcfudj0Q1fovjUQJrNewS9NMzeTtqPf+n5EA==} dependencies: @@ -11047,6 +11595,10 @@ packages: dependencies: internal-slot: 1.0.5 + /store2@2.14.2: + resolution: {integrity: sha512-siT1RiqlfQnGqgT/YzXVUNsom9S0H1OX+dpdGN1xkyYATo4I6sep5NmsRD/40s3IIOvlCq6akxkqG82urIZW1w==} + dev: false + /stream-each@1.2.3: resolution: {integrity: sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==} dependencies: @@ -11224,7 +11776,6 @@ packages: mz: 2.7.0 pirates: 4.0.5 ts-interface-checker: 0.1.13 - dev: true /supports-color@5.5.0: resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} @@ -11278,6 +11829,10 @@ packages: resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} dev: false + /synchronous-promise@2.0.17: + resolution: {integrity: sha512-AsS729u2RHUfEra9xJrE39peJcc2stq2+poBXX8bcM08Y6g9j/i/PUzwNQqkaJde7Ntg1TO7bSREbR5sdosQ+g==} + dev: false + /synckit@0.8.5: resolution: {integrity: sha512-L1dapNV6vu2s/4Sputv8xGsCdAVlb5nRDMFU/E27D44l5U6cw1g0dGd45uLc+OXjNMmF4ntiMdCimzcjFKQI8Q==} engines: {node: ^14.18.0 || >=16.0.0} @@ -11285,6 +11840,10 @@ packages: '@pkgr/utils': 2.4.1 tslib: 2.5.2 + /tabbable@6.1.2: + resolution: {integrity: sha512-qCN98uP7i9z0fIS4amQ5zbGBOq+OSigYeGvPy7NDk8Y9yncqDZ9pRPgfsc2PJIVM9RrJj7GIfuRgmjoUU9zTHQ==} + dev: false + /tailwind-merge@1.12.0: resolution: {integrity: sha512-Y17eDp7FtN1+JJ4OY0Bqv9OA41O+MS8c1Iyr3T6JFLnOgLg3EvcyMKZAnQ8AGyvB5Nxm3t9Xb5Mhe139m8QT/g==} dev: false @@ -11353,7 +11912,6 @@ packages: sucrase: 3.32.0 transitivePeerDependencies: - ts-node - dev: true /tapable@2.2.1: resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} @@ -11379,6 +11937,12 @@ packages: readable-stream: 3.6.2 dev: false + /telejson@7.1.0: + resolution: {integrity: sha512-jFJO4P5gPebZAERPkJsqMAQ0IMA1Hi0AoSfxpnUaV6j6R2SZqlpkbS20U6dEUtA3RUYt2Ak/mTlkQzHH9Rv/hA==} + dependencies: + memoizerific: 1.11.3 + dev: false + /terser-webpack-plugin@5.3.9(esbuild@0.16.17)(webpack@5.86.0): resolution: {integrity: sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==} engines: {node: '>= 10.13.0'} @@ -11423,13 +11987,11 @@ packages: engines: {node: '>=0.8'} dependencies: thenify: 3.3.1 - dev: true /thenify@3.3.1: resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} dependencies: any-promise: 1.3.0 - dev: true /throttle-debounce@5.0.0: resolution: {integrity: sha512-2iQTSgkkc1Zyk0MeVrt/3BvuOXYPl/R8Z0U2xxo9rjwNciaHDG3R+Lm6dh4EeUci49DanvBnuqI6jshoQQRGEg==} @@ -11550,9 +12112,13 @@ packages: resolution: {integrity: sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g==} dev: false + /ts-dedent@2.2.0: + resolution: {integrity: sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==} + engines: {node: '>=6.10'} + dev: false + /ts-interface-checker@0.1.13: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} - dev: true /tsconfig-paths@3.14.2: resolution: {integrity: sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==} @@ -11975,6 +12541,17 @@ packages: use-isomorphic-layout-effect: 1.1.2(@types/react@18.2.7)(react@18.2.0) dev: false + /use-resize-observer@9.1.0(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-R25VqO9Wb3asSD4eqtcxk8sJalvIOYBqS8MNZlpDSQ4l4xMQxC/J7Id9HoTqPq8FwULIn0PVW+OAqF2dyYbjow==} + peerDependencies: + react: 16.8.0 - 18 + react-dom: 16.8.0 - 18 + dependencies: + '@juggle/resize-observer': 3.4.0 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + /use-sidecar@1.1.2(@types/react@18.2.7)(react@18.2.0): resolution: {integrity: sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==} engines: {node: '>=10'} @@ -12055,6 +12632,25 @@ packages: vfile-message: 3.1.4 dev: false + /victory-vendor@36.6.10: + resolution: {integrity: sha512-7YqYGtsA4mByokBhCjk+ewwPhUfzhR1I3Da6/ZsZUv/31ceT77RKoaqrxRq5Ki+9we4uzf7+A+7aG2sfYhm7nA==} + dependencies: + '@types/d3-array': 3.0.5 + '@types/d3-ease': 3.0.0 + '@types/d3-interpolate': 3.0.1 + '@types/d3-scale': 4.0.3 + '@types/d3-shape': 3.1.1 + '@types/d3-time': 3.0.0 + '@types/d3-timer': 3.0.0 + d3-array: 3.2.4 + d3-ease: 3.0.1 + d3-interpolate: 3.0.1 + d3-scale: 4.0.2 + d3-shape: 3.2.0 + d3-time: 3.1.0 + d3-timer: 3.0.1 + dev: false + /vite@4.3.9(@types/node@18.16.15): resolution: {integrity: sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg==} engines: {node: ^14.18.0 || >=16.0.0} @@ -12340,7 +12936,6 @@ packages: /yaml@2.3.1: resolution: {integrity: sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==} engines: {node: '>= 14'} - dev: true /yargs-parser@21.1.1: resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} diff --git a/tailwind.config.cjs b/tailwind.config.cjs index 0d04b933..5fb565f3 100644 --- a/tailwind.config.cjs +++ b/tailwind.config.cjs @@ -7,8 +7,11 @@ module.exports = { content: [ './app/**/*.tsx', './components/**/*.tsx', + './node_modules/@tremor/**/*.{js,ts,jsx,tsx}', // Tremor module ], theme: { + transparent: "transparent", + current: "currentColor", fontSize: { xs: ['0.8125rem', { lineHeight: '1.5rem' }], sm: ['0.875rem', { lineHeight: '1.5rem' }], @@ -304,6 +307,66 @@ module.exports = { primary: { 900: '#000212', }, + // light mode + tremor: { + brand: { + faint: "#eff6ff", // blue-50 + muted: "#bfdbfe", // blue-200 + subtle: "#60a5fa", // blue-400 + DEFAULT: "#3b82f6", // blue-500 + emphasis: "#1d4ed8", // blue-700 + inverted: "#ffffff", // white + }, + background: { + muted: "#f9fafb", // gray-50 + subtle: "#f3f4f6", // gray-100 + DEFAULT: "#ffffff", // white + emphasis: "#374151", // gray-700 + }, + border: { + DEFAULT: "#e5e7eb", // gray-200 + }, + ring: { + DEFAULT: "#e5e7eb", // gray-200 + }, + content: { + subtle: "#9ca3af", // gray-400 + DEFAULT: "#6b7280", // gray-500 + emphasis: "#374151", // gray-700 + strong: "#111827", // gray-900 + inverted: "#ffffff", // white + }, + }, + // dark mode + "dark-tremor": { + brand: { + faint: "#0B1229", // custom + muted: "#172554", // blue-950 + subtle: "#1e40af", // blue-800 + DEFAULT: "#3b82f6", // blue-500 + emphasis: "#60a5fa", // blue-400 + inverted: "#030712", // gray-950 + }, + background: { + muted: "#131A2B", // custom + subtle: "#1f2937", // gray-800 + DEFAULT: "#111827", // gray-900 + emphasis: "#d1d5db", // gray-300 + }, + border: { + DEFAULT: "#1f2937", // gray-800 + }, + ring: { + DEFAULT: "#1f2937", // gray-800 + }, + content: { + subtle: "#4b5563", // gray-600 + DEFAULT: "#6b7280", // gray-600 + emphasis: "#e5e7eb", // gray-200 + strong: "#f9fafb", // gray-50 + inverted: "#000000", // black + }, + }, }, fontFamily: { @@ -312,8 +375,61 @@ module.exports = { animation: { 'typing': 'typing-pulse 1.35s steps(1, end) infinite', - } + }, + + boxShadow: { + // light + "tremor-input": "0 1px 2px 0 rgb(0 0 0 / 0.05)", + "tremor-card": "0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)", + "tremor-dropdown": "0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)", + // dark + "dark-tremor-input": "0 1px 2px 0 rgb(0 0 0 / 0.05)", + "dark-tremor-card": "0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)", + "dark-tremor-dropdown": "0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)", + }, + + borderRadius: { + "tremor-small": "0.375rem", + "tremor-default": "0.5rem", + "tremor-full": "9999px", + }, + + fontSize: { + "tremor-label": ["0.75rem"], + "tremor-default": ["0.875rem", { lineHeight: "1.25rem" }], + "tremor-title": ["1.125rem", { lineHeight: "1.75rem" }], + "tremor-metric": ["1.875rem", { lineHeight: "2.25rem" }], + }, }, }, - plugins: [require('@tailwindcss/typography')], + safelist: [ + { + pattern: + /^(bg-(?:slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-(?:50|100|200|300|400|500|600|700|800|900|950))$/, + variants: ["hover", "ui-selected"], + }, + { + pattern: + /^(text-(?:slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-(?:50|100|200|300|400|500|600|700|800|900|950))$/, + variants: ["hover", "ui-selected"], + }, + { + pattern: + /^(border-(?:slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-(?:50|100|200|300|400|500|600|700|800|900|950))$/, + variants: ["hover", "ui-selected"], + }, + { + pattern: + /^(ring-(?:slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-(?:50|100|200|300|400|500|600|700|800|900|950))$/, + }, + { + pattern: + /^(stroke-(?:slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-(?:50|100|200|300|400|500|600|700|800|900|950))$/, + }, + { + pattern: + /^(fill-(?:slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-(?:50|100|200|300|400|500|600|700|800|900|950))$/, + }, + ], + plugins: [require('@tailwindcss/typography'), require("@headlessui/tailwindcss")], }