Files

157 lines
6.7 KiB
TypeScript

"use client";
import { useState, useMemo } from "react";
import { CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { DashboardCard } from "@/components/dashboard-card";
import { Input } from "@/components/ui/input";
import { SearchIcon, FuelIcon } from "@/components/ui/phosphor-icons";
import { ContinuousTabs } from "@/components/ui/continuous-tabs";
import type { FuelPricesResponse } from "./gas-station-stats-cards";
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table";
interface PertaminaPriceTableProps {
fuelPrices: FuelPricesResponse | null;
loading: boolean;
}
export function PertaminaPriceTable({ fuelPrices, loading }: PertaminaPriceTableProps) {
const [activeTab, setActiveTab] = useState<string>("gasoline");
const [searchQuery, setSearchQuery] = useState<string>("");
const dataList = useMemo(() => {
if (!fuelPrices) return [];
return activeTab === "gasoline" ? fuelPrices.gasoline : fuelPrices.diesel;
}, [fuelPrices, activeTab]);
const filteredData = useMemo(() => {
return dataList.filter((row) =>
row.region?.toLowerCase().includes(searchQuery.toLowerCase())
);
}, [dataList, searchQuery]);
const formatVal = (val: number | null) => {
if (val == null) return <span className="text-muted-foreground/45"></span>;
return <span className="font-semibold text-foreground">Rp {val.toLocaleString("id-ID")}</span>;
};
return (
<DashboardCard className="relative gap-0 h-full flex flex-col">
<CardHeader className="border-b border-border/60 bg-muted/10 px-6 py-4 flex flex-col sm:flex-row justify-between sm:items-center gap-4">
<div>
<CardTitle className="text-base font-semibold flex items-center gap-2">
<FuelIcon className="h-5 w-5 text-primary" />
Daftar Harga BBM Pertamina Seluruh Indonesia
</CardTitle>
<CardDescription>
Data real-time disinkronkan dari Pertamina Patra Niaga ({fuelPrices?.lastUpdated || "Update terbaru"}).
</CardDescription>
</div>
<div className="flex flex-col sm:flex-row gap-3 items-center w-full sm:w-auto">
<div className="relative w-full sm:w-64">
<SearchIcon className="absolute left-3 top-2.5 h-4 w-4 text-muted-foreground" />
<Input
placeholder="Cari provinsi..."
className="pl-9 bg-background h-9 text-xs"
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
/>
</div>
<ContinuousTabs
tabs={[
{ id: "gasoline", label: "Bensin (Gasoline)" },
{ id: "diesel", label: "Solar (Gasoil)" },
]}
activeId={activeTab}
onChange={setActiveTab}
size="sm"
/>
</div>
</CardHeader>
<CardContent className="p-0 flex-1 flex flex-col">
{loading ? (
<div className="py-12 text-center text-sm text-muted-foreground">
Memuat data harga BBM terbaru...
</div>
) : filteredData.length === 0 ? (
<div className="py-12 text-center text-sm text-muted-foreground">
Tidak ada data provinsi yang cocok.
</div>
) : (
<div className="overflow-x-auto w-full max-h-[420px] overflow-y-auto">
<Table>
<TableHeader className="bg-muted/30 sticky top-0 backdrop-blur z-10">
<TableRow>
<TableHead className="px-6 py-3 min-w-[200px] text-[10px] uppercase font-bold text-muted-foreground tracking-wider">Provinsi / Wilayah</TableHead>
{activeTab === "gasoline" ? (
<>
<TableHead className="px-6 py-3 text-right text-[10px] uppercase font-bold text-muted-foreground tracking-wider">Pertalite (90)</TableHead>
<TableHead className="px-6 py-3 text-right text-[10px] uppercase font-bold text-muted-foreground tracking-wider">Pertamax (92)</TableHead>
<TableHead className="px-6 py-3 text-right text-[10px] uppercase font-bold text-muted-foreground tracking-wider">Pertamax Green 95</TableHead>
<TableHead className="px-6 py-3 text-right text-[10px] uppercase font-bold text-muted-foreground tracking-wider">Pertamax Turbo (98)</TableHead>
<TableHead className="px-6 py-3 text-right text-[10px] uppercase font-bold text-muted-foreground tracking-wider">Pertamax Pertashop</TableHead>
</>
) : (
<>
<TableHead className="px-6 py-3 text-right text-[10px] uppercase font-bold text-muted-foreground tracking-wider">Bio Solar (Subsidi)</TableHead>
<TableHead className="px-6 py-3 text-right text-[10px] uppercase font-bold text-muted-foreground tracking-wider">Bio Solar (Non-Sub)</TableHead>
<TableHead className="px-6 py-3 text-right text-[10px] uppercase font-bold text-muted-foreground tracking-wider">Dexlite</TableHead>
<TableHead className="px-6 py-3 text-right text-[10px] uppercase font-bold text-muted-foreground tracking-wider">Pertamina Dex</TableHead>
</>
)}
</TableRow>
</TableHeader>
<TableBody>
{filteredData.map((row) => {
const isKalbar = row.region === "Prov. Kalimantan Barat";
return (
<TableRow
key={row.region}
className={`text-xs transition-colors hover:bg-muted/40 h-12 ${
isKalbar
? "bg-amber-500/5 hover:bg-amber-500/10 border-l-4 border-l-amber-500 font-semibold"
: ""
}`}
>
<TableCell className="px-6 py-3.5 font-medium flex items-center gap-2">
{isKalbar && (
<span className="h-1.5 w-1.5 rounded-full bg-amber-500 animate-pulse" />
)}
{row.region}
</TableCell>
{activeTab === "gasoline" ? (
<>
<TableCell className="px-6 py-3.5 text-right">{formatVal(row.pertalite)}</TableCell>
<TableCell className="px-6 py-3.5 text-right">{formatVal(row.pertamax)}</TableCell>
<TableCell className="px-6 py-3.5 text-right">{formatVal(row.pertamaxGreen)}</TableCell>
<TableCell className="px-6 py-3.5 text-right">{formatVal(row.pertamaxTurbo)}</TableCell>
<TableCell className="px-6 py-3.5 text-right">{formatVal(row.pertamaxPertashop)}</TableCell>
</>
) : (
<>
<TableCell className="px-6 py-3.5 text-right">{formatVal(row.bioSolarSubsidi)}</TableCell>
<TableCell className="px-6 py-3.5 text-right">{formatVal(row.bioSolarNonSubsidi)}</TableCell>
<TableCell className="px-6 py-3.5 text-right">{formatVal(row.dexlite)}</TableCell>
<TableCell className="px-6 py-3.5 text-right">{formatVal(row.pertaminaDex)}</TableCell>
</>
)}
</TableRow>
);
})}
</TableBody>
</Table>
</div>
)}
</CardContent>
</DashboardCard>
);
}