feat(users): implement advanced user actions (notifications, moderation, support, audit)
This commit is contained in:
134
src/features/users/components/dialogs/OrdersExportPopover.tsx
Normal file
134
src/features/users/components/dialogs/OrdersExportPopover.tsx
Normal file
@@ -0,0 +1,134 @@
|
||||
'use client';
|
||||
|
||||
import { useState } from 'react';
|
||||
import {
|
||||
Popover,
|
||||
PopoverContent,
|
||||
PopoverTrigger,
|
||||
} from '@/components/ui/popover';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Label } from '@/components/ui/label';
|
||||
import { Checkbox } from '@/components/ui/checkbox';
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from '@/components/ui/select';
|
||||
import { Download, FileDown, CalendarDays } from 'lucide-react';
|
||||
import { toast } from 'sonner';
|
||||
|
||||
interface OrdersExportPopoverProps {
|
||||
onExport: (options: ExportOptions) => void;
|
||||
}
|
||||
|
||||
export interface ExportOptions {
|
||||
range: string;
|
||||
includeColumns: string[];
|
||||
respectFilters: boolean;
|
||||
}
|
||||
|
||||
const AVAILABLE_COLUMNS = [
|
||||
{ id: 'id', label: 'Order ID' },
|
||||
{ id: 'eventName', label: 'Event Name' },
|
||||
{ id: 'amount', label: 'Amount' },
|
||||
{ id: 'status', label: 'Status' },
|
||||
{ id: 'date', label: 'Date' },
|
||||
{ id: 'customer', label: 'Customer Info' },
|
||||
];
|
||||
|
||||
export function OrdersExportPopover({ onExport }: OrdersExportPopoverProps) {
|
||||
const [range, setRange] = useState('30d');
|
||||
const [respectFilters, setRespectFilters] = useState(true);
|
||||
const [selectedColumns, setSelectedColumns] = useState<string[]>(AVAILABLE_COLUMNS.map(c => c.id));
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
const handleColumnToggle = (id: string, checked: boolean) => {
|
||||
if (checked) {
|
||||
setSelectedColumns([...selectedColumns, id]);
|
||||
} else {
|
||||
setSelectedColumns(selectedColumns.filter(c => c !== id));
|
||||
}
|
||||
};
|
||||
|
||||
const handleExport = () => {
|
||||
onExport({ range, includeColumns: selectedColumns, respectFilters });
|
||||
setOpen(false);
|
||||
toast.promise(new Promise(resolve => setTimeout(resolve, 2000)), {
|
||||
loading: 'Generating CSV...',
|
||||
success: 'Export downloaded successfully!',
|
||||
error: 'Failed to export'
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<Popover open={open} onOpenChange={setOpen}>
|
||||
<PopoverTrigger asChild>
|
||||
<Button variant="outline" size="sm" className="h-8 gap-2">
|
||||
<FileDown className="h-3.5 w-3.5" />
|
||||
Export CSV
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="w-80 p-0" align="end">
|
||||
<div className="p-4 border-b border-border/50 bg-secondary/5">
|
||||
<h4 className="font-semibold text-sm">Export Options</h4>
|
||||
<p className="text-xs text-muted-foreground">Customize your data export.</p>
|
||||
</div>
|
||||
|
||||
<div className="p-4 space-y-4">
|
||||
<div className="space-y-2">
|
||||
<Label className="text-xs">Date Range</Label>
|
||||
<Select value={range} onValueChange={setRange}>
|
||||
<SelectTrigger className="h-8">
|
||||
<SelectValue placeholder="Select range" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="7d">Last 7 Days</SelectItem>
|
||||
<SelectItem value="30d">Last 30 Days</SelectItem>
|
||||
<SelectItem value="90d">Last 3 months</SelectItem>
|
||||
<SelectItem value="all">All Time</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label className="text-xs">Columns</Label>
|
||||
<div className="grid grid-cols-2 gap-2">
|
||||
{AVAILABLE_COLUMNS.map(col => (
|
||||
<div key={col.id} className="flex items-center space-x-2">
|
||||
<Checkbox
|
||||
id={`col-${col.id}`}
|
||||
checked={selectedColumns.includes(col.id)}
|
||||
onCheckedChange={(c) => handleColumnToggle(col.id, c as boolean)}
|
||||
className="h-3.5 w-3.5"
|
||||
/>
|
||||
<Label htmlFor={`col-${col.id}`} className="text-xs font-normal cursor-pointer">
|
||||
{col.label}
|
||||
</Label>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center space-x-2 pt-1">
|
||||
<Checkbox
|
||||
id="respect-filters"
|
||||
checked={respectFilters}
|
||||
onCheckedChange={(c) => setRespectFilters(c as boolean)}
|
||||
/>
|
||||
<Label htmlFor="respect-filters" className="text-xs font-normal cursor-pointer">
|
||||
Apply current table filters
|
||||
</Label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="p-3 bg-secondary/5 border-t border-border/50 flex justify-end">
|
||||
<Button size="sm" onClick={handleExport} className="w-full">
|
||||
<Download className="mr-2 h-3.5 w-3.5" /> Download .CSV
|
||||
</Button>
|
||||
</div>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user