This commit is contained in:
g
2026-01-12 02:42:44 +00:00
parent 624bfa5485
commit 02ba4b0e66
7 changed files with 182 additions and 86 deletions

View File

@@ -6,6 +6,7 @@ import { Button } from "@/components/ui/button";
import Link from "next/link"; import Link from "next/link";
import { AnimatedStatsSection } from "@/components/animated-stats-section"; import { AnimatedStatsSection } from "@/components/animated-stats-section";
import { isDecember } from "@/lib/utils/christmas"; import { isDecember } from "@/lib/utils/christmas";
import { MotionWrapper } from "@/components/ui/motion-wrapper";
export const dynamic = 'force-dynamic'; export const dynamic = 'force-dynamic';
@@ -35,22 +36,20 @@ export default async function Home() {
return ( return (
<div className={`flex flex-col min-h-screen bg-black text-white ${isDec ? 'christmas-theme' : ''}`}> <div className={`flex flex-col min-h-screen bg-black text-white ${isDec ? 'christmas-theme' : ''}`}>
<div className={`absolute inset-0 bg-gradient-to-br pointer-events-none scale-100 ${ <div className={`absolute inset-0 bg-gradient-to-br pointer-events-none scale-100 ${isDec
isDec ? 'from-red-500/10 via-green-500/5 to-transparent'
? 'from-red-500/10 via-green-500/5 to-transparent' : 'from-[#D53F8C]/10 via-[#D53F8C]/3 to-transparent'
: 'from-[#D53F8C]/10 via-[#D53F8C]/3 to-transparent' }`} />
}`} />
<HomeNavbar /> <HomeNavbar />
{/* Hero Section */} {/* Hero Section */}
<section className="relative overflow-hidden"> <section className="relative overflow-hidden">
<div className="relative flex flex-col items-center px-4 py-20 md:py-32 mx-auto max-w-7xl"> <div className="relative flex flex-col items-center px-4 py-20 md:py-32 mx-auto max-w-7xl">
<div className="flex flex-col items-center text-center space-y-6 max-w-3xl"> <div className="flex flex-col items-center text-center space-y-6 max-w-3xl">
<div className={`inline-flex items-center px-4 py-2 rounded-full border mb-4 ${ <div className={`inline-flex items-center px-4 py-2 rounded-full border mb-4 ${isDec
isDec ? 'bg-red-500/10 border-red-500/20'
? 'bg-red-500/10 border-red-500/20' : 'bg-[#D53F8C]/10 border-[#D53F8C]/20'
: 'bg-[#D53F8C]/10 border-[#D53F8C]/20' }`}>
}`}>
<Sparkles className={`h-4 w-4 mr-2 ${isDec ? 'text-red-400' : 'text-[#D53F8C]'}`} /> <Sparkles className={`h-4 w-4 mr-2 ${isDec ? 'text-red-400' : 'text-[#D53F8C]'}`} />
<span className={`text-sm font-medium ${isDec ? 'text-red-400' : 'text-[#D53F8C]'}`}> <span className={`text-sm font-medium ${isDec ? 'text-red-400' : 'text-[#D53F8C]'}`}>
Secure Crypto Payments Secure Crypto Payments
@@ -60,20 +59,19 @@ export default async function Home() {
The Future of <span className={isDec ? 'text-red-400' : 'text-[#D53F8C]'}>E-commerce</span> Management The Future of <span className={isDec ? 'text-red-400' : 'text-[#D53F8C]'}>E-commerce</span> Management
</h1> </h1>
<p className="text-lg md:text-xl text-zinc-400 max-w-2xl"> <p className="text-lg md:text-xl text-zinc-400 max-w-2xl">
{isDec {isDec
? 'Spread joy this holiday season with our all-in-one platform. Secure payments, order tracking, and analytics wrapped up in one beautiful package. 🎄' ? 'Spread joy this holiday season with our all-in-one platform. Secure payments, order tracking, and analytics wrapped up in one beautiful package. 🎄'
: 'Streamline your online business with our all-in-one platform. Secure payments, order tracking, and analytics in one place.' : 'Streamline your online business with our all-in-one platform. Secure payments, order tracking, and analytics in one place.'
} }
</p> </p>
<div className="flex flex-col sm:flex-row gap-4 mt-4"> <div className="flex flex-col sm:flex-row gap-4 mt-4">
<Link href="/dashboard"> <Link href="/dashboard">
<Button <Button
size="lg" size="lg"
className={`gap-2 text-white border-0 h-12 px-8 ${ className={`gap-2 text-white border-0 h-12 px-8 ${isDec
isDec ? 'bg-gradient-to-r from-red-500 to-green-500 hover:from-red-600 hover:to-green-600'
? 'bg-gradient-to-r from-red-500 to-green-500 hover:from-red-600 hover:to-green-600' : 'bg-[#D53F8C] hover:bg-[#B83280]'
: 'bg-[#D53F8C] hover:bg-[#B83280]' }`}
}`}
> >
Get Started Get Started
<ArrowRight className="h-4 w-4" /> <ArrowRight className="h-4 w-4" />
@@ -87,56 +85,55 @@ export default async function Home() {
{/* Features Grid */} {/* Features Grid */}
<section className="relative py-20 px-4"> <section className="relative py-20 px-4">
<div className="max-w-7xl mx-auto space-y-20"> <div className="max-w-7xl mx-auto space-y-20">
<div className="grid md:grid-cols-3 gap-6"> <MotionWrapper>
{[ <div className="grid md:grid-cols-3 gap-6">
{ {[
icon: Shield, {
title: "Secure Payments", icon: Shield,
description: "Built-in cryptocurrency support with maximum privacy and security for your transactions." title: "Secure Payments",
}, description: "Built-in cryptocurrency support with maximum privacy and security for your transactions."
{ },
icon: LineChart, {
title: "Real-time Analytics", icon: LineChart,
description: "Track your business performance with detailed insights and reporting tools." title: "Real-time Analytics",
}, description: "Track your business performance with detailed insights and reporting tools."
{ },
icon: Zap, {
title: "Lightning Fast", icon: Zap,
description: "Optimized for speed with real-time updates and instant notifications." title: "Lightning Fast",
} description: "Optimized for speed with real-time updates and instant notifications."
].map((feature, i) => { }
const christmasColors = ['from-red-500/5', 'from-green-500/5', 'from-yellow-500/5']; ].map((feature, i) => {
const christmasBorders = ['border-red-500/30', 'border-green-500/30', 'border-yellow-500/30']; const christmasColors = ['from-red-500/5', 'from-green-500/5', 'from-yellow-500/5'];
const christmasIcons = ['text-red-400', 'text-green-400', 'text-yellow-400']; const christmasBorders = ['border-red-500/30', 'border-green-500/30', 'border-yellow-500/30'];
const christmasBgs = ['bg-red-500/10', 'bg-green-500/10', 'bg-yellow-500/10']; const christmasIcons = ['text-red-400', 'text-green-400', 'text-yellow-400'];
const christmasBgs = ['bg-red-500/10', 'bg-green-500/10', 'bg-yellow-500/10'];
return (
<div return (
key={i} <div
className={`group relative overflow-hidden rounded-xl bg-gradient-to-b p-6 border ${ key={i}
isDec className={`group relative overflow-hidden rounded-xl bg-gradient-to-b p-6 border transition-all duration-300 hover:scale-[1.02] hover:shadow-lg ${isDec
? `from-zinc-800/30 to-transparent ${christmasBorders[i % 3]}` ? `from-zinc-800/30 to-transparent ${christmasBorders[i % 3]}`
: 'from-zinc-800/30 to-transparent border-zinc-800' : 'from-zinc-800/30 to-transparent border-zinc-800'
}`} }`}
> >
<div <div
className={`absolute inset-0 bg-gradient-to-b to-transparent opacity-0 group-hover:opacity-100 transition-opacity ${ className={`absolute inset-0 bg-gradient-to-b to-transparent opacity-0 group-hover:opacity-100 transition-opacity ${isDec ? christmasColors[i % 3] : 'from-[#D53F8C]/5'
isDec ? christmasColors[i % 3] : 'from-[#D53F8C]/5' }`}
}`} />
/> <div className="relative">
<div className="relative"> <div className={`h-12 w-12 flex items-center justify-center rounded-lg mb-4 ${isDec ? christmasBgs[i % 3] : 'bg-[#D53F8C]/10'
<div className={`h-12 w-12 flex items-center justify-center rounded-lg mb-4 ${ }`}>
isDec ? christmasBgs[i % 3] : 'bg-[#D53F8C]/10' <feature.icon className={`h-6 w-6 ${isDec ? christmasIcons[i % 3] : 'text-[#D53F8C]'}`} />
}`}> </div>
<feature.icon className={`h-6 w-6 ${isDec ? christmasIcons[i % 3] : 'text-[#D53F8C]'}`} /> <h3 className="text-lg font-semibold text-white mb-2">{feature.title}</h3>
<p className="text-sm text-zinc-400">{feature.description}</p>
</div> </div>
<h3 className="text-lg font-semibold text-white mb-2">{feature.title}</h3>
<p className="text-sm text-zinc-400">{feature.description}</p>
</div> </div>
</div> );
); })}
})} </div>
</div> </MotionWrapper>
{/* Stats Section */} {/* Stats Section */}
<div className="relative"> <div className="relative">

View File

@@ -24,6 +24,7 @@ import {
CartesianGrid, CartesianGrid,
Tooltip, Tooltip,
ResponsiveContainer, ResponsiveContainer,
Area,
} from "recharts"; } from "recharts";
interface GrowthAnalyticsChartProps { interface GrowthAnalyticsChartProps {
@@ -195,18 +196,32 @@ export default function GrowthAnalyticsChart({
}))} }))}
margin={{ top: 5, right: 30, left: 20, bottom: 5 }} margin={{ top: 5, right: 30, left: 20, bottom: 5 }}
> >
<CartesianGrid strokeDasharray="3 3" /> <defs>
<XAxis dataKey="formattedMonth" tick={{ fontSize: 12 }} /> <linearGradient id="colorRevenueGrowth" x1="0" y1="0" x2="0" y2="1">
<YAxis yAxisId="left" tick={{ fontSize: 12 }} /> <stop offset="5%" stopColor="#10b981" stopOpacity={0.8} />
<stop offset="95%" stopColor="#10b981" stopOpacity={0} />
</linearGradient>
</defs>
<CartesianGrid strokeDasharray="3 3" vertical={false} stroke="hsl(var(--border))" />
<XAxis
dataKey="formattedMonth"
tick={{ fontSize: 12, fill: "hsl(var(--muted-foreground))" }}
axisLine={false}
tickLine={false}
/>
<YAxis yAxisId="left" tick={{ fontSize: 12, fill: "hsl(var(--muted-foreground))" }} axisLine={false} tickLine={false} />
<YAxis <YAxis
yAxisId="right" yAxisId="right"
orientation="right" orientation="right"
tick={{ fontSize: 12 }} tick={{ fontSize: 12, fill: "hsl(var(--muted-foreground))" }}
axisLine={false}
tickLine={false}
tickFormatter={(value) => tickFormatter={(value) =>
hideNumbers ? "***" : `£${(value / 1000).toFixed(0)}k` hideNumbers ? "***" : `£${(value / 1000).toFixed(0)}k`
} }
/> />
<Tooltip <Tooltip
cursor={{ fill: "transparent", stroke: "hsl(var(--muted-foreground))", strokeDasharray: "3 3" }}
content={({ active, payload }) => { content={({ active, payload }) => {
if (active && payload?.length) { if (active && payload?.length) {
const data = payload[0].payload; const data = payload[0].payload;
@@ -240,14 +255,16 @@ export default function GrowthAnalyticsChart({
return null; return null;
}} }}
/> />
<Bar <Line
yAxisId="left" yAxisId="left"
type="monotone"
dataKey="orders" dataKey="orders"
fill="#3b82f6" stroke="#3b82f6"
radius={[4, 4, 0, 0]} strokeWidth={2}
dot={{ fill: "#3b82f6", r: 3 }}
name="Orders" name="Orders"
/> />
<Line <Area
yAxisId="right" yAxisId="right"
type="monotone" type="monotone"
dataKey="revenue" dataKey="revenue"
@@ -255,6 +272,7 @@ export default function GrowthAnalyticsChart({
strokeWidth={3} strokeWidth={3}
dot={{ fill: "#10b981", r: 4 }} dot={{ fill: "#10b981", r: 4 }}
name="Revenue" name="Revenue"
fill="url(#colorRevenueGrowth)"
/> />
</ComposedChart> </ComposedChart>
</ResponsiveContainer> </ResponsiveContainer>

View File

@@ -34,6 +34,7 @@ import {
} from "lucide-react"; } from "lucide-react";
import { useToast } from "@/hooks/use-toast"; import { useToast } from "@/hooks/use-toast";
import { Skeleton } from "@/components/ui/skeleton"; import { Skeleton } from "@/components/ui/skeleton";
import CountUp from "react-countup";
import { import {
getPredictionsOverviewWithStore, getPredictionsOverviewWithStore,
getStockPredictionsWithStore, getStockPredictionsWithStore,
@@ -146,10 +147,11 @@ export default function PredictionsChart({
const simulatedData = useMemo(() => { const simulatedData = useMemo(() => {
if (!predictions?.sales?.dailyPredictions) return []; if (!predictions?.sales?.dailyPredictions) return [];
return predictions.sales.dailyPredictions.map((d) => ({ return predictions.sales.dailyPredictions.map((d: any) => ({
...d, ...d,
formattedDate: format(new Date(d.date), "MMM d"), formattedDate: format(new Date(d.date), "MMM d"),
value: d.predicted, value: d.predicted,
orders: d.predictedOrders || 0, // Ensure orders exist
})); }));
}, [predictions]); }, [predictions]);
@@ -301,7 +303,13 @@ export default function PredictionsChart({
<Tooltip> <Tooltip>
<TooltipTrigger asChild> <TooltipTrigger asChild>
<div className="text-2xl font-bold w-fit cursor-help"> <div className="text-2xl font-bold w-fit cursor-help">
{formatGBP(predictions.sales.predicted)} <CountUp
end={predictions.sales.predicted}
duration={1.5}
separator=","
decimals={2}
prefix="£"
/>
</div> </div>
</TooltipTrigger> </TooltipTrigger>
<TooltipContent> <TooltipContent>

View File

@@ -0,0 +1,15 @@
"use client";
import { motion } from "framer-motion";
export function MotionWrapper({ children }: { children: React.ReactNode }) {
return (
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5, staggerChildren: 0.1 }}
>
{children}
</motion.div>
);
}

View File

@@ -52,6 +52,7 @@
"date-fns": "4.1.0", "date-fns": "4.1.0",
"embla-carousel-react": "8.5.1", "embla-carousel-react": "8.5.1",
"form-data": "^4.0.2", "form-data": "^4.0.2",
"framer-motion": "^12.25.0",
"input-otp": "1.4.1", "input-otp": "1.4.1",
"jwt-decode": "^4.0.0", "jwt-decode": "^4.0.0",
"lodash": "^4.17.21", "lodash": "^4.17.21",
@@ -59,6 +60,7 @@
"next": "^16.1.1", "next": "^16.1.1",
"next-themes": "latest", "next-themes": "latest",
"react": "^19.0.0", "react": "^19.0.0",
"react-countup": "^6.5.3",
"react-day-picker": "8.10.1", "react-day-picker": "8.10.1",
"react-dnd": "^16.0.1", "react-dnd": "^16.0.1",
"react-dnd-html5-backend": "^16.0.1", "react-dnd-html5-backend": "^16.0.1",

72
pnpm-lock.yaml generated
View File

@@ -113,6 +113,9 @@ importers:
form-data: form-data:
specifier: ^4.0.2 specifier: ^4.0.2
version: 4.0.5 version: 4.0.5
framer-motion:
specifier: ^12.25.0
version: 12.25.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
input-otp: input-otp:
specifier: 1.4.1 specifier: 1.4.1
version: 1.4.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) version: 1.4.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
@@ -134,6 +137,9 @@ importers:
react: react:
specifier: ^19.0.0 specifier: ^19.0.0
version: 19.2.3 version: 19.2.3
react-countup:
specifier: ^6.5.3
version: 6.5.3(react@19.2.3)
react-day-picker: react-day-picker:
specifier: 8.10.1 specifier: 8.10.1
version: 8.10.1(date-fns@4.1.0)(react@19.2.3) version: 8.10.1(date-fns@4.1.0)(react@19.2.3)
@@ -1731,6 +1737,9 @@ packages:
convert-source-map@2.0.0: convert-source-map@2.0.0:
resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
countup.js@2.9.0:
resolution: {integrity: sha512-llqrvyXztRFPp6+i8jx25phHWcVWhrHO4Nlt0uAOSKHB8778zzQswa4MU3qKBvkXfJKftRYFJuVHez67lyKdHg==}
cross-env@7.0.3: cross-env@7.0.3:
resolution: {integrity: sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==} resolution: {integrity: sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==}
engines: {node: '>=10.14', npm: '>=6', yarn: '>=1'} engines: {node: '>=10.14', npm: '>=6', yarn: '>=1'}
@@ -2144,6 +2153,20 @@ packages:
fraction.js@5.3.4: fraction.js@5.3.4:
resolution: {integrity: sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==} resolution: {integrity: sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==}
framer-motion@12.25.0:
resolution: {integrity: sha512-mlWqd0rApIjeyhTCSNCqPYsUAEhkcUukZxH3ke6KbstBRPcxhEpuIjmiUQvB+1E9xkEm5SpNHBgHCapH/QHTWg==}
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
fsevents@2.3.3: fsevents@2.3.3:
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
@@ -2637,6 +2660,12 @@ packages:
minimist@1.2.8: minimist@1.2.8:
resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
motion-dom@12.24.11:
resolution: {integrity: sha512-DlWOmsXMJrV8lzZyd+LKjG2CXULUs++bkq8GZ2Sr0R0RRhs30K2wtY+LKiTjhmJU3W61HK+rB0GLz6XmPvTA1A==}
motion-utils@12.24.10:
resolution: {integrity: sha512-x5TFgkCIP4pPsRLpKoI86jv/q8t8FQOiM/0E8QKBzfMozWHfkKap2gA1hOki+B5g3IsBNpxbUnfOum1+dgvYww==}
mrmime@2.0.1: mrmime@2.0.1:
resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==}
engines: {node: '>=10'} engines: {node: '>=10'}
@@ -2866,6 +2895,11 @@ packages:
queue-microtask@1.2.3: queue-microtask@1.2.3:
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
react-countup@6.5.3:
resolution: {integrity: sha512-udnqVQitxC7QWADSPDOxVWULkLvKUWrDapn5i53HE4DPRVgs+Y5rr4bo25qEl8jSh+0l2cToJgGMx+clxPM3+w==}
peerDependencies:
react: '>= 16.3.0'
react-day-picker@8.10.1: react-day-picker@8.10.1:
resolution: {integrity: sha512-TMx7fNbhLk15eqcMt+7Z7S2KF7mfTId/XJDjKE8f+IUcFn0l08/kI4FiYTL/0yuOLmEcbR4Fwe3GJf/NiiMnPA==} resolution: {integrity: sha512-TMx7fNbhLk15eqcMt+7Z7S2KF7mfTId/XJDjKE8f+IUcFn0l08/kI4FiYTL/0yuOLmEcbR4Fwe3GJf/NiiMnPA==}
peerDependencies: peerDependencies:
@@ -4970,6 +5004,8 @@ snapshots:
convert-source-map@2.0.0: {} convert-source-map@2.0.0: {}
countup.js@2.9.0: {}
cross-env@7.0.3: cross-env@7.0.3:
dependencies: dependencies:
cross-spawn: 7.0.6 cross-spawn: 7.0.6
@@ -5240,8 +5276,8 @@ snapshots:
'@next/eslint-plugin-next': 16.1.1 '@next/eslint-plugin-next': 16.1.1
eslint: 9.39.2(jiti@1.21.7) eslint: 9.39.2(jiti@1.21.7)
eslint-import-resolver-node: 0.3.9 eslint-import-resolver-node: 0.3.9
eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.2(jiti@1.21.7)) eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.52.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(eslint@9.39.2(jiti@1.21.7)))(eslint@9.39.2(jiti@1.21.7))
eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.52.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.2(jiti@1.21.7)) eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.52.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.52.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(eslint@9.39.2(jiti@1.21.7)))(eslint@9.39.2(jiti@1.21.7)))(eslint@9.39.2(jiti@1.21.7))
eslint-plugin-jsx-a11y: 6.10.2(eslint@9.39.2(jiti@1.21.7)) eslint-plugin-jsx-a11y: 6.10.2(eslint@9.39.2(jiti@1.21.7))
eslint-plugin-react: 7.37.5(eslint@9.39.2(jiti@1.21.7)) eslint-plugin-react: 7.37.5(eslint@9.39.2(jiti@1.21.7))
eslint-plugin-react-hooks: 7.0.1(eslint@9.39.2(jiti@1.21.7)) eslint-plugin-react-hooks: 7.0.1(eslint@9.39.2(jiti@1.21.7))
@@ -5263,7 +5299,7 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.2(jiti@1.21.7)): eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.52.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(eslint@9.39.2(jiti@1.21.7)))(eslint@9.39.2(jiti@1.21.7)):
dependencies: dependencies:
'@nolyfill/is-core-module': 1.0.39 '@nolyfill/is-core-module': 1.0.39
debug: 4.4.3 debug: 4.4.3
@@ -5274,22 +5310,22 @@ snapshots:
tinyglobby: 0.2.15 tinyglobby: 0.2.15
unrs-resolver: 1.11.1 unrs-resolver: 1.11.1
optionalDependencies: optionalDependencies:
eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.52.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.2(jiti@1.21.7)) eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.52.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.52.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(eslint@9.39.2(jiti@1.21.7)))(eslint@9.39.2(jiti@1.21.7)))(eslint@9.39.2(jiti@1.21.7))
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
eslint-module-utils@2.12.1(@typescript-eslint/parser@8.52.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.2(jiti@1.21.7)): eslint-module-utils@2.12.1(@typescript-eslint/parser@8.52.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.52.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(eslint@9.39.2(jiti@1.21.7)))(eslint@9.39.2(jiti@1.21.7)))(eslint@9.39.2(jiti@1.21.7)):
dependencies: dependencies:
debug: 3.2.7 debug: 3.2.7
optionalDependencies: optionalDependencies:
'@typescript-eslint/parser': 8.52.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) '@typescript-eslint/parser': 8.52.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
eslint: 9.39.2(jiti@1.21.7) eslint: 9.39.2(jiti@1.21.7)
eslint-import-resolver-node: 0.3.9 eslint-import-resolver-node: 0.3.9
eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.2(jiti@1.21.7)) eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.52.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(eslint@9.39.2(jiti@1.21.7)))(eslint@9.39.2(jiti@1.21.7))
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.52.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.2(jiti@1.21.7)): eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.52.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.52.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(eslint@9.39.2(jiti@1.21.7)))(eslint@9.39.2(jiti@1.21.7)))(eslint@9.39.2(jiti@1.21.7)):
dependencies: dependencies:
'@rtsao/scc': 1.1.0 '@rtsao/scc': 1.1.0
array-includes: 3.1.9 array-includes: 3.1.9
@@ -5300,7 +5336,7 @@ snapshots:
doctrine: 2.1.0 doctrine: 2.1.0
eslint: 9.39.2(jiti@1.21.7) eslint: 9.39.2(jiti@1.21.7)
eslint-import-resolver-node: 0.3.9 eslint-import-resolver-node: 0.3.9
eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.52.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.2(jiti@1.21.7)) eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.52.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.52.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(eslint@9.39.2(jiti@1.21.7)))(eslint@9.39.2(jiti@1.21.7)))(eslint@9.39.2(jiti@1.21.7))
hasown: 2.0.2 hasown: 2.0.2
is-core-module: 2.16.1 is-core-module: 2.16.1
is-glob: 4.0.3 is-glob: 4.0.3
@@ -5512,6 +5548,15 @@ snapshots:
fraction.js@5.3.4: {} fraction.js@5.3.4: {}
framer-motion@12.25.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3):
dependencies:
motion-dom: 12.24.11
motion-utils: 12.24.10
tslib: 2.8.1
optionalDependencies:
react: 19.2.3
react-dom: 19.2.3(react@19.2.3)
fsevents@2.3.3: fsevents@2.3.3:
optional: true optional: true
@@ -6134,6 +6179,12 @@ snapshots:
minimist@1.2.8: {} minimist@1.2.8: {}
motion-dom@12.24.11:
dependencies:
motion-utils: 12.24.10
motion-utils@12.24.10: {}
mrmime@2.0.1: {} mrmime@2.0.1: {}
ms@2.1.3: {} ms@2.1.3: {}
@@ -6348,6 +6399,11 @@ snapshots:
queue-microtask@1.2.3: {} queue-microtask@1.2.3: {}
react-countup@6.5.3(react@19.2.3):
dependencies:
countup.js: 2.9.0
react: 19.2.3
react-day-picker@8.10.1(date-fns@4.1.0)(react@19.2.3): react-day-picker@8.10.1(date-fns@4.1.0)(react@19.2.3):
dependencies: dependencies:
date-fns: 4.1.0 date-fns: 4.1.0

View File

@@ -1,4 +1,4 @@
{ {
"commitHash": "2477e9b", "commitHash": "624bfa5",
"buildTime": "2026-01-11T07:54:27.069Z" "buildTime": "2026-01-12T02:42:11.944Z"
} }