diff --git a/app/Http/Controllers/AnalysisController.php b/app/Http/Controllers/AnalysisController.php index 6ec89f6..082ba05 100644 --- a/app/Http/Controllers/AnalysisController.php +++ b/app/Http/Controllers/AnalysisController.php @@ -196,6 +196,17 @@ public function __invoke() ]; }); + $topCategories = DB::table('order_items') + ->join('products', 'order_items.product_id', '=', 'products.id') + ->join('category_product', 'products.id', '=', 'category_product.product_id') + ->join('categories', 'category_product.category_id', '=', 'categories.id') + ->select('categories.name', DB::raw('SUM(order_items.qty) as total')) + ->whereNull('order_items.deleted_at') + ->groupBy('categories.id', 'categories.name') + ->orderByDesc('total') + ->limit(5) + ->get(); + return Inertia::render('analysis', [ 'stats' => $stats, 'salesByMonth' => $salesByMonth, @@ -207,6 +218,7 @@ public function __invoke() 'orderChannels' => $orderChannels, 'topProducts' => $topProducts, 'topCustomers' => $topCustomers, + 'topCategories' => $topCategories, ]); } diff --git a/resources/js/components/charts/aov-trend-chart.tsx b/resources/js/components/charts/aov-trend-chart.tsx new file mode 100644 index 0000000..b29e04c --- /dev/null +++ b/resources/js/components/charts/aov-trend-chart.tsx @@ -0,0 +1,100 @@ +"use client" + +import { TrendingUp } from "lucide-react" +import { CartesianGrid, Line, LineChart, XAxis, YAxis } 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, formatShortCurrency } from "@/lib/formatters" + +export const description = "Tren rata-rata nilai pesanan (AOV) per bulan." + +const chartConfig = { + aov: { + label: "AOV", + color: "var(--chart-1)", + }, +} satisfies ChartConfig + +export function AovTrendChart({ data }: { data: any[] }) { + return ( + + + Tren AOV + Rata-rata nilai belanja per pesanan + + + + + + value.slice(0, 3)} + /> + + [ + formatCurrency(Number(value)), + chartConfig.aov.label + ]} + /> + } + /> + + + + + +
+ Menampilkan tren kualitas belanja pelanggan +
+
+ Berdasarkan data operasional Januari - Desember +
+
+
+ ) +} diff --git a/resources/js/components/charts/pie-chart.tsx b/resources/js/components/charts/pie-chart.tsx index 2664738..acafbd0 100644 --- a/resources/js/components/charts/pie-chart.tsx +++ b/resources/js/components/charts/pie-chart.tsx @@ -50,6 +50,7 @@ export const CustomPieChart = React.memo(function CustomPieChart({ ...item, fill: `var(--color-${key})`, name: String(item.name), + total: Number(item.total), } }) diff --git a/resources/js/components/charts/transaction-volume-chart.tsx b/resources/js/components/charts/transaction-volume-chart.tsx index 0e03042..ee48e26 100644 --- a/resources/js/components/charts/transaction-volume-chart.tsx +++ b/resources/js/components/charts/transaction-volume-chart.tsx @@ -26,10 +26,6 @@ const chartConfig = { label: "Jumlah Transaksi", color: "var(--chart-1)", }, - aov: { - label: "AOV", - color: "var(--chart-2)", - }, } satisfies ChartConfig export function TransactionVolumeChart({ data }: { data: any[] }) { @@ -65,29 +61,7 @@ export function TransactionVolumeChart({ data }: { data: any[] }) { /> { - if (name === "count") { - return ( -
-
-
- Transaksi: - {value} -
-
-
- AOV: - {formatCurrency(item.payload.aov)} -
-
- ) - } - return null; - }} - /> - } + content={} /> ().props; return ( @@ -62,18 +63,20 @@ export default function Analisa() { {/* Activity & Volume Grid */}
- +
-
+ + +
+
diff --git a/resources/js/types/dashboard.ts b/resources/js/types/dashboard.ts index 933b5b3..de81bf3 100644 --- a/resources/js/types/dashboard.ts +++ b/resources/js/types/dashboard.ts @@ -40,5 +40,6 @@ export interface AnalysisPageProps { orderChannels: any[]; topProducts: any[]; topCustomers: any[]; + topCategories: any[]; [key: string]: any; }