Files
pn-new-crm/src/components/reports/generate-report-form.tsx

143 lines
4.3 KiB
TypeScript
Raw Normal View History

'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 {
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';
const REPORT_TYPE_LABELS: Record<string, string> = {
pipeline: 'Pipeline Summary',
revenue: 'Revenue Report',
activity: 'Activity Log',
occupancy: 'Berth Occupancy',
};
export function GenerateReportForm() {
const queryClient = useQueryClient();
const [reportType, setReportType] = useState<string>('');
const [name, setName] = useState<string>('');
const [dateFrom, setDateFrom] = useState<string>('');
const [dateTo, setDateTo] = useState<string>('');
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 (
<Card>
<CardHeader>
<CardTitle>Generate Report</CardTitle>
</CardHeader>
<CardContent>
<form onSubmit={handleSubmit} className="space-y-4">
<div className="grid gap-2">
<Label htmlFor="reportType">Report Type</Label>
<Select value={reportType} onValueChange={setReportType}>
<SelectTrigger id="reportType">
<SelectValue placeholder="Select a report type..." />
</SelectTrigger>
<SelectContent>
{Object.entries(REPORT_TYPE_LABELS).map(([value, label]) => (
<SelectItem key={value} value={value}>
{label}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
<div className="grid gap-2">
<Label htmlFor="name">Report Name</Label>
<Input
id="name"
value={name}
onChange={(e) => setName(e.target.value)}
placeholder="e.g. Pipeline Summary Q1 2025"
maxLength={200}
/>
</div>
<div className="grid grid-cols-2 gap-4">
<div className="grid gap-2">
<Label htmlFor="dateFrom">Date From (optional)</Label>
<Input
id="dateFrom"
type="date"
value={dateFrom}
onChange={(e) => setDateFrom(e.target.value)}
/>
</div>
<div className="grid gap-2">
<Label htmlFor="dateTo">Date To (optional)</Label>
<Input
id="dateTo"
type="date"
value={dateTo}
onChange={(e) => setDateTo(e.target.value)}
/>
</div>
</div>
{mutation.isError && (
<p className="text-sm text-destructive">
{mutation.error instanceof Error
? mutation.error.message
: 'Failed to queue report. Please try again.'}
</p>
)}
{mutation.isSuccess && (
<p className="text-sm text-green-600">
Report queued successfully. You will be notified when it is ready.
</p>
)}
<Button
type="submit"
disabled={!reportType || !name.trim() || mutation.isPending}
>
{mutation.isPending ? 'Queuing...' : 'Generate Report'}
</Button>
</form>
</CardContent>
</Card>
);
}