diff --git a/app/Http/Controllers/AnalysisController.php b/app/Http/Controllers/AnalysisController.php index 3d868d5..6ec89f6 100644 --- a/app/Http/Controllers/AnalysisController.php +++ b/app/Http/Controllers/AnalysisController.php @@ -137,12 +137,13 @@ public function __invoke() ]; }); - // Revenue & Profit per month + // Revenue & Profit & Volume per month $ordersByMonth = DB::table('orders') ->select( DB::raw('MONTH(created_at) as month'), DB::raw('SUM(total) as revenue'), - DB::raw('SUM(hpp) as cogs') + DB::raw('SUM(hpp) as cogs'), + DB::raw('COUNT(*) as count') ) ->groupBy(DB::raw('MONTH(created_at)')) ->get(); @@ -182,10 +183,24 @@ public function __invoke() ]; }); + $transactionVolume = collect(range(1, 12))->map(function ($month) use ($ordersByMonth, $monthNames) { + $found = $ordersByMonth->firstWhere('month', $month); + $count = $found ? (int) $found->count : 0; + $revenue = $found ? (float) $found->revenue : 0; + $aov = $count > 0 ? $revenue / $count : 0; + + return [ + 'month' => $monthNames[$month - 1], + 'count' => $count, + 'aov' => $aov, + ]; + }); + return Inertia::render('analysis', [ 'stats' => $stats, 'salesByMonth' => $salesByMonth, 'revenueVsProfit' => $revenueVsProfit, + 'transactionVolume' => $transactionVolume, 'salesByHour' => $salesByHour, 'paymentMethods' => $paymentMethods, 'orderStatuses' => $orderStatuses, diff --git a/resources/js/components/charts/transaction-volume-chart.tsx b/resources/js/components/charts/transaction-volume-chart.tsx new file mode 100644 index 0000000..7489387 --- /dev/null +++ b/resources/js/components/charts/transaction-volume-chart.tsx @@ -0,0 +1,124 @@ +"use client" + +import { GitCommitVertical, TrendingUp } from "lucide-react" +import { CartesianGrid, Line, LineChart, XAxis } from "recharts" + +import { + Card, + CardContent, + CardDescription, + CardFooter, + CardHeader, + CardTitle, +} from "@/components/ui/card" +import { + ChartContainer, + ChartTooltip, + ChartTooltipContent, + type ChartConfig, +} from "@/components/ui/chart" +import { formatCurrency } from "@/lib/formatters" + +export const description = "Menampilkan volume transaksi per bulan." + +const chartConfig = { + count: { + label: "Jumlah Transaksi", + color: "var(--chart-1)", + }, + aov: { + label: "AOV", + color: "var(--chart-2)", + }, +} satisfies ChartConfig + +export function TransactionVolumeChart({ data }: { data: any[] }) { + return ( + + + Volume Transaksi + Total pesanan masuk per bulan + + + + + + value.slice(0, 3)} + /> + { + if (name === "count") { + return ( +
+
+
+ Transaksi: + {value} +
+
+
+ AOV: + {formatCurrency(item.payload.aov)} +
+
+ ) + } + return null; + }} + /> + } + /> + { + if (cx == null || cy == null) { + return null + } + + const r = 24 + + return ( + + ) + }} + /> + + + + +
+ Menampilkan tren aktivitas transaksi +
+
+ Berdasarkan total pesanan dari Januari - Desember +
+
+ + ) +} diff --git a/resources/js/pages/analysis.tsx b/resources/js/pages/analysis.tsx index 238ca8d..7178fae 100644 --- a/resources/js/pages/analysis.tsx +++ b/resources/js/pages/analysis.tsx @@ -5,11 +5,12 @@ 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, salesByHour, paymentMethods, orderStatuses, orderChannels, topProducts, topCustomers } = + const { stats, salesByMonth, revenueVsProfit, transactionVolume, salesByHour, paymentMethods, orderStatuses, orderChannels, topProducts, topCustomers } = usePage().props; return ( @@ -56,6 +57,8 @@ export default function Analisa() { + +