diff --git a/apps/recnet/src/app/admin/stats/StatBox.tsx b/apps/recnet/src/app/admin/stats/StatBox.tsx index 24d4dc78..c3a76a5d 100644 --- a/apps/recnet/src/app/admin/stats/StatBox.tsx +++ b/apps/recnet/src/app/admin/stats/StatBox.tsx @@ -23,12 +23,13 @@ export function StatBox({ "p-6", "gap-y-3", "w-fit", + "relative", className )} >
{icon} diff --git a/apps/recnet/src/app/admin/stats/user-rec/RecsCycleBarChart.tsx b/apps/recnet/src/app/admin/stats/user-rec/RecsCycleBarChart.tsx index 7685af52..fd490c4e 100644 --- a/apps/recnet/src/app/admin/stats/user-rec/RecsCycleBarChart.tsx +++ b/apps/recnet/src/app/admin/stats/user-rec/RecsCycleBarChart.tsx @@ -6,6 +6,10 @@ import { ParentSize } from "@visx/responsive"; import { Bar } from "@visx/shape"; import { Group } from "@visx/group"; import { AxisBottom } from "@visx/axis"; +import { useTooltip, useTooltipInPortal, defaultStyles } from "@visx/tooltip"; +import { localPoint } from "@visx/event"; +import { WeekTs, formatDate } from "@/utils/date"; +import { Text } from "@radix-ui/themes"; type Timestamp = string; @@ -15,17 +19,45 @@ interface RecsCycleBarChartProps { data: Record; } +interface TooltipData { + ts: number; + count: number; +} + const themeColor = "#2A78D0"; +const tooltipStyles = { + ...defaultStyles, + minWidth: 60, + backgroundColor: "black", + color: "white", +}; +let tooltipTimeout: number; function BarChart(props: RecsCycleBarChartProps) { const { parentWidth, parentHeight, data } = props; + const { + tooltipOpen, + tooltipLeft, + tooltipTop, + tooltipData, + hideTooltip, + showTooltip, + } = useTooltip(); + + const { containerRef, TooltipInPortal } = useTooltipInPortal({ + // TooltipInPortal is rendered in a separate child of and positioned + // with page coordinates which should be updated on scroll. consider using + // Tooltip or TooltipWithBounds if you don't need to render inside a Portal + scroll: true, + }); + // data + const timestamps = Object.keys(data).map((key) => parseInt(key, 10)); + // bounds const margin = { top: 40, right: 0, bottom: 40, left: 0 }; const xMax = parentWidth; const yMax = parentHeight - margin.top - margin.bottom; - - // data - const timestamps = Object.keys(data).map((key) => parseInt(key, 10)); + const barWidth = parentWidth / timestamps.length - 5; const xScale = useMemo(() => { return scaleUtc({ @@ -45,52 +77,85 @@ function BarChart(props: RecsCycleBarChartProps) { }, [yMax, data]); return ( - - - {Object.keys(data) - .map((key) => { - const ts = parseInt(key, 10); - return { - ts, - count: data[key], - }; - }) - .map((d) => { - const barWidth = 20; - const barHeight = yMax - (yScale(d.count) ?? 0); - const barX = xScale(new Date(d.ts)); - const barY = yMax - barHeight; - return ( - {}} - /> - ); - })} - - { - if (d instanceof Date) { - return xScale.tickFormat(undefined, "%b %d")(d); - } - return ""; - }} - stroke={themeColor} - tickStroke={themeColor} - tickLabelProps={{ - fill: themeColor, - fontSize: 9, - textAnchor: "middle", - }} - /> - + <> + + + {Object.keys(data) + .map((key) => { + const ts = parseInt(key, 10); + return { + ts, + count: data[key], + }; + }) + .map((d) => { + const barHeight = yMax - (yScale(d.count) ?? 0); + const barX = xScale(new Date(d.ts)); + const barY = yMax - barHeight; + return ( + {}} + onMouseLeave={() => { + tooltipTimeout = window.setTimeout(() => { + hideTooltip(); + }, 300); + }} + onMouseMove={(event) => { + if (tooltipTimeout) clearTimeout(tooltipTimeout); + // TooltipInPortal expects coordinates to be relative to containerRef + // localPoint returns coordinates relative to the nearest SVG, which + // is what containerRef is set to. + const eventSvgCoords = localPoint(event); + const left = barX + barWidth / 2; + showTooltip({ + tooltipData: { + ts: d.ts, + count: d.count, + }, + tooltipTop: eventSvgCoords?.y, + tooltipLeft: left, + }); + }} + /> + ); + })} + + { + if (d instanceof Date) { + return xScale.tickFormat(undefined, "%b %d")(d); + } + return ""; + }} + stroke={themeColor} + tickStroke={themeColor} + tickLabelProps={{ + fill: themeColor, + fontSize: 9, + textAnchor: "middle", + }} + /> + + {tooltipData && tooltipOpen ? ( + + {`${formatDate(new Date(tooltipData.ts - WeekTs))} ~ ${formatDate(new Date(tooltipData.ts))}`} +
Num of Rec: {tooltipData.count}
+
+ ) : null} + ); } diff --git a/apps/recnet/src/app/admin/stats/user-rec/page.tsx b/apps/recnet/src/app/admin/stats/user-rec/page.tsx index 954b3e7a..81c3379d 100644 --- a/apps/recnet/src/app/admin/stats/user-rec/page.tsx +++ b/apps/recnet/src/app/admin/stats/user-rec/page.tsx @@ -1,7 +1,7 @@ import { db } from "@/firebase/admin"; import { StatBox, StatBoxSkeleton } from "@/app/admin/stats/StatBox"; import { Pencil1Icon, PersonIcon } from "@radix-ui/react-icons"; -import { getDateFromFirebaseTimestamp, getLatestCutOff } from "@/utils/date"; +import { getDateFromFirebaseTimestamp, getNextCutOff } from "@/utils/date"; import { Timestamp } from "firebase-admin/firestore"; import { withSuspense } from "@/utils/withSuspense"; import groupBy from "lodash.groupby"; @@ -37,7 +37,8 @@ const RecCount = withSuspense( const RecsThisCycle = withSuspense( async () => { - const cutOff = getLatestCutOff(); + const cutOff = getNextCutOff(); + console.log("cutOff", cutOff); const recsThisCycle = await db .collection("recommendations") .where("cutoff", "==", Timestamp.fromMillis(cutOff.getTime())) @@ -62,7 +63,7 @@ const RecsBarChart = withSuspense( if (res.success) { return res.data; } else { - console.error("Failed to parse rec", res.error); + // console.error("Failed to parse rec", res.error); return null; } }) @@ -93,9 +94,11 @@ const RecsBarChart = withSuspense( } - className="h-[300px] w-[40%] min-w-[500px]" + className="h-[300px] w-[100%] md:w-[40%] overflow-x-auto whitespace-nowrap overflow-y-hidden" > - +
+ +
); }, @@ -105,7 +108,7 @@ const RecsBarChart = withSuspense( export default async function UserRecStats() { return (
-
+
diff --git a/apps/recnet/src/utils/date.ts b/apps/recnet/src/utils/date.ts index 82df7331..e3c55120 100644 --- a/apps/recnet/src/utils/date.ts +++ b/apps/recnet/src/utils/date.ts @@ -2,6 +2,7 @@ import { FirebaseTs } from "@/types/rec"; import { Timestamp } from "firebase/firestore"; const CYCLE_DUE_DAY = 2; +export const WeekTs = 604800000 as const; export const START_DATE = new Date(2023, 9, 24); export const Months = [ "Jan", diff --git a/package.json b/package.json index f628327f..c0ee02f1 100644 --- a/package.json +++ b/package.json @@ -13,10 +13,12 @@ "@react-email/components": "0.0.14", "@react-email/render": "^0.0.12", "@visx/axis": "^3.8.0", + "@visx/event": "^3.3.0", "@visx/group": "^3.3.0", "@visx/responsive": "^3.3.0", "@visx/scale": "^3.5.0", "@visx/shape": "^3.5.0", + "@visx/tooltip": "^3.3.0", "@visx/vendor": "^3.5.0", "chance": "^1.1.11", "clsx": "^2.1.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 03b1923f..4282e97c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,9 +1,5 @@ lockfileVersion: '6.0' -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - dependencies: '@hookform/resolvers': specifier: ^3.3.4 @@ -29,6 +25,9 @@ dependencies: '@visx/axis': specifier: ^3.8.0 version: 3.8.0(react@18.2.0) + '@visx/event': + specifier: ^3.3.0 + version: 3.3.0 '@visx/group': specifier: ^3.3.0 version: 3.3.0(react@18.2.0) @@ -41,6 +40,9 @@ dependencies: '@visx/shape': specifier: ^3.5.0 version: 3.5.0(react@18.2.0) + '@visx/tooltip': + specifier: ^3.3.0 + version: 3.3.0(react-dom@18.2.0)(react@18.2.0) '@visx/vendor': specifier: ^3.5.0 version: 3.5.0 @@ -1796,7 +1798,6 @@ packages: cpu: [ppc64] os: [aix] requiresBuild: true - dev: false optional: true /@esbuild/android-arm64@0.19.11: @@ -1805,7 +1806,6 @@ packages: cpu: [arm64] os: [android] requiresBuild: true - dev: false optional: true /@esbuild/android-arm@0.19.11: @@ -1814,7 +1814,6 @@ packages: cpu: [arm] os: [android] requiresBuild: true - dev: false optional: true /@esbuild/android-x64@0.19.11: @@ -1823,7 +1822,6 @@ packages: cpu: [x64] os: [android] requiresBuild: true - dev: false optional: true /@esbuild/darwin-arm64@0.19.11: @@ -1832,7 +1830,6 @@ packages: cpu: [arm64] os: [darwin] requiresBuild: true - dev: false optional: true /@esbuild/darwin-x64@0.19.11: @@ -1841,7 +1838,6 @@ packages: cpu: [x64] os: [darwin] requiresBuild: true - dev: false optional: true /@esbuild/freebsd-arm64@0.19.11: @@ -1850,7 +1846,6 @@ packages: cpu: [arm64] os: [freebsd] requiresBuild: true - dev: false optional: true /@esbuild/freebsd-x64@0.19.11: @@ -1859,7 +1854,6 @@ packages: cpu: [x64] os: [freebsd] requiresBuild: true - dev: false optional: true /@esbuild/linux-arm64@0.19.11: @@ -1868,7 +1862,6 @@ packages: cpu: [arm64] os: [linux] requiresBuild: true - dev: false optional: true /@esbuild/linux-arm@0.19.11: @@ -1877,7 +1870,6 @@ packages: cpu: [arm] os: [linux] requiresBuild: true - dev: false optional: true /@esbuild/linux-ia32@0.19.11: @@ -1886,7 +1878,6 @@ packages: cpu: [ia32] os: [linux] requiresBuild: true - dev: false optional: true /@esbuild/linux-loong64@0.19.11: @@ -1895,7 +1886,6 @@ packages: cpu: [loong64] os: [linux] requiresBuild: true - dev: false optional: true /@esbuild/linux-mips64el@0.19.11: @@ -1904,7 +1894,6 @@ packages: cpu: [mips64el] os: [linux] requiresBuild: true - dev: false optional: true /@esbuild/linux-ppc64@0.19.11: @@ -1913,7 +1902,6 @@ packages: cpu: [ppc64] os: [linux] requiresBuild: true - dev: false optional: true /@esbuild/linux-riscv64@0.19.11: @@ -1922,7 +1910,6 @@ packages: cpu: [riscv64] os: [linux] requiresBuild: true - dev: false optional: true /@esbuild/linux-s390x@0.19.11: @@ -1931,7 +1918,6 @@ packages: cpu: [s390x] os: [linux] requiresBuild: true - dev: false optional: true /@esbuild/linux-x64@0.19.11: @@ -1940,7 +1926,6 @@ packages: cpu: [x64] os: [linux] requiresBuild: true - dev: false optional: true /@esbuild/netbsd-x64@0.19.11: @@ -1949,7 +1934,6 @@ packages: cpu: [x64] os: [netbsd] requiresBuild: true - dev: false optional: true /@esbuild/openbsd-x64@0.19.11: @@ -1958,7 +1942,6 @@ packages: cpu: [x64] os: [openbsd] requiresBuild: true - dev: false optional: true /@esbuild/sunos-x64@0.19.11: @@ -1967,7 +1950,6 @@ packages: cpu: [x64] os: [sunos] requiresBuild: true - dev: false optional: true /@esbuild/win32-arm64@0.19.11: @@ -1976,7 +1958,6 @@ packages: cpu: [arm64] os: [win32] requiresBuild: true - dev: false optional: true /@esbuild/win32-ia32@0.19.11: @@ -1985,7 +1966,6 @@ packages: cpu: [ia32] os: [win32] requiresBuild: true - dev: false optional: true /@esbuild/win32-x64@0.19.11: @@ -1994,7 +1974,6 @@ packages: cpu: [x64] os: [win32] requiresBuild: true - dev: false optional: true /@eslint-community/eslint-utils@4.4.0(eslint@8.48.0): @@ -3812,11 +3791,11 @@ packages: style-loader: 3.3.4(webpack@5.90.1) stylus: 0.59.0 stylus-loader: 7.1.3(stylus@0.59.0)(webpack@5.90.1) - terser-webpack-plugin: 5.3.10(@swc/core@1.3.85)(webpack@5.90.1) + terser-webpack-plugin: 5.3.10(@swc/core@1.3.101)(esbuild@0.19.11)(webpack@5.90.1) ts-loader: 9.5.1(typescript@5.3.3)(webpack@5.90.1) tsconfig-paths-webpack-plugin: 4.0.0 tslib: 2.6.2 - webpack: 5.90.1(@swc/core@1.3.85) + webpack: 5.90.1(@swc/core@1.3.101)(esbuild@0.19.11) webpack-dev-server: 4.15.1(webpack@5.90.1) webpack-node-externals: 3.0.0 webpack-subresource-integrity: 5.1.0(webpack@5.90.1) @@ -5721,7 +5700,6 @@ packages: cpu: [arm64] os: [darwin] requiresBuild: true - dev: false optional: true /@swc/core-darwin-arm64@1.3.85: @@ -5738,7 +5716,6 @@ packages: cpu: [x64] os: [darwin] requiresBuild: true - dev: false optional: true /@swc/core-darwin-x64@1.3.85: @@ -5755,7 +5732,6 @@ packages: cpu: [arm] os: [linux] requiresBuild: true - dev: false optional: true /@swc/core-linux-arm-gnueabihf@1.3.85: @@ -5772,7 +5748,6 @@ packages: cpu: [arm64] os: [linux] requiresBuild: true - dev: false optional: true /@swc/core-linux-arm64-gnu@1.3.85: @@ -5789,7 +5764,6 @@ packages: cpu: [arm64] os: [linux] requiresBuild: true - dev: false optional: true /@swc/core-linux-arm64-musl@1.3.85: @@ -5806,7 +5780,6 @@ packages: cpu: [x64] os: [linux] requiresBuild: true - dev: false optional: true /@swc/core-linux-x64-gnu@1.3.85: @@ -5823,7 +5796,6 @@ packages: cpu: [x64] os: [linux] requiresBuild: true - dev: false optional: true /@swc/core-linux-x64-musl@1.3.85: @@ -5840,7 +5812,6 @@ packages: cpu: [arm64] os: [win32] requiresBuild: true - dev: false optional: true /@swc/core-win32-arm64-msvc@1.3.85: @@ -5857,7 +5828,6 @@ packages: cpu: [ia32] os: [win32] requiresBuild: true - dev: false optional: true /@swc/core-win32-ia32-msvc@1.3.85: @@ -5874,7 +5844,6 @@ packages: cpu: [x64] os: [win32] requiresBuild: true - dev: false optional: true /@swc/core-win32-x64-msvc@1.3.85: @@ -5909,7 +5878,6 @@ packages: '@swc/core-win32-arm64-msvc': 1.3.101 '@swc/core-win32-ia32-msvc': 1.3.101 '@swc/core-win32-x64-msvc': 1.3.101 - dev: false /@swc/core@1.3.85(@swc/helpers@0.5.2): resolution: {integrity: sha512-qnoxp+2O0GtvRdYnXgR1v8J7iymGGYpx6f6yCK9KxipOZOjrlKILFANYlghQxZyPUfXwK++TFxfSlX4r9wK+kg==} @@ -5937,7 +5905,6 @@ packages: /@swc/counter@0.1.3: resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} - dev: false /@swc/helpers@0.5.2: resolution: {integrity: sha512-E4KcWTpoLHqwPHLxidpOqQbcrZVgi0rsmmZXUle1jXmJfuIf/UWpczUJ7MZZ5tlxytgJXyp0w4PGkkeLiuIdZw==} @@ -6625,6 +6592,19 @@ packages: react: 18.2.0 dev: false + /@visx/bounds@3.3.0(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-gESmN+4N2NkeUzqQEDZaS63umkGfMp9XjQcKBqtOR64mjjQtamh3lNVRWvKjJ2Zb421RbYHWq22Wv9nay6ZUOg==} + peerDependencies: + react: ^16.0.0-0 || ^17.0.0-0 || ^18.0.0-0 + react-dom: ^16.0.0-0 || ^17.0.0-0 || ^18.0.0-0 + dependencies: + '@types/react': 18.2.33 + '@types/react-dom': 18.2.14 + prop-types: 15.8.1 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + /@visx/curve@3.3.0: resolution: {integrity: sha512-G1l1rzGWwIs8ka3mBhO/gj8uYK6XdU/3bwRSoiZ+MockMahQFPog0bUkuVgPwwzPSJfsA/E5u53Y/DNesnHQxg==} dependencies: @@ -6632,6 +6612,13 @@ packages: d3-shape: 1.3.7 dev: false + /@visx/event@3.3.0: + resolution: {integrity: sha512-fKalbNgNz2ooVOTXhvcOx5IlEQDgVfX66rI7bgZhBxI2/scy+5rWcXJXpwkheRF68SMx9R93SjKW6tmiD0h+jA==} + dependencies: + '@types/react': 18.2.33 + '@visx/point': 3.3.0 + dev: false + /@visx/group@3.3.0(react@18.2.0): resolution: {integrity: sha512-yKepDKwJqlzvnvPS0yDuW13XNrYJE4xzT6xM7J++441nu6IybWWwextyap8ey+kU651cYDb+q1Oi6aHvQwyEyw==} peerDependencies: @@ -6699,6 +6686,21 @@ packages: reduce-css-calc: 1.3.0 dev: false + /@visx/tooltip@3.3.0(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-0ovbxnvAphEU/RVJprWHdOJT7p3YfBDpwXclXRuhIY2EkH59g8sDHatDcYwiNPeqk61jBh1KACRZxqToMuutlg==} + peerDependencies: + react: ^16.8.0-0 || ^17.0.0-0 || ^18.0.0-0 + react-dom: ^16.8.0-0 || ^17.0.0-0 || ^18.0.0-0 + dependencies: + '@types/react': 18.2.33 + '@visx/bounds': 3.3.0(react-dom@18.2.0)(react@18.2.0) + classnames: 2.5.1 + prop-types: 15.8.1 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-use-measure: 2.1.1(react-dom@18.2.0)(react@18.2.0) + dev: false + /@visx/vendor@3.5.0: resolution: {integrity: sha512-yt3SEZRVmt36+APsCISSO9eSOtzQkBjt+QRxNRzcTWuzwMAaF3PHCCSe31++kkpgY9yFoF+Gfes1TBe5NlETiQ==} dependencies: @@ -7304,7 +7306,7 @@ packages: '@babel/core': 7.23.9 find-cache-dir: 4.0.0 schema-utils: 4.2.0 - webpack: 5.90.1(@swc/core@1.3.85) + webpack: 5.90.1(@swc/core@1.3.101)(esbuild@0.19.11) dev: true /babel-plugin-const-enum@1.2.0(@babel/core@7.23.9): @@ -7972,7 +7974,7 @@ packages: normalize-path: 3.0.0 schema-utils: 4.2.0 serialize-javascript: 6.0.2 - webpack: 5.90.1(@swc/core@1.3.85) + webpack: 5.90.1(@swc/core@1.3.101)(esbuild@0.19.11) dev: true /core-js-compat@3.35.1: @@ -8108,7 +8110,7 @@ packages: postcss-modules-values: 4.0.0(postcss@8.4.35) postcss-value-parser: 4.2.0 semver: 7.6.0 - webpack: 5.90.1(@swc/core@1.3.85) + webpack: 5.90.1(@swc/core@1.3.101)(esbuild@0.19.11) dev: true /css-minimizer-webpack-plugin@5.0.1(webpack@5.90.1): @@ -8142,7 +8144,7 @@ packages: postcss: 8.4.35 schema-utils: 4.2.0 serialize-javascript: 6.0.2 - webpack: 5.90.1(@swc/core@1.3.85) + webpack: 5.90.1(@swc/core@1.3.101)(esbuild@0.19.11) dev: true /css-select@5.1.0: @@ -8384,6 +8386,10 @@ packages: whatwg-url: 11.0.0 dev: true + /debounce@1.2.1: + resolution: {integrity: sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==} + dev: false + /debounce@2.0.0: resolution: {integrity: sha512-xRetU6gL1VJbs85Mc4FoEGSjQxzpdxRyFhe3lmWFyy2EzydIcD4xzUvRJMD+NPDfMwKNhxa3PvsIOU32luIWeA==} engines: {node: '>=18'} @@ -8929,7 +8935,6 @@ packages: '@esbuild/win32-arm64': 0.19.11 '@esbuild/win32-ia32': 0.19.11 '@esbuild/win32-x64': 0.19.11 - dev: false /escalade@3.1.2: resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} @@ -9745,7 +9750,7 @@ packages: semver: 7.6.0 tapable: 2.2.1 typescript: 5.3.3 - webpack: 5.90.1(@swc/core@1.3.85) + webpack: 5.90.1(@swc/core@1.3.101)(esbuild@0.19.11) dev: true /form-data@2.5.1: @@ -11578,7 +11583,7 @@ packages: dependencies: klona: 2.0.6 less: 4.1.3 - webpack: 5.90.1(@swc/core@1.3.85) + webpack: 5.90.1(@swc/core@1.3.101)(esbuild@0.19.11) dev: true /less@4.1.3: @@ -11618,8 +11623,10 @@ packages: peerDependenciesMeta: webpack: optional: true + webpack-sources: + optional: true dependencies: - webpack: 5.90.1(@swc/core@1.3.85) + webpack: 5.90.1(@swc/core@1.3.101)(esbuild@0.19.11) webpack-sources: 3.2.3 dev: true @@ -12011,7 +12018,7 @@ packages: webpack: ^5.0.0 dependencies: schema-utils: 4.2.0 - webpack: 5.90.1(@swc/core@1.3.85) + webpack: 5.90.1(@swc/core@1.3.101)(esbuild@0.19.11) dev: true /minimalistic-assert@1.0.1: @@ -12917,7 +12924,7 @@ packages: klona: 2.0.6 postcss: 8.4.21 semver: 7.6.0 - webpack: 5.90.1(@swc/core@1.3.85) + webpack: 5.90.1(@swc/core@1.3.101)(esbuild@0.19.11) dev: true /postcss-merge-longhand@6.0.2(postcss@8.4.35): @@ -13589,6 +13596,17 @@ packages: tslib: 2.6.2 dev: false + /react-use-measure@2.1.1(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-nocZhN26cproIiIduswYpV5y5lQpSQS1y/4KuvUCjSKmw7ZWIS/+g3aFnX3WdBkyuGUtTLif3UTqnLLhbDoQig==} + peerDependencies: + react: '>=16.13' + react-dom: '>=16.13' + dependencies: + debounce: 1.2.1 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + /react@18.2.0: resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==} engines: {node: '>=0.10.0'} @@ -13918,7 +13936,7 @@ packages: klona: 2.0.6 neo-async: 2.6.2 sass: 1.70.0 - webpack: 5.90.1(@swc/core@1.3.85) + webpack: 5.90.1(@swc/core@1.3.101)(esbuild@0.19.11) dev: true /sass@1.70.0: @@ -14289,7 +14307,7 @@ packages: abab: 2.0.6 iconv-lite: 0.6.3 source-map-js: 1.0.2 - webpack: 5.90.1(@swc/core@1.3.85) + webpack: 5.90.1(@swc/core@1.3.101)(esbuild@0.19.11) dev: true /source-map-support@0.5.13: @@ -14589,7 +14607,7 @@ packages: peerDependencies: webpack: ^5.0.0 dependencies: - webpack: 5.90.1(@swc/core@1.3.85) + webpack: 5.90.1(@swc/core@1.3.101)(esbuild@0.19.11) dev: true /styled-components@6.1.8(react-dom@18.2.0)(react@18.2.0): @@ -14654,7 +14672,7 @@ packages: fast-glob: 3.3.2 normalize-path: 3.0.0 stylus: 0.59.0 - webpack: 5.90.1(@swc/core@1.3.85) + webpack: 5.90.1(@swc/core@1.3.101)(esbuild@0.19.11) dev: true /stylus@0.59.0: @@ -14888,32 +14906,6 @@ packages: serialize-javascript: 6.0.2 terser: 5.27.0 webpack: 5.90.1(@swc/core@1.3.101)(esbuild@0.19.11) - dev: false - - /terser-webpack-plugin@5.3.10(@swc/core@1.3.85)(webpack@5.90.1): - resolution: {integrity: sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==} - engines: {node: '>= 10.13.0'} - peerDependencies: - '@swc/core': '*' - esbuild: '*' - uglify-js: '*' - webpack: ^5.1.0 - peerDependenciesMeta: - '@swc/core': - optional: true - esbuild: - optional: true - uglify-js: - optional: true - dependencies: - '@jridgewell/trace-mapping': 0.3.22 - '@swc/core': 1.3.85(@swc/helpers@0.5.2) - jest-worker: 27.5.1 - schema-utils: 3.3.0 - serialize-javascript: 6.0.2 - terser: 5.27.0 - webpack: 5.90.1(@swc/core@1.3.85) - dev: true /terser@5.27.0: resolution: {integrity: sha512-bi1HRwVRskAjheeYl291n3JC4GgO/Ty4z1nVs5AAsmonJulGxpSektecnNedrwK9C7vpvVtcX3cw00VSLt7U2A==} @@ -15098,7 +15090,7 @@ packages: semver: 7.6.0 source-map: 0.7.4 typescript: 5.3.3 - webpack: 5.90.1(@swc/core@1.3.85) + webpack: 5.90.1(@swc/core@1.3.101)(esbuild@0.19.11) dev: true /ts-node@10.9.1(@swc/core@1.3.85)(@types/node@20.0.0)(typescript@5.3.3): @@ -15382,7 +15374,7 @@ packages: loader-utils: 2.0.4 mime-types: 2.1.35 schema-utils: 3.3.0 - webpack: 5.90.1(@swc/core@1.3.85) + webpack: 5.90.1(@swc/core@1.3.101)(esbuild@0.19.11) dev: true /url-parse@1.5.10: @@ -15531,7 +15523,7 @@ packages: mime-types: 2.1.35 range-parser: 1.2.1 schema-utils: 4.2.0 - webpack: 5.90.1(@swc/core@1.3.85) + webpack: 5.90.1(@swc/core@1.3.101)(esbuild@0.19.11) dev: true /webpack-dev-server@4.15.1(webpack@5.90.1): @@ -15575,7 +15567,7 @@ packages: serve-index: 1.9.1 sockjs: 0.3.24 spdy: 4.0.2 - webpack: 5.90.1(@swc/core@1.3.85) + webpack: 5.90.1(@swc/core@1.3.101)(esbuild@0.19.11) webpack-dev-middleware: 5.3.3(webpack@5.90.1) ws: 8.16.0 transitivePeerDependencies: @@ -15614,7 +15606,7 @@ packages: optional: true dependencies: typed-assert: 1.0.9 - webpack: 5.90.1(@swc/core@1.3.85) + webpack: 5.90.1(@swc/core@1.3.101)(esbuild@0.19.11) dev: true /webpack@5.90.1(@swc/core@1.3.101)(esbuild@0.19.11): @@ -15655,47 +15647,6 @@ packages: - '@swc/core' - esbuild - uglify-js - dev: false - - /webpack@5.90.1(@swc/core@1.3.85): - resolution: {integrity: sha512-SstPdlAC5IvgFnhiRok8hqJo/+ArAbNv7rhU4fnWGHNVfN59HSQFaxZDSAL3IFG2YmqxuRs+IU33milSxbPlog==} - engines: {node: '>=10.13.0'} - hasBin: true - peerDependencies: - webpack-cli: '*' - peerDependenciesMeta: - webpack-cli: - optional: true - dependencies: - '@types/eslint-scope': 3.7.7 - '@types/estree': 1.0.5 - '@webassemblyjs/ast': 1.11.6 - '@webassemblyjs/wasm-edit': 1.11.6 - '@webassemblyjs/wasm-parser': 1.11.6 - acorn: 8.11.3 - acorn-import-assertions: 1.9.0(acorn@8.11.3) - browserslist: 4.22.3 - chrome-trace-event: 1.0.3 - enhanced-resolve: 5.15.0 - es-module-lexer: 1.4.1 - eslint-scope: 5.1.1 - events: 3.3.0 - glob-to-regexp: 0.4.1 - graceful-fs: 4.2.11 - json-parse-even-better-errors: 2.3.1 - loader-runner: 4.3.0 - mime-types: 2.1.35 - neo-async: 2.6.2 - schema-utils: 3.3.0 - tapable: 2.2.1 - terser-webpack-plugin: 5.3.10(@swc/core@1.3.85)(webpack@5.90.1) - watchpack: 2.4.0 - webpack-sources: 3.2.3 - transitivePeerDependencies: - - '@swc/core' - - esbuild - - uglify-js - dev: true /websocket-driver@0.7.4: resolution: {integrity: sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==} @@ -15988,3 +15939,7 @@ packages: /zod@3.22.4: resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==} dev: false + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false