feat: add quick filter options for date range selection in Analysis.vue to enhance user experience

This commit is contained in:
Yoga Pangestu 2026-06-25 20:00:18 +07:00
parent 11232293a9
commit cecbf92310

View File

@ -1,6 +1,6 @@
<script setup lang="ts">
import { Head, router } from '@inertiajs/vue3';
import { Banknote, DollarSign, Package, Percent, ShoppingCart, TrendingDown, TrendingUp, UserCheck } from '@lucide/vue';
import { Banknote, Package, Percent, ShoppingCart, TrendingDown, TrendingUp, UserCheck } from '@lucide/vue';
import { VisAxis, VisGroupedBar, VisXYContainer } from '@unovis/vue';
import { computed, ref, watch } from 'vue';
import StatCard from '@/components/card/StatCard.vue';
@ -15,6 +15,7 @@ import {
import type { ChartConfig } from '@/components/ui/chart';
import { ChartContainer } from '@/components/ui/chart';
import { DatePicker } from '@/components/ui/date-picker';
import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import AdminLayout from '@/layouts/AdminLayout.vue';
import { formatRupiah } from '@/lib/rupiah';
import admin from '@/routes/admin';
@ -116,9 +117,45 @@ const props = defineProps<{
const startDate = ref(props.filters.start_date ?? '');
const endDate = ref(props.filters.end_date ?? '');
const selectedPreset = ref<string>('');
const hasActiveFilters = computed(() => !!startDate.value || !!endDate.value);
function formatDate(date: Date): string {
return date.toISOString().split('T')[0];
}
function onPresetChange(value: any) {
if (typeof value !== 'string') {
return;
}
selectedPreset.value = value;
const now = new Date();
let start: Date;
switch (value) {
case 'today':
start = new Date(now);
break;
case 'week':
start = new Date(now);
start.setDate(now.getDate() - now.getDay() + 1);
break;
case 'month':
start = new Date(now.getFullYear(), now.getMonth(), 1);
break;
case 'year':
start = new Date(now.getFullYear(), 0, 1);
break;
default:
return;
}
startDate.value = formatDate(start);
endDate.value = formatDate(now);
}
// Revenue Chart
type MonthlyRevenueData = { month: string; total: number; net: number; potongan: number; ongkir: number };
@ -263,6 +300,7 @@ function applyFilters() {
function clearFilters() {
startDate.value = '';
endDate.value = '';
selectedPreset.value = '';
applyFilters();
}
@ -277,17 +315,25 @@ watch([startDate, endDate], () => {
<AdminLayout>
<div class="flex flex-col gap-6">
<!-- Header & Filter -->
<div
class="flex flex-col gap-4 rounded-lg border bg-card p-6 shadow-xs md:flex-row md:items-center md:justify-between">
<div class="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
<div class="space-y-1">
<h2 class="text-2xl font-bold tracking-tight">Analisa</h2>
<p class="text-sm text-muted-foreground">
Halaman analisa data dan performa toko.
</p>
</div>
<!-- Date Filters -->
<div class="flex flex-wrap items-center gap-3">
<Select v-model="selectedPreset" @update:model-value="onPresetChange">
<SelectTrigger class="w-[140px] h-9">
<SelectValue placeholder="Filter Cepat" />
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectItem value="today">Hari Ini</SelectItem>
<SelectItem value="week">Minggu Ini</SelectItem>
<SelectItem value="month">Bulan Ini</SelectItem>
<SelectItem value="year">Tahun Ini</SelectItem>
</SelectGroup>
</SelectContent>
</Select>
<div class="flex items-center gap-2">
<span class="text-xs font-semibold tracking-wider text-muted-foreground uppercase">Mulai:</span>
<DatePicker v-model="startDate" class="w-[170px]" placeholder="Pilih tanggal" />
@ -492,7 +538,8 @@ watch([startDate, endDate], () => {
<!-- Profit Metrics Cards -->
<div class="grid gap-4 md:grid-cols-2 lg:grid-cols-4">
<StatCard title="Total Order" :icon="ShoppingCart" main-label="Pesanan Selesai"
:main-value="profitMetrics.total_orders.toLocaleString('id-ID')" :sub-label="'AOV: Rp' + formatRupiah(profitMetrics.aov)" :items="[
:main-value="profitMetrics.total_orders.toLocaleString('id-ID')"
:sub-label="'AOV: Rp' + formatRupiah(profitMetrics.aov)" :items="[
{
label: 'Produk Terjual',
value: profitMetrics.total_products_sold.toLocaleString('id-ID'),