Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
1c7695e
Merge pull request #30 from devxtra-community/dev
ansabazys Jan 2, 2026
b024128
Merge pull request #31 from devxtra-community/dev
ansabazys Jan 2, 2026
a9b1908
Merge pull request #32 from devxtra-community/dev
ansabazys Jan 2, 2026
7b8c44f
Merge pull request #33 from devxtra-community/dev
ansabazys Jan 2, 2026
ee09cd6
Merge pull request #34 from devxtra-community/dev
ansabazys Jan 2, 2026
d3648b5
Merge pull request #35 from devxtra-community/dev
ansabazys Jan 2, 2026
9fcad4d
Merge pull request #36 from devxtra-community/dev
ansabazys Jan 2, 2026
0ddac04
Merge pull request #37 from devxtra-community/dev
ansabazys Jan 2, 2026
e65b81a
Merge pull request #38 from devxtra-community/dev
ansabazys Jan 2, 2026
5c3549c
Merge pull request #39 from devxtra-community/dev
ansabazys Jan 2, 2026
88b290b
Merge pull request #40 from devxtra-community/dev
ansabazys Jan 2, 2026
4c24f67
Merge pull request #41 from devxtra-community/dev
ansabazys Jan 2, 2026
d765b7f
Merge pull request #42 from devxtra-community/dev
ansabazys Jan 2, 2026
a781f72
Merge pull request #43 from devxtra-community/dev
ansabazys Jan 2, 2026
1c39c2d
Merge pull request #44 from devxtra-community/dev
ansabazys Jan 2, 2026
25dfc4c
Merge pull request #45 from devxtra-community/dev
ansabazys Jan 2, 2026
5911823
Merge pull request #46 from devxtra-community/dev
ansabazys Jan 2, 2026
da9f4e0
Merge pull request #47 from devxtra-community/dev
ansabazys Jan 3, 2026
43c6119
Merge pull request #48 from devxtra-community/dev
ansabazys Jan 3, 2026
3e8dfde
Merge pull request #49 from devxtra-community/dev
ansabazys Jan 3, 2026
a7a5951
Merge pull request #50 from devxtra-community/dev
ansabazys Jan 3, 2026
5c2bdcd
Merge pull request #51 from devxtra-community/dev
ansabazys Jan 3, 2026
7a60c99
Merge pull request #52 from devxtra-community/dev
aleenamolroy Jan 3, 2026
2c06e4c
Merge pull request #53 from devxtra-community/dev
aleenamolroy Jan 3, 2026
59cc813
Merge pull request #55 from devxtra-community/dev
ansabazys Mar 6, 2026
a5fa293
Merge pull request #56 from devxtra-community/dev
ansabazys Mar 6, 2026
6546af0
Merge pull request #58 from devxtra-community/dev
ansabazys Mar 6, 2026
402e51e
Merge pull request #59 from devxtra-community/dev
ansabazys Mar 6, 2026
af5e3c2
Merge pull request #60 from devxtra-community/dev
ansabazys Mar 6, 2026
8b56094
Merge pull request #61 from devxtra-community/dev
ansabazys Mar 6, 2026
7548615
Merge pull request #64 from devxtra-community/dev
ansabazys Mar 7, 2026
c8c47d4
Merge pull request #65 from devxtra-community/dev
ansabazys Mar 7, 2026
fd63fa4
Merge pull request #66 from devxtra-community/dev
ansabazys Mar 7, 2026
d8bda22
Merge pull request #67 from devxtra-community/dev
ansabazys Mar 7, 2026
c9d26cc
Merge pull request #68 from devxtra-community/dev
ansabazys Mar 7, 2026
d87a223
Merge pull request #69 from devxtra-community/dev
ansabazys Mar 7, 2026
24445b1
Merge pull request #70 from devxtra-community/dev
ansabazys Mar 7, 2026
d55af96
Merge pull request #71 from devxtra-community/dev
ansabazys Mar 7, 2026
549f2e7
Merge pull request #72 from devxtra-community/dev
ansabazys Mar 7, 2026
55592c9
Merge pull request #73 from devxtra-community/dev
ansabazys Mar 7, 2026
e01d191
Merge pull request #74 from devxtra-community/dev
ansabazys Mar 7, 2026
8b911e3
Merge pull request #75 from devxtra-community/dev
ansabazys Mar 7, 2026
2736b98
Merge pull request #76 from devxtra-community/dev
ansabazys Mar 8, 2026
47c8921
Merge pull request #77 from devxtra-community/dev
ansabazys Mar 8, 2026
e087505
Merge pull request #78 from devxtra-community/dev
ansabazys Mar 8, 2026
f204bbe
Merge pull request #79 from devxtra-community/dev
ansabazys Mar 8, 2026
eab58fb
Merge pull request #80 from devxtra-community/dev
ansabazys Mar 8, 2026
1f807b2
Merge pull request #81 from devxtra-community/dev
ansabazys Mar 8, 2026
bb410ac
Merge pull request #82 from devxtra-community/dev
ansabazys Mar 8, 2026
7b1e242
Merge pull request #83 from devxtra-community/dev
ansabazys Mar 8, 2026
882aea2
feat: implemented analytics
ansabazys Mar 9, 2026
d97575c
fix: fixed parameter issue
ansabazys Mar 10, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 42 additions & 19 deletions frontend/web/src/app/admin/(protected)/dashboard/page.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,29 @@
'use client';

import ActivePromotions from '@/src/components/admin/dashboard/ActivePromotions';
import CustomerInsights from '@/src/components/admin/dashboard/CustomerInsights';
import QuickActionCard from '@/src/components/admin/dashboard/QuickActionCard';
import SalesChart from '@/src/components/admin/dashboard/SalesChart';
import StatCard from '@/src/components/admin/dashboard/StatCard';
import { analyticsService } from '@/src/services/analytics.service';
import { DashboardSummary } from '@/src/types/api/analytics.api';
import Link from 'next/link';
import { useEffect, useState } from 'react';

export default function Home() {
const [stats, setStats] = useState<DashboardSummary | null>(null);

useEffect(() => {
const loadDashboard = async () => {
const data = await analyticsService.getDashboardSummary();
setStats(data);
};

loadDashboard();
}, []);

if (!stats) return <div>Loading...</div>;

return (
<div className="flex flex-col gap-8 pt-2">
<div className="flex justify-between items-center max-md:flex-col max-md:items-start max-md:gap-4">
Expand Down Expand Up @@ -52,39 +70,44 @@ export default function Home() {
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
<StatCard
title="Total Sales"
value="$54,890"
trend={12.5}
trendLabel="This month"
value={`₹${stats.revenue}`}
trend={0}
trendLabel="Total revenue"
/>

<StatCard
title="Orders"
value="1,429"
trend={8.2}
trendLabel="This month"
value={stats.orders.toString()}
trend={0}
trendLabel="Total orders"
/>

<StatCard
title="Average Order Value"
value="$38.42"
trend={3.1}
trendLabel="This month"
value={`₹${stats.avgOrderValue.toFixed(2)}`}
trend={0}
trendLabel="Per order"
/>
{/*
<StatCard
title="Returning Customers"
value="68%"
trend={2.4}
trendLabel="This month"
/>
value={`${stats.returningCustomers}%`}
trend={0}
trendLabel="Repeat buyers"
/> */}

<StatCard
title="Cart Abandonment"
value="23.8%"
trend={-1.8}
trendLabel="This month"
value={`${stats.cartAbandonment.toFixed(1)}%`}
trend={0}
trendLabel="Abandonment rate"
/>

<StatCard
title="Product Views"
value="45,210"
trend={15.3}
trendLabel="This month"
value={stats.productViews.toString()}
trend={0}
trendLabel="Total views"
/>
</div>

Expand Down
95 changes: 61 additions & 34 deletions frontend/web/src/components/admin/analytics/AnalyticsStats.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use client';

import { useEffect, useState } from 'react';
import {
DollarSign,
ShoppingCart,
Expand All @@ -9,42 +10,65 @@ import {
ArrowDownRight,
} from 'lucide-react';

const stats = [
{
title: 'Total Revenue',
value: '$54,239',
change: '+12.5%',
trend: 'up',
icon: DollarSign,
color: 'bg-emerald-100 text-emerald-600',
},
{
title: 'Total Orders',
value: '1,253',
change: '+8.2%',
trend: 'up',
icon: ShoppingCart,
color: 'bg-blue-100 text-blue-600',
},
{
title: 'Avg. Order Value',
value: '$43.28',
change: '-2.1%',
trend: 'down',
icon: CreditCard,
color: 'bg-purple-100 text-purple-600',
},
{
title: 'Refund Rate',
value: '1.2%',
change: '+0.4%',
trend: 'down', // down is bad for refund rate usually, but visually down arrow red is consistent
icon: TrendingUp, // Maybe iterate on icon
color: 'bg-amber-100 text-amber-600',
},
];
import { analyticsService } from '@/src/services/analytics.service';
import { OverviewStats, GrowthStats } from '@/src/types/api/analytics.api';

interface StatsState {
overview: OverviewStats;
growth: GrowthStats;
}

export default function AnalyticsStats() {
const [data, setData] = useState<StatsState | null>(null);

useEffect(() => {
const loadStats = async () => {
const overview = await analyticsService.getOverview();
const growth = await analyticsService.getGrowthStats();

setData({ overview, growth });
};

loadStats();
}, []);

if (!data) return null;

const stats = [
{
title: 'Total Revenue',
value: `₹${data.overview.revenue.toLocaleString()}`,
change: `${data.growth.revenueGrowth.toFixed(1)}%`,
trend: data.growth.revenueGrowth >= 0 ? 'up' : 'down',
icon: DollarSign,
color: 'bg-emerald-100 text-emerald-600',
},
{
title: 'Total Orders',
value: data.overview.orders.toString(),
change: `${data.growth.orderGrowth.toFixed(1)}%`,
trend: data.growth.orderGrowth >= 0 ? 'up' : 'down',
icon: ShoppingCart,
color: 'bg-blue-100 text-blue-600',
},
{
title: 'Avg. Order Value',
value: `₹${data.overview.avgOrderValue.toFixed(2)}`,
change: '—',
trend: 'up',
icon: CreditCard,
color: 'bg-purple-100 text-purple-600',
},
{
title: 'Refund Rate',
value: `${data.overview.refundRate.toFixed(1)}%`,
change: '—',
trend: 'down',
icon: TrendingUp,
color: 'bg-amber-100 text-amber-600',
},
];

return (
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6">
{stats.map((stat, index) => (
Expand All @@ -56,6 +80,7 @@ export default function AnalyticsStats() {
<div className={`p-3 rounded-xl ${stat.color}`}>
<stat.icon size={22} />
</div>

<div
className={`flex items-center gap-1 text-xs font-semibold px-2 py-1 rounded-lg ${
stat.trend === 'up'
Expand All @@ -71,8 +96,10 @@ export default function AnalyticsStats() {
{stat.change}
</div>
</div>

<div>
<p className="text-gray-500 text-sm font-medium">{stat.title}</p>

<h3 className="text-2xl font-bold text-gray-900 mt-1">
{stat.value}
</h3>
Expand Down
43 changes: 29 additions & 14 deletions frontend/web/src/components/admin/analytics/RevenueChart.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use client';

import { useEffect, useState } from 'react';
import {
AreaChart,
Area,
Expand All @@ -10,22 +11,36 @@ import {
ResponsiveContainer,
} from 'recharts';

const data = [
{ name: 'Jan', revenue: 4000, profit: 2400 },
{ name: 'Feb', revenue: 3000, profit: 1398 },
{ name: 'Mar', revenue: 2000, profit: 9800 },
{ name: 'Apr', revenue: 2780, profit: 3908 },
{ name: 'May', revenue: 1890, profit: 4800 },
{ name: 'Jun', revenue: 2390, profit: 3800 },
{ name: 'Jul', revenue: 3490, profit: 4300 },
{ name: 'Aug', revenue: 4200, profit: 5100 },
{ name: 'Sep', revenue: 5100, profit: 5900 },
{ name: 'Oct', revenue: 6200, profit: 6500 },
{ name: 'Nov', revenue: 5800, profit: 5400 },
{ name: 'Dec', revenue: 7500, profit: 6800 },
];
import { analyticsService } from '@/src/services/analytics.service';
import { RevenueChartPoint } from '@/src/types/api/analytics.api';

interface ChartPoint {
name: string;
revenue: number;
profit: number;
}

export default function RevenueChart() {
const [data, setData] = useState<ChartPoint[]>([]);

useEffect(() => {
const loadRevenue = async () => {
const res: RevenueChartPoint[] =
await analyticsService.getRevenueChart(365);

const chartData: ChartPoint[] = res.map((item) => ({
name: new Date(item.date).toLocaleDateString('en-US', {
month: 'short',
}),
revenue: item.revenue,
profit: Math.round(item.revenue * 0.3), // placeholder profit calc
}));

setData(chartData);
};

loadRevenue();
}, []);
return (
<div className="bg-white p-6 rounded-[20px] shadow-sm border border-gray-100 flex flex-col h-full">
<div className="flex justify-between items-center mb-8">
Expand Down
41 changes: 27 additions & 14 deletions frontend/web/src/components/admin/dashboard/SalesChart.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use client';

import { useEffect, useState } from 'react';
import {
BarChart,
Bar,
Expand All @@ -10,22 +11,34 @@ import {
ResponsiveContainer,
} from 'recharts';

const data = [
{ name: 'Jan', sales: 2500 },
{ name: 'Feb', sales: 7500 },
{ name: 'Mar', sales: 6000 },
{ name: 'Apr', sales: 9000 },
{ name: 'May', sales: 7800 },
{ name: 'Jun', sales: 5500 },
{ name: 'Jul', sales: 3000 },
{ name: 'Aug', sales: 8500 },
{ name: 'Sep', sales: 7000 },
{ name: 'Oct', sales: 10000 },
{ name: 'Nov', sales: 6500 },
{ name: 'Dec', sales: 3500 },
];
import { analyticsService } from '@/src/services/analytics.service';
import { RevenueChartPoint } from '@/src/types/api/analytics.api';

interface ChartPoint {
name: string;
sales: number;
}

export default function SalesChart() {
const [data, setData] = useState<ChartPoint[]>([]);

useEffect(() => {
const loadRevenue = async () => {
const res: RevenueChartPoint[] =
await analyticsService.getRevenueChart(30);

const chartData: ChartPoint[] = res.map((item) => ({
name: new Date(item.date).toLocaleDateString('en-US', {
month: 'short',
}),
sales: item.revenue,
}));

setData(chartData);
};

loadRevenue();
}, []);
return (
<div className="bg-white rounded-[20px] p-6 shadow-[0_4px_6px_-1px_rgba(0,0,0,0.02)] h-full flex flex-col">
<div className="flex justify-between items-center mb-8 max-[500px]:flex-col max-[500px]:items-start max-[500px]:gap-4">
Expand Down
Loading