feat(fuel-logs): add project Month/Week badge and filter

This commit is contained in:
DEls 2026-09-11 22:29:13 +02:00
parent 4ae138686a
commit 67785fe2b3
2 changed files with 36 additions and 3 deletions

View file

@ -33,6 +33,12 @@ import {
} from "@/components/ui/table";
import { Pagination } from "@/components/ui/pagination";
import { cn, formatCurrency, formatNumber } from "@/lib/utils";
import {
type ProjectPeriodFilterValue,
type ProjectPeriodLabel,
matchesProjectPeriodFilter,
} from "@/lib/project-calendar";
import { ProjectPeriodBadge } from "@/components/project-period-badge";
export interface FuelLogRow {
id: string;
@ -49,6 +55,7 @@ export interface FuelLogRow {
latestConsumption: number | null;
hasDocument: boolean;
documentStatus?: string | null;
projectPeriod: ProjectPeriodLabel | null;
}
type UnitFilter = "all" | "fuel" | "plant";
@ -64,6 +71,7 @@ export function FuelLogsView({
const [siteFilter, setSiteFilter] = React.useState<string>("all");
const [unitFilter, setUnitFilter] = React.useState<UnitFilter>("all");
const [sourceFilter, setSourceFilter] = React.useState<SourceFilter>("all");
const [periodFilter, setPeriodFilter] = React.useState<ProjectPeriodFilterValue>("all");
const [search, setSearch] = React.useState("");
const [page, setPage] = React.useState(1);
@ -74,13 +82,14 @@ export function FuelLogsView({
if (unitFilter !== "all" && r.unitType !== unitFilter) return false;
if (sourceFilter === "uploaded" && !r.hasDocument) return false;
if (sourceFilter === "direct" && r.hasDocument) return false;
if (!matchesProjectPeriodFilter(periodFilter, r.projectPeriod)) return false;
if (q) {
const hay = `${r.vehicleDescription}`.toLowerCase();
if (!hay.includes(q)) return false;
}
return true;
});
}, [rows, siteFilter, unitFilter, sourceFilter, search]);
}, [rows, siteFilter, unitFilter, sourceFilter, periodFilter, search]);
// KPIs from the FULL dataset
const kpis = React.useMemo(() => {
@ -114,10 +123,10 @@ export function FuelLogsView({
React.useEffect(() => {
setPage(1);
}, [siteFilter, unitFilter, sourceFilter, search]);
}, [siteFilter, unitFilter, sourceFilter, periodFilter, search]);
const filtersActive =
siteFilter !== "all" || unitFilter !== "all" || sourceFilter !== "all" || search !== "";
siteFilter !== "all" || unitFilter !== "all" || sourceFilter !== "all" || periodFilter !== "all" || search !== "";
return (
<div className="space-y-6 p-4 sm:p-6">
@ -196,6 +205,18 @@ export function FuelLogsView({
]}
/>
<SelectFilter
label="Period"
value={periodFilter}
onChange={(v) => setPeriodFilter(v as ProjectPeriodFilterValue)}
options={[
{ value: "all", label: "All time" },
{ value: "today", label: "Today" },
{ value: "week", label: "This week" },
{ value: "month", label: "This month" },
]}
/>
{filtersActive && (
<Button
variant="ghost"
@ -204,6 +225,7 @@ export function FuelLogsView({
setSiteFilter("all");
setUnitFilter("all");
setSourceFilter("all");
setPeriodFilter("all");
setSearch("");
}}
>
@ -238,6 +260,7 @@ export function FuelLogsView({
<TableHead>Date</TableHead>
<TableHead>Vehicle / equipment</TableHead>
<TableHead>Site</TableHead>
<TableHead>Month/Week</TableHead>
<TableHead className="text-right">Litres</TableHead>
<TableHead className="text-right">Reading</TableHead>
<TableHead className="text-right">Cost</TableHead>
@ -284,6 +307,9 @@ export function FuelLogsView({
)}
</div>
</TableCell>
<TableCell>
<ProjectPeriodBadge period={r.projectPeriod} />
</TableCell>
<TableCell className="text-right tabular-nums">
{formatNumber(r.litres, { maximumFractionDigits: 2 })} L
</TableCell>

View file

@ -4,6 +4,7 @@ import { ImportFuelLogsButton } from "@/components/import-fuel-logs-button";
import { resolveFuelPrice } from "@/lib/metrics";
import { loadFuelPrices } from "@/lib/fuel-prices";
import { FuelLogsView, type FuelLogRow } from "./fuel-logs-view";
import { deriveProjectPeriodLabel } from "@/lib/project-calendar";
export const dynamic = "force-dynamic";
@ -28,6 +29,7 @@ export default async function FuelLogsPage() {
documents.map((d) => [d.id, d.processing_status ?? ""]),
);
const fuelPrices = await loadFuelPrices();
const now = new Date();
const rows: FuelLogRow[] = logs.map((l) => {
const v =
@ -60,6 +62,11 @@ export default async function FuelLogsPage() {
documentStatus: fuelSheetId
? docStatusById.get(fuelSheetId) ?? null
: null,
projectPeriod: deriveProjectPeriodLabel(
l.date_logged ?? "",
siteById.get(l.site) ?? {},
now,
),
};
});