Files
ember-market-frontend/components/dashboard/widget-settings-modal.tsx
g 9acd18955e
Some checks failed
Build Frontend / build (push) Failing after 6s
Add scroll area to widget settings modal
Wrapped the widget settings modal content in a ScrollArea to improve usability when there are many settings, preventing overflow and keeping the modal compact.
2026-01-12 10:41:52 +00:00

295 lines
16 KiB
TypeScript

"use client"
import { useState } from "react"
import { Button } from "@/components/ui/button"
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
DialogDescription,
DialogFooter,
} from "@/components/ui/dialog"
import { Label } from "@/components/ui/label"
import { Input } from "@/components/ui/input"
import { Switch } from "@/components/ui/switch"
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select"
import { WidgetConfig } from "@/hooks/useWidgetLayout"
import { Settings2 } from "lucide-react"
import { ScrollArea } from "@/components/ui/scroll-area"
interface WidgetSettingsModalProps {
widget: WidgetConfig | null
open: boolean
onOpenChange: (open: boolean) => void
onSave: (widgetId: string, settings: Record<string, any>, colSpan: number) => void
}
export function WidgetSettingsModal({ widget, open, onOpenChange, onSave }: WidgetSettingsModalProps) {
const [localSettings, setLocalSettings] = useState<Record<string, any>>({})
const [localColSpan, setLocalColSpan] = useState<number>(4)
// Initialize local settings when widget changes
const handleOpenChange = (isOpen: boolean) => {
if (isOpen && widget) {
setLocalSettings({ ...widget.settings })
setLocalColSpan(widget.colSpan || 4)
}
onOpenChange(isOpen)
}
const handleSave = () => {
if (widget) {
onSave(widget.id, localSettings, localColSpan)
onOpenChange(false)
}
}
const updateSetting = (key: string, value: any) => {
setLocalSettings(prev => ({ ...prev, [key]: value }))
}
if (!widget) return null
return (
<Dialog open={open} onOpenChange={handleOpenChange}>
<DialogContent className="sm:max-w-md">
<DialogHeader>
<DialogTitle className="flex items-center gap-2">
<Settings2 className="h-5 w-5" />
{widget.title} Settings
</DialogTitle>
<DialogDescription>
Customize how this widget displays on your dashboard.
</DialogDescription>
</DialogHeader>
<ScrollArea className="max-h-[60vh] -mr-4 pr-4">
<div className="space-y-6 py-4">
{/* Resize Selection */}
<div className="space-y-3 pb-6 border-b border-border/40">
<Label className="text-xs font-semibold text-muted-foreground uppercase tracking-wider">Widget Display</Label>
<div className="flex items-center justify-between">
<Label htmlFor="colSpan" className="text-sm font-medium">Widget Width</Label>
<Select
value={String(localColSpan)}
onValueChange={(v) => setLocalColSpan(parseInt(v))}
>
<SelectTrigger className="w-40">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="1">Small (1/4)</SelectItem>
<SelectItem value="2">Medium (1/2)</SelectItem>
<SelectItem value="3">Large (3/4)</SelectItem>
<SelectItem value="4">Full Width</SelectItem>
</SelectContent>
</Select>
</div>
</div>
<div className="space-y-4">
{/* Recent Activity Settings */}
{widget.id === "recent-activity" && (
<div className="space-y-4">
<div className="flex items-center justify-between">
<Label htmlFor="itemCount">Number of items</Label>
<Select
value={String(localSettings.itemCount || 10)}
onValueChange={(v) => updateSetting("itemCount", parseInt(v))}
>
<SelectTrigger className="w-24">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="5">5</SelectItem>
<SelectItem value="10">10</SelectItem>
<SelectItem value="15">15</SelectItem>
<SelectItem value="20">20</SelectItem>
</SelectContent>
</Select>
</div>
</div>
)}
{/* Top Products Settings */}
{widget.id === "top-products" && (
<div className="space-y-4">
<div className="flex items-center justify-between">
<Label htmlFor="itemCount">Number of products</Label>
<Select
value={String(localSettings.itemCount || 5)}
onValueChange={(v) => updateSetting("itemCount", parseInt(v))}
>
<SelectTrigger className="w-24">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="3">3</SelectItem>
<SelectItem value="5">5</SelectItem>
<SelectItem value="10">10</SelectItem>
</SelectContent>
</Select>
</div>
<div className="flex items-center justify-between">
<Label htmlFor="showRevenue">Show revenue</Label>
<Switch
id="showRevenue"
checked={localSettings.showRevenue ?? true}
onCheckedChange={(checked) => updateSetting("showRevenue", checked)}
/>
</div>
</div>
)}
{/* Revenue Chart Settings */}
{widget.id === "revenue-chart" && (
<div className="space-y-4">
<div className="flex items-center justify-between">
<Label htmlFor="days">Time period</Label>
<Select
value={String(localSettings.days || 7)}
onValueChange={(v) => updateSetting("days", parseInt(v))}
>
<SelectTrigger className="w-32">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="7">Last 7 days</SelectItem>
<SelectItem value="14">Last 14 days</SelectItem>
<SelectItem value="30">Last 30 days</SelectItem>
</SelectContent>
</Select>
</div>
<div className="flex items-center justify-between">
<Label htmlFor="showComparison">Show comparison</Label>
<Switch
id="showComparison"
checked={localSettings.showComparison ?? false}
onCheckedChange={(checked) => updateSetting("showComparison", checked)}
/>
</div>
</div>
)}
{/* Low Stock Settings */}
{widget.id === "low-stock" && (
<div className="space-y-4">
<div className="flex items-center justify-between">
<Label htmlFor="threshold">Stock threshold</Label>
<Input
id="threshold"
type="number"
className="w-24"
value={localSettings.threshold || 5}
onChange={(e) => updateSetting("threshold", parseInt(e.target.value) || 5)}
min={1}
max={100}
/>
</div>
<div className="flex items-center justify-between">
<Label htmlFor="itemCount">Max items to show</Label>
<Select
value={String(localSettings.itemCount || 5)}
onValueChange={(v) => updateSetting("itemCount", parseInt(v))}
>
<SelectTrigger className="w-24">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="3">3</SelectItem>
<SelectItem value="5">5</SelectItem>
<SelectItem value="10">10</SelectItem>
</SelectContent>
</Select>
</div>
</div>
)}
{/* Recent Customers Settings */}
{widget.id === "recent-customers" && (
<div className="space-y-4">
<div className="flex items-center justify-between">
<Label htmlFor="itemCount">Number of customers</Label>
<Select
value={String(localSettings.itemCount || 5)}
onValueChange={(v) => updateSetting("itemCount", parseInt(v))}
>
<SelectTrigger className="w-24">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="3">3</SelectItem>
<SelectItem value="5">5</SelectItem>
<SelectItem value="10">10</SelectItem>
</SelectContent>
</Select>
</div>
<div className="flex items-center justify-between">
<Label htmlFor="showSpent">Show amount spent</Label>
<Switch
id="showSpent"
checked={localSettings.showSpent ?? true}
onCheckedChange={(checked) => updateSetting("showSpent", checked)}
/>
</div>
</div>
)}
{/* Pending Chats Settings */}
{widget.id === "pending-chats" && (
<div className="space-y-4">
<div className="flex items-center justify-between">
<Label htmlFor="showPreview">Show message preview</Label>
<Switch
id="showPreview"
checked={localSettings.showPreview ?? true}
onCheckedChange={(checked) => updateSetting("showPreview", checked)}
/>
</div>
</div>
)}
{/* Overview Settings */}
{widget.id === "overview" && (
<div className="space-y-4">
<div className="flex items-center justify-between">
<Label htmlFor="showChange">Show percentage change</Label>
<Switch
id="showChange"
checked={localSettings.showChange ?? false}
onCheckedChange={(checked) => updateSetting("showChange", checked)}
/>
</div>
</div>
)}
{/* Quick Actions - no settings */}
{widget.id === "quick-actions" && (
<p className="text-sm text-muted-foreground text-center py-4">
This widget has no customizable settings.
</p>
)}
</div>
</div>
</ScrollArea>
<DialogFooter>
<Button variant="outline" onClick={() => onOpenChange(false)}>
Cancel
</Button>
<Button onClick={handleSave}>
Save Changes
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
)
}