- {[
- {
- icon: Shield,
- title: "Secure Payments",
- description: "Built-in cryptocurrency support with maximum privacy and security for your transactions."
- },
- {
- icon: LineChart,
- title: "Real-time Analytics",
- description: "Track your business performance with detailed insights and reporting tools."
- },
- {
- icon: Zap,
- 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'];
- const christmasBorders = ['border-red-500/30', 'border-green-500/30', 'border-yellow-500/30'];
- 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 (
-
+
+ {[
+ {
+ icon: Shield,
+ title: "Secure Payments",
+ description: "Built-in cryptocurrency support with maximum privacy and security for your transactions."
+ },
+ {
+ icon: LineChart,
+ title: "Real-time Analytics",
+ description: "Track your business performance with detailed insights and reporting tools."
+ },
+ {
+ icon: Zap,
+ 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'];
+ const christmasBorders = ['border-red-500/30', 'border-green-500/30', 'border-yellow-500/30'];
+ 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 (
+
-
-
-
-
+ }`}
+ >
+
+
+
+
+
+
{feature.title}
+
{feature.description}
-
{feature.title}
-
{feature.description}
-
- );
- })}
-
+ );
+ })}
+
+
{/* Stats Section */}
diff --git a/components/analytics/GrowthAnalyticsChart.tsx b/components/analytics/GrowthAnalyticsChart.tsx
index 10d8ff7..4a30ccc 100644
--- a/components/analytics/GrowthAnalyticsChart.tsx
+++ b/components/analytics/GrowthAnalyticsChart.tsx
@@ -24,6 +24,7 @@ import {
CartesianGrid,
Tooltip,
ResponsiveContainer,
+ Area,
} from "recharts";
interface GrowthAnalyticsChartProps {
@@ -195,18 +196,32 @@ export default function GrowthAnalyticsChart({
}))}
margin={{ top: 5, right: 30, left: 20, bottom: 5 }}
>
-
-
-
+
+
+
+
+
+
+
+
+
hideNumbers ? "***" : `£${(value / 1000).toFixed(0)}k`
}
/>
{
if (active && payload?.length) {
const data = payload[0].payload;
@@ -240,14 +255,16 @@ export default function GrowthAnalyticsChart({
return null;
}}
/>
-
-
diff --git a/components/analytics/PredictionsChart.tsx b/components/analytics/PredictionsChart.tsx
index 142ef57..6608128 100644
--- a/components/analytics/PredictionsChart.tsx
+++ b/components/analytics/PredictionsChart.tsx
@@ -34,6 +34,7 @@ import {
} from "lucide-react";
import { useToast } from "@/hooks/use-toast";
import { Skeleton } from "@/components/ui/skeleton";
+import CountUp from "react-countup";
import {
getPredictionsOverviewWithStore,
getStockPredictionsWithStore,
@@ -146,10 +147,11 @@ export default function PredictionsChart({
const simulatedData = useMemo(() => {
if (!predictions?.sales?.dailyPredictions) return [];
- return predictions.sales.dailyPredictions.map((d) => ({
+ return predictions.sales.dailyPredictions.map((d: any) => ({
...d,
formattedDate: format(new Date(d.date), "MMM d"),
value: d.predicted,
+ orders: d.predictedOrders || 0, // Ensure orders exist
}));
}, [predictions]);
@@ -301,7 +303,13 @@ export default function PredictionsChart({
- {formatGBP(predictions.sales.predicted)}
+
diff --git a/components/ui/motion-wrapper.tsx b/components/ui/motion-wrapper.tsx
new file mode 100644
index 0000000..a304739
--- /dev/null
+++ b/components/ui/motion-wrapper.tsx
@@ -0,0 +1,15 @@
+"use client";
+
+import { motion } from "framer-motion";
+
+export function MotionWrapper({ children }: { children: React.ReactNode }) {
+ return (
+
+ {children}
+
+ );
+}
diff --git a/package.json b/package.json
index 731a74c..0d9f212 100644
--- a/package.json
+++ b/package.json
@@ -52,6 +52,7 @@
"date-fns": "4.1.0",
"embla-carousel-react": "8.5.1",
"form-data": "^4.0.2",
+ "framer-motion": "^12.25.0",
"input-otp": "1.4.1",
"jwt-decode": "^4.0.0",
"lodash": "^4.17.21",
@@ -59,6 +60,7 @@
"next": "^16.1.1",
"next-themes": "latest",
"react": "^19.0.0",
+ "react-countup": "^6.5.3",
"react-day-picker": "8.10.1",
"react-dnd": "^16.0.1",
"react-dnd-html5-backend": "^16.0.1",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 9b7d654..5573115 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -113,6 +113,9 @@ importers:
form-data:
specifier: ^4.0.2
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:
specifier: 1.4.1
version: 1.4.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
@@ -134,6 +137,9 @@ importers:
react:
specifier: ^19.0.0
version: 19.2.3
+ react-countup:
+ specifier: ^6.5.3
+ version: 6.5.3(react@19.2.3)
react-day-picker:
specifier: 8.10.1
version: 8.10.1(date-fns@4.1.0)(react@19.2.3)
@@ -1731,6 +1737,9 @@ packages:
convert-source-map@2.0.0:
resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
+ countup.js@2.9.0:
+ resolution: {integrity: sha512-llqrvyXztRFPp6+i8jx25phHWcVWhrHO4Nlt0uAOSKHB8778zzQswa4MU3qKBvkXfJKftRYFJuVHez67lyKdHg==}
+
cross-env@7.0.3:
resolution: {integrity: sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==}
engines: {node: '>=10.14', npm: '>=6', yarn: '>=1'}
@@ -2144,6 +2153,20 @@ packages:
fraction.js@5.3.4:
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:
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
@@ -2637,6 +2660,12 @@ packages:
minimist@1.2.8:
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:
resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==}
engines: {node: '>=10'}
@@ -2866,6 +2895,11 @@ packages:
queue-microtask@1.2.3:
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:
resolution: {integrity: sha512-TMx7fNbhLk15eqcMt+7Z7S2KF7mfTId/XJDjKE8f+IUcFn0l08/kI4FiYTL/0yuOLmEcbR4Fwe3GJf/NiiMnPA==}
peerDependencies:
@@ -4970,6 +5004,8 @@ snapshots:
convert-source-map@2.0.0: {}
+ countup.js@2.9.0: {}
+
cross-env@7.0.3:
dependencies:
cross-spawn: 7.0.6
@@ -5240,8 +5276,8 @@ snapshots:
'@next/eslint-plugin-next': 16.1.1
eslint: 9.39.2(jiti@1.21.7)
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-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-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-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-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))
@@ -5263,7 +5299,7 @@ snapshots:
transitivePeerDependencies:
- 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:
'@nolyfill/is-core-module': 1.0.39
debug: 4.4.3
@@ -5274,22 +5310,22 @@ snapshots:
tinyglobby: 0.2.15
unrs-resolver: 1.11.1
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:
- 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:
debug: 3.2.7
optionalDependencies:
'@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-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:
- 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:
'@rtsao/scc': 1.1.0
array-includes: 3.1.9
@@ -5300,7 +5336,7 @@ snapshots:
doctrine: 2.1.0
eslint: 9.39.2(jiti@1.21.7)
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
is-core-module: 2.16.1
is-glob: 4.0.3
@@ -5512,6 +5548,15 @@ snapshots:
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:
optional: true
@@ -6134,6 +6179,12 @@ snapshots:
minimist@1.2.8: {}
+ motion-dom@12.24.11:
+ dependencies:
+ motion-utils: 12.24.10
+
+ motion-utils@12.24.10: {}
+
mrmime@2.0.1: {}
ms@2.1.3: {}
@@ -6348,6 +6399,11 @@ snapshots:
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):
dependencies:
date-fns: 4.1.0
diff --git a/public/git-info.json b/public/git-info.json
index 58acf8f..bffac89 100644
--- a/public/git-info.json
+++ b/public/git-info.json
@@ -1,4 +1,4 @@
{
- "commitHash": "2477e9b",
- "buildTime": "2026-01-11T07:54:27.069Z"
+ "commitHash": "624bfa5",
+ "buildTime": "2026-01-12T02:42:11.944Z"
}
\ No newline at end of file