dress/resources/js/pages/analysis.tsx

125 lines
5.8 KiB
TypeScript

import { StatCard } from '@/components/cards/stat-card';
import { analysis } from '@/routes';
import type { AnalysisPageProps } from '@/types';
import { Head, usePage } from '@inertiajs/react';
import { CustomBarChart } from '../components/charts/bar-chart';
import { CustomPieChart } from '../components/charts/pie-chart';
import { RevenueVsProfitChart } from '../components/charts/revenue-vs-profit-chart';
import { TransactionVolumeChart } from '../components/charts/transaction-volume-chart';
import { RevenueVsPurchasesChart } from '../components/charts/revenue-vs-purchases-chart';
import { SalesByHourChart } from '../components/charts/sales-by-hour-chart';
export default function Analisa() {
const { stats, salesByMonth, revenueVsProfit, transactionVolume, salesByHour, paymentMethods, orderStatuses, orderChannels, topProducts, topCustomers } =
usePage<AnalysisPageProps>().props;
return (
<>
<Head title="Analisa" />
<div className="flex h-full min-h-screen flex-1 flex-col gap-4 overflow-x-auto rounded-xl p-6 @container/main">
<div>
<h1 className="text-3xl font-bold tracking-tight">Analisa</h1>
</div>
{/* Stats Grid */}
<div className="grid grid-cols-1 gap-4 *:data-[slot=card]:bg-gradient-to-t *:data-[slot=card]:from-primary/5 *:data-[slot=card]:to-card *:data-[slot=card]:shadow-xs @xl/main:grid-cols-2 @4xl/main:grid-cols-4 dark:*:data-[slot=card]:bg-card">
{[
{ title: "Total Penjualan", stat: stats.total_sales, isCurrency: false },
{ title: "Total Pendapatan", stat: stats.total_revenue },
{ title: "Total Pengeluaran", stat: stats.total_expenses },
{ title: "HPP (Modal)", stat: stats.cogs },
{ title: "AOV (Avg Order Value)", stat: stats.aov },
{ title: "Profit Margin", stat: stats.profit_margin, isPercentage: true },
{ title: "Total Diskon", stat: stats.total_discount },
{ title: "Laba Kotor", stat: stats.gross_profit },
{ title: "Laba Bersih", stat: stats.net_profit },
{ title: "Total Gaji", stat: stats.total_payrolls },
{ title: "Total Pembelian", stat: stats.total_purchases },
{ title: "Produk Terjual", stat: stats.products_sold, isCurrency: false },
{ title: "Total Pelanggan", stat: stats.total_customers, isCurrency: false },
].map((item, index) => (
<div
key={index}
className="animate-in fade-in slide-in-from-bottom-4 fill-mode-both"
style={{ animationDelay: `${index * 100}ms` }}
>
<StatCard
{...item}
className="transition-all duration-300 hover:scale-[1.03] hover:shadow-xl hover:-translate-y-1"
/>
</div>
))}
</div>
{/* Main Trends Grid */}
<div className="grid grid-cols-1 gap-4 lg:grid-cols-2">
<RevenueVsProfitChart data={revenueVsProfit} />
<RevenueVsPurchasesChart data={salesByMonth} />
</div>
{/* Activity & Volume Grid */}
<div className="grid grid-cols-1 gap-4 lg:grid-cols-2">
<TransactionVolumeChart data={transactionVolume} />
<SalesByHourChart
data={salesByHour}
config={{
total: {
label: "Total Penjualan",
color: "var(--chart-1)",
},
}}
/>
</div>
<div className="grid grid-cols-1 gap-4 lg:grid-cols-3">
<CustomPieChart
title="Metode Pembayaran"
description="Distribusi pesanan berdasarkan metode pembayaran."
data={paymentMethods}
colorOffset={0}
/>
<CustomPieChart
title="Status Pesanan"
description="Distribusi pesanan berdasarkan status."
data={orderStatuses}
colorOffset={120}
/>
<CustomPieChart
title="Channel Pesanan"
description="Distribusi pesanan berdasarkan channel/platform."
data={orderChannels}
colorOffset={240}
/>
</div>
<div className="grid grid-cols-1 gap-4 lg:grid-cols-2">
<CustomBarChart
title="Top 5 Produk Terlaris"
description="Berdasarkan jumlah produk yang terjual."
data={topProducts}
colorOffset={45}
/>
<CustomBarChart
title="Top 5 Pelanggan Setia"
description="Berdasarkan total nominal belanja."
data={topCustomers}
colorOffset={180}
isCurrency={true}
/>
</div>
</div>
</>
);
}
Analisa.layout = {
breadcrumbs: [
{
title: 'Analisa',
href: analysis().url,
},
],
};