mirror of
https://github.com/escalante29/WealthySmart.git
synced 2026-05-19 11:28:49 +02:00
All checks were successful
Deploy to VPS / deploy (push) Successful in 28s
Replace custom markup across all pages and components with shadcn/ui primitives (Dialog, Sheet, Select, Card, Tabs, etc.). Add reusable DataTable component powered by @tanstack/react-table with sortable column headers and client-side pagination. Introduce TransactionList with responsive mobile cards and desktop DataTable, dashboard section customization (DashboardSection, SectionConfigDialog), and settings API types. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
138 lines
4.0 KiB
TypeScript
138 lines
4.0 KiB
TypeScript
import { useState } from 'react';
|
|
import type { SectionSettings } from '../api';
|
|
import { Button } from '@/components/ui/button';
|
|
import { Input } from '@/components/ui/input';
|
|
import { Label } from '@/components/ui/label';
|
|
import {
|
|
Dialog,
|
|
DialogContent,
|
|
DialogHeader,
|
|
DialogTitle,
|
|
DialogFooter,
|
|
} from '@/components/ui/dialog';
|
|
import {
|
|
Select,
|
|
SelectContent,
|
|
SelectItem,
|
|
SelectTrigger,
|
|
SelectValue,
|
|
} from '@/components/ui/select';
|
|
import { COLOR_OPTIONS, getColorClasses } from '@/lib/colors';
|
|
import { cn } from '@/lib/utils';
|
|
|
|
interface Props {
|
|
sectionId: string;
|
|
settings: SectionSettings;
|
|
open: boolean;
|
|
onOpenChange: (open: boolean) => void;
|
|
onSave: (sectionId: string, updated: Partial<SectionSettings>) => void;
|
|
}
|
|
|
|
function ColorSwatch({ color }: { color: string }) {
|
|
const classes = getColorClasses(color);
|
|
return (
|
|
<span className="flex items-center gap-2">
|
|
<span className={cn('w-3 h-3 rounded-full', classes.bg, classes.ring, 'ring-1')} />
|
|
{color}
|
|
</span>
|
|
);
|
|
}
|
|
|
|
export default function SectionConfigDialog({ sectionId, settings, open, onOpenChange, onSave }: Props) {
|
|
const [label, setLabel] = useState(settings.label);
|
|
const [color, setColor] = useState(settings.color);
|
|
const [cardColor, setCardColor] = useState(settings.cardColor);
|
|
const [visible, setVisible] = useState(settings.visible);
|
|
const [order, setOrder] = useState(String(settings.order));
|
|
|
|
const handleSave = () => {
|
|
onSave(sectionId, {
|
|
label,
|
|
color,
|
|
cardColor,
|
|
visible,
|
|
order: parseInt(order) || 0,
|
|
});
|
|
onOpenChange(false);
|
|
};
|
|
|
|
return (
|
|
<Dialog open={open} onOpenChange={onOpenChange}>
|
|
<DialogContent className="sm:max-w-md">
|
|
<DialogHeader>
|
|
<DialogTitle>Configure Section</DialogTitle>
|
|
</DialogHeader>
|
|
|
|
<div className="space-y-4">
|
|
<div className="space-y-2">
|
|
<Label>Label</Label>
|
|
<Input value={label} onChange={(e) => setLabel(e.target.value)} />
|
|
</div>
|
|
|
|
<div className="space-y-2">
|
|
<Label>Section Color</Label>
|
|
<Select value={color} onValueChange={setColor}>
|
|
<SelectTrigger className="w-full">
|
|
<SelectValue />
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
{COLOR_OPTIONS.map((c) => (
|
|
<SelectItem key={c} value={c}>
|
|
<ColorSwatch color={c} />
|
|
</SelectItem>
|
|
))}
|
|
</SelectContent>
|
|
</Select>
|
|
</div>
|
|
|
|
<div className="space-y-2">
|
|
<Label>Card Color</Label>
|
|
<Select value={cardColor} onValueChange={setCardColor}>
|
|
<SelectTrigger className="w-full">
|
|
<SelectValue />
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
{COLOR_OPTIONS.map((c) => (
|
|
<SelectItem key={c} value={c}>
|
|
<ColorSwatch color={c} />
|
|
</SelectItem>
|
|
))}
|
|
</SelectContent>
|
|
</Select>
|
|
</div>
|
|
|
|
<div className="flex items-center gap-3">
|
|
<Label htmlFor={`visible-${sectionId}`}>Visible</Label>
|
|
<input
|
|
id={`visible-${sectionId}`}
|
|
type="checkbox"
|
|
checked={visible}
|
|
onChange={(e) => setVisible(e.target.checked)}
|
|
className="h-4 w-4 rounded border-input accent-primary cursor-pointer"
|
|
/>
|
|
</div>
|
|
|
|
<div className="space-y-2">
|
|
<Label>Order</Label>
|
|
<Input
|
|
type="number"
|
|
min="0"
|
|
max="10"
|
|
value={order}
|
|
onChange={(e) => setOrder(e.target.value)}
|
|
className="w-20"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<DialogFooter>
|
|
<Button variant="outline" onClick={() => onOpenChange(false)}>
|
|
Cancel
|
|
</Button>
|
|
<Button onClick={handleSave}>Save</Button>
|
|
</DialogFooter>
|
|
</DialogContent>
|
|
</Dialog>
|
|
);
|
|
}
|