Add scroll area to widget settings modal
Some checks failed
Build Frontend / build (push) Failing after 6s

Wrapped the widget settings modal content in a ScrollArea to improve usability when there are many settings, preventing overflow and keeping the modal compact.
This commit is contained in:
g
2026-01-12 10:41:52 +00:00
parent 318927cd0c
commit 9acd18955e

View File

@@ -22,6 +22,7 @@ import {
} 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
@@ -69,213 +70,215 @@ export function WidgetSettingsModal({ widget, open, onOpenChange, onSave }: Widg
</DialogDescription>
</DialogHeader>
<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>
<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>
<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)}>