'use client'; import { useState } from 'react'; import { useMutation, useQueryClient } from '@tanstack/react-query'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { DatePicker } from '@/components/ui/date-picker'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { apiFetch } from '@/lib/api/client'; import type { RequestReportInput } from '@/lib/validators/reports'; interface ReportTypeMeta { label: string; subtitle: string; contents: string[]; } const REPORT_TYPES: Record = { pipeline: { label: 'Pipeline Summary', subtitle: 'Interest counts by stage and conversion rates', contents: [ 'Active (non-archived) interests grouped by pipeline stage', 'Stage-to-stage drop-off counts', 'Open vs. won vs. lost roll-up at the bottom', ], }, revenue: { label: 'Revenue Report', subtitle: 'Berth-price totals rolled up by pipeline stage', contents: [ 'Sum of primary-berth prices grouped by stage', 'Pulled from each interest’s primary berth link (non-primary junctions ignored)', 'Sold-stage total reflects realised revenue; earlier stages are forecast', ], }, activity: { label: 'Activity Log', subtitle: 'Audit events across the port for a date range', contents: [ 'Audit log entries (create / update / delete) per entity', 'Filtered to the selected date range - defaults to last 30 days', 'Includes actor name, entity type, and action verb', ], }, occupancy: { label: 'Berth Occupancy', subtitle: 'Berth counts by status', contents: [ 'Berths grouped by status: Available, Under Offer, Sold', 'Per-dock breakdown using the mooring-letter prefix', 'Total port utilisation percentage at the top', ], }, }; export function GenerateReportForm() { const queryClient = useQueryClient(); const [reportType, setReportType] = useState(''); const [name, setName] = useState(''); const [dateFrom, setDateFrom] = useState(''); const [dateTo, setDateTo] = useState(''); const mutation = useMutation({ mutationFn: (data: RequestReportInput) => apiFetch('/api/v1/reports', { method: 'POST', body: data }), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['reports'] }); setReportType(''); setName(''); setDateFrom(''); setDateTo(''); }, }); const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); if (!reportType || !name.trim()) return; const payload: RequestReportInput = { reportType: reportType as RequestReportInput['reportType'], name: name.trim(), parameters: { ...(dateFrom ? { dateFrom } : {}), ...(dateTo ? { dateTo } : {}), }, }; mutation.mutate(payload); }; return ( Generate Report
{reportType && REPORT_TYPES[reportType] ? (

{REPORT_TYPES[reportType].subtitle}

    {REPORT_TYPES[reportType].contents.map((line) => (
  • {line}
  • ))}
) : null}
setName(e.target.value)} placeholder="e.g. Pipeline Summary Q1 2025" maxLength={200} />
{mutation.isError && (

{mutation.error instanceof Error ? mutation.error.message : 'Failed to queue report. Please try again.'}

)} {mutation.isSuccess && (

Report queued successfully. You will be notified when it is ready.

)}
); }