feat(ui): enhance settings dialog with tabbed interface and scrollable areas

- Add Radix UI scroll-area and tabs components
- Redesign settings dialog with tabbed layout for better organization
- Add Card components for structured content display
- Update accounts and profiles tables UI
- Add scrollable areas for better content management
- Improve overall dialog loading and styling
This commit is contained in:
kaitranntt
2025-12-07 21:41:17 -05:00
parent 1f215d8ecb
commit 4adb94b90c
9 changed files with 224 additions and 67 deletions
+8
View File
@@ -10,8 +10,10 @@
"@radix-ui/react-dialog": "^1.1.15",
"@radix-ui/react-dropdown-menu": "^2.1.16",
"@radix-ui/react-label": "^2.1.8",
"@radix-ui/react-scroll-area": "^1.2.10",
"@radix-ui/react-separator": "^1.1.8",
"@radix-ui/react-slot": "^1.2.4",
"@radix-ui/react-tabs": "^1.1.13",
"@radix-ui/react-tooltip": "^1.2.8",
"@tanstack/react-query": "^5.90.12",
"@tanstack/react-table": "^8.21.3",
@@ -184,6 +186,8 @@
"@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
"@radix-ui/number": ["@radix-ui/number@1.1.1", "", {}, "sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g=="],
"@radix-ui/primitive": ["@radix-ui/primitive@1.1.3", "", {}, "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg=="],
"@radix-ui/react-alert-dialog": ["@radix-ui/react-alert-dialog@1.1.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dialog": "1.1.15", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-oTVLkEw5GpdRe29BqJ0LSDFWI3qu0vR1M0mUkOQWDIUnY/QIkLpgDMWuKxP94c2NAC2LGcgVhG1ImF3jkZ5wXw=="],
@@ -226,10 +230,14 @@
"@radix-ui/react-roving-focus": ["@radix-ui/react-roving-focus@1.1.11", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA=="],
"@radix-ui/react-scroll-area": ["@radix-ui/react-scroll-area@1.2.10", "", { "dependencies": { "@radix-ui/number": "1.1.1", "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-tAXIa1g3sM5CGpVT0uIbUx/U3Gs5N8T52IICuCtObaos1S8fzsrPXG5WObkQN3S6NVl6wKgPhAIiBGbWnvc97A=="],
"@radix-ui/react-separator": ["@radix-ui/react-separator@1.1.8", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.4" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-sDvqVY4itsKwwSMEe0jtKgfTh+72Sy3gPmQpjqcQneqQ4PFmr/1I0YA+2/puilhggCe2gJcx5EBAYFkWkdpa5g=="],
"@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.4", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA=="],
"@radix-ui/react-tabs": ["@radix-ui/react-tabs@1.1.13", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-roving-focus": "1.1.11", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A=="],
"@radix-ui/react-tooltip": ["@radix-ui/react-tooltip@1.2.8", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-visually-hidden": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-tY7sVt1yL9ozIxvmbtN5qtmH2krXcBCfjEiCgKGLqunJHvgvZG2Pcl2oQ3kbcZARb1BGEHdkLzcYGO8ynVlieg=="],
"@radix-ui/react-use-callback-ref": ["@radix-ui/react-use-callback-ref@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg=="],
+2
View File
@@ -21,8 +21,10 @@
"@radix-ui/react-dialog": "^1.1.15",
"@radix-ui/react-dropdown-menu": "^2.1.16",
"@radix-ui/react-label": "^2.1.8",
"@radix-ui/react-scroll-area": "^1.2.10",
"@radix-ui/react-separator": "^1.1.8",
"@radix-ui/react-slot": "^1.2.4",
"@radix-ui/react-tabs": "^1.1.13",
"@radix-ui/react-tooltip": "^1.2.8",
"@tanstack/react-query": "^5.90.12",
"@tanstack/react-table": "^8.21.3",
+18 -10
View File
@@ -29,11 +29,12 @@ export function AccountsTable({ data, defaultAccount }: AccountsTableProps) {
{
accessorKey: 'name',
header: 'Name',
size: 200,
cell: ({ row }) => (
<div className="flex items-center gap-2">
{row.original.name}
<span className="font-medium">{row.original.name}</span>
{row.original.name === defaultAccount && (
<span className="text-xs bg-primary text-primary-foreground px-1.5 py-0.5 rounded">
<span className="text-xs bg-primary/10 text-primary px-1.5 py-0.5 rounded border border-primary/20">
default
</span>
)}
@@ -43,39 +44,46 @@ export function AccountsTable({ data, defaultAccount }: AccountsTableProps) {
{
accessorKey: 'type',
header: 'Type',
cell: ({ row }) => row.original.type || 'oauth',
size: 100,
cell: ({ row }) => (
<span className="capitalize text-muted-foreground">{row.original.type || 'oauth'}</span>
),
},
{
accessorKey: 'created',
header: 'Created',
size: 150,
cell: ({ row }) => {
const date = new Date(row.original.created);
return date.toLocaleDateString();
return <span className="text-muted-foreground">{date.toLocaleDateString()}</span>;
},
},
{
accessorKey: 'last_used',
header: 'Last Used',
size: 150,
cell: ({ row }) => {
if (!row.original.last_used) return '-';
if (!row.original.last_used) return <span className="text-muted-foreground/50">-</span>;
const date = new Date(row.original.last_used);
return date.toLocaleDateString();
return <span className="text-muted-foreground">{date.toLocaleDateString()}</span>;
},
},
{
id: 'actions',
header: 'Actions',
size: 100,
cell: ({ row }) => {
const isDefault = row.original.name === defaultAccount;
return (
<Button
variant={isDefault ? 'outline' : 'default'}
variant={isDefault ? 'secondary' : 'default'}
size="sm"
className="h-8 px-2 w-full"
disabled={isDefault || setDefaultMutation.isPending}
onClick={() => setDefaultMutation.mutate(row.original.name)}
>
<Check className="w-4 h-4 mr-1" />
{isDefault ? 'Default' : 'Set Default'}
<Check className={`w-3 h-3 mr-1.5 ${isDefault ? 'opacity-50' : ''}`} />
{isDefault ? 'Active' : 'Set Default'}
</Button>
);
},
@@ -111,7 +119,7 @@ export function AccountsTable({ data, defaultAccount }: AccountsTableProps) {
type: 'w-[100px]',
created: 'w-[150px]',
last_used: 'w-[150px]',
actions: 'w-[120px]',
actions: 'w-[100px]',
}[header.id] || 'w-auto';
return (
+6 -13
View File
@@ -20,17 +20,16 @@ import {
DropdownMenuSeparator,
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import { MoreHorizontal, Trash2, Edit, Settings } from 'lucide-react';
import { MoreHorizontal, Trash2, Edit } from 'lucide-react';
import { useDeleteProfile } from '@/hooks/use-profiles';
import type { Profile } from '@/lib/api-client';
interface ProfilesTableProps {
data: Profile[];
onEdit?: (profile: Profile) => void;
onEditSettings?: (profile: Profile) => void;
}
export function ProfilesTable({ data, onEdit, onEditSettings }: ProfilesTableProps) {
export function ProfilesTable({ data, onEditSettings }: ProfilesTableProps) {
const deleteMutation = useDeleteProfile();
const columns: ColumnDef<Profile>[] = [
@@ -64,22 +63,16 @@ export function ProfilesTable({ data, onEdit, onEditSettings }: ProfilesTablePro
<MoreHorizontal className="w-4 h-4" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
{onEdit && (
<DropdownMenuItem onClick={() => onEdit(row.original)}>
<Edit className="w-4 h-4 mr-2" />
Edit Profile
</DropdownMenuItem>
)}
<DropdownMenuContent align="end" className="bg-white dark:bg-zinc-950 border shadow-md">
{onEditSettings && (
<DropdownMenuItem onClick={() => onEditSettings(row.original)}>
<Settings className="w-4 h-4 mr-2" />
Edit Settings
<Edit className="w-4 h-4 mr-2" />
Edit
</DropdownMenuItem>
)}
<DropdownMenuSeparator />
<DropdownMenuItem
className="text-red-600"
className="text-red-600 focus:text-red-600 focus:bg-red-100/50"
onClick={() => deleteMutation.mutate(row.original.name)}
>
<Trash2 className="w-4 h-4 mr-2" />
+86 -34
View File
@@ -42,6 +42,10 @@ interface SettingsDialogProps {
* Inner component that manages local edits state
* Gets unmounted/remounted via key prop when dialog closes/opens
*/
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import { ScrollArea } from '@/components/ui/scroll-area';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
function SettingsDialogContent({
profileName,
onClose,
@@ -147,42 +151,94 @@ function SettingsDialogContent({
return (
<>
<DialogHeader>
<DialogTitle>Environment Settings: {profileName}</DialogTitle>
<DialogTitle>Edit Profile: {profileName}</DialogTitle>
<DialogDescription>
Edit environment variables for this profile. Sensitive keys are masked.
Configure environment variables and settings for this profile.
</DialogDescription>
</DialogHeader>
{isLoading ? (
<div className="flex items-center justify-center py-8">
<Loader2 className="w-6 h-6 animate-spin text-muted-foreground" />
<span className="ml-2 text-muted-foreground">Loading settings...</span>
<div className="flex items-center justify-center py-12">
<Loader2 className="w-8 h-8 animate-spin text-muted-foreground" />
<span className="ml-3 text-muted-foreground">Loading settings...</span>
</div>
) : currentSettings?.env && Object.keys(currentSettings.env).length > 0 ? (
<div className="space-y-4">
{Object.entries(currentSettings.env).map(([key, value]) => (
<div key={key}>
<Label>{key}</Label>
{isSensitiveKey(key) ? (
<MaskedInput value={value} onChange={(e) => updateEnvValue(key, e.target.value)} />
) : (
<Input
value={value}
onChange={(e) => updateEnvValue(key, e.target.value)}
className="font-mono"
/>
)}
</div>
))}
) : (
<div className="flex flex-col h-[60vh]">
<Tabs defaultValue="env" className="flex-1 flex flex-col overflow-hidden">
<TabsList className="w-full justify-start border-b rounded-none p-0 h-auto bg-transparent">
<TabsTrigger
value="env"
className="rounded-none border-b-2 border-transparent data-[state=active]:border-primary data-[state=active]:bg-transparent px-4 py-2"
>
Environment
</TabsTrigger>
<TabsTrigger
value="general"
className="rounded-none border-b-2 border-transparent data-[state=active]:border-primary data-[state=active]:bg-transparent px-4 py-2"
>
General
</TabsTrigger>
</TabsList>
{data && (
<div className="pt-4 text-xs text-muted-foreground border-t">
<p>Path: {data.path}</p>
<p>Last modified: {new Date(data.mtime).toLocaleString()}</p>
</div>
)}
<TabsContent value="env" className="flex-1 overflow-hidden p-4 pt-4 m-0">
<ScrollArea className="h-full pr-4">
{currentSettings?.env && Object.keys(currentSettings.env).length > 0 ? (
<div className="space-y-6">
{Object.entries(currentSettings.env).map(([key, value]) => (
<div key={key} className="space-y-2">
<Label className="text-sm font-medium text-foreground">{key}</Label>
{isSensitiveKey(key) ? (
<MaskedInput
value={value}
onChange={(e) => updateEnvValue(key, e.target.value)}
className="font-mono text-sm"
/>
) : (
<Input
value={value}
onChange={(e) => updateEnvValue(key, e.target.value)}
className="font-mono text-sm"
/>
)}
</div>
))}
</div>
) : (
<div className="py-12 text-center text-muted-foreground bg-muted/30 rounded-lg border border-dashed">
<p>No environment variables configured.</p>
<p className="text-xs mt-1">Add variables in your settings.json file.</p>
</div>
)}
</ScrollArea>
</TabsContent>
<div className="flex justify-end gap-2 pt-4">
<TabsContent value="general" className="p-4 m-0">
<Card>
<CardHeader>
<CardTitle className="text-base">Profile Information</CardTitle>
<CardDescription>Details about this configuration file.</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
{data && (
<>
<div className="grid grid-cols-3 gap-2 text-sm">
<span className="font-medium text-muted-foreground">Path</span>
<code className="col-span-2 bg-muted p-1 rounded text-xs break-all">
{data.path}
</code>
</div>
<div className="grid grid-cols-3 gap-2 text-sm">
<span className="font-medium text-muted-foreground">Last Modified</span>
<span className="col-span-2">{new Date(data.mtime).toLocaleString()}</span>
</div>
</>
)}
</CardContent>
</Card>
</TabsContent>
</Tabs>
<div className="pt-4 mt-auto border-t flex justify-end gap-2">
<Button type="button" variant="outline" onClick={onClose}>
<X className="w-4 h-4 mr-2" /> Cancel
</Button>
@@ -193,16 +249,12 @@ function SettingsDialogContent({
</>
) : (
<>
<Save className="w-4 h-4 mr-2" /> Save
<Save className="w-4 h-4 mr-2" /> Save Changes
</>
)}
</Button>
</div>
</div>
) : (
<div className="py-8 text-center text-muted-foreground">
No environment variables configured for this profile.
</div>
)}
<ConfirmDialog
@@ -231,7 +283,7 @@ export function SettingsDialog({ open, onClose, profileName }: SettingsDialogPro
return (
<Dialog open={open} onOpenChange={handleOpenChange}>
<DialogContent className="max-w-2xl max-h-[80vh] overflow-y-auto">
<DialogContent className="sm:max-w-3xl max-h-[80vh] overflow-y-auto">
{/* Key prop ensures fresh state on each open */}
{open && profileName && (
<SettingsDialogContent
+44
View File
@@ -0,0 +1,44 @@
import * as React from 'react';
import * as ScrollAreaPrimitive from '@radix-ui/react-scroll-area';
import { cn } from '@/lib/utils';
const ScrollArea = React.forwardRef<
React.ComponentRef<typeof ScrollAreaPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Root>
>(({ className, children, ...props }, ref) => (
<ScrollAreaPrimitive.Root
ref={ref}
className={cn('relative overflow-hidden', className)}
{...props}
>
<ScrollAreaPrimitive.Viewport className="h-full w-full rounded-[inherit]">
{children}
</ScrollAreaPrimitive.Viewport>
<ScrollBar />
<ScrollAreaPrimitive.Corner />
</ScrollAreaPrimitive.Root>
));
ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName;
const ScrollBar = React.forwardRef<
React.ComponentRef<typeof ScrollAreaPrimitive.Scrollbar>,
React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Scrollbar>
>(({ className, orientation = 'vertical', ...props }, ref) => (
<ScrollAreaPrimitive.Scrollbar
ref={ref}
orientation={orientation}
className={cn(
'flex touch-none select-none transition-colors',
orientation === 'vertical' && 'h-full w-2.5 border-l border-l-transparent p-[1px]',
orientation === 'horizontal' && 'h-2.5 flex-col border-t border-t-transparent p-[1px]',
className
)}
{...props}
>
<ScrollAreaPrimitive.Thumb className="relative flex-1 rounded-full bg-border" />
</ScrollAreaPrimitive.Scrollbar>
));
ScrollBar.displayName = ScrollAreaPrimitive.Scrollbar.displayName;
export { ScrollArea, ScrollBar };
+53
View File
@@ -0,0 +1,53 @@
import * as React from 'react';
import * as TabsPrimitive from '@radix-ui/react-tabs';
import { cn } from '@/lib/utils';
const Tabs = TabsPrimitive.Root;
const TabsList = React.forwardRef<
React.ComponentRef<typeof TabsPrimitive.List>,
React.ComponentPropsWithoutRef<typeof TabsPrimitive.List>
>(({ className, ...props }, ref) => (
<TabsPrimitive.List
ref={ref}
className={cn(
'inline-flex h-10 items-center justify-center rounded-md bg-muted p-1 text-muted-foreground',
className
)}
{...props}
/>
));
TabsList.displayName = TabsPrimitive.List.displayName;
const TabsTrigger = React.forwardRef<
React.ComponentRef<typeof TabsPrimitive.Trigger>,
React.ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger>
>(({ className, ...props }, ref) => (
<TabsPrimitive.Trigger
ref={ref}
className={cn(
'inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm',
className
)}
{...props}
/>
));
TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
const TabsContent = React.forwardRef<
React.ComponentRef<typeof TabsPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof TabsPrimitive.Content>
>(({ className, ...props }, ref) => (
<TabsPrimitive.Content
ref={ref}
className={cn(
'mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',
className
)}
{...props}
/>
));
TabsContent.displayName = TabsPrimitive.Content.displayName;
export { Tabs, TabsList, TabsTrigger, TabsContent };
+6
View File
@@ -27,6 +27,9 @@
--ring: oklch(0.2 0.02 40); /* Match primary */
--radius: 0.5rem;
--popover: oklch(0.9635 0.0067 97.35); /* Match background */
--popover-foreground: oklch(0.2 0.02 40); /* Match foreground */
/* Sidebar colors - Light */
--sidebar: oklch(0.9635 0.0067 97.35); /* Pampas */
--sidebar-foreground: oklch(0.2 0.02 40);
@@ -63,6 +66,9 @@
--ring: oklch(0.9635 0.0067 97.35);
--popover: oklch(0.21 0.006 100); /* Match dark bg */
--popover-foreground: oklch(0.9635 0.0067 97.35); /* Match dark fg */
/* Sidebar Dark Theme */
--sidebar: oklch(0.21 0.006 100); /* Match bg */
--sidebar-foreground: oklch(0.9635 0.0067 97.35);
+1 -10
View File
@@ -19,11 +19,6 @@ export function ApiPage() {
const [settingsProfileName, setSettingsProfileName] = useState<string | null>(null);
const { data, isLoading } = useProfiles();
const handleEdit = (profile: Profile) => {
setEditingProfile(profile);
setDialogOpen(true);
};
const handleEditSettings = (profile: Profile) => {
setSettingsProfileName(profile.name);
setSettingsDialogOpen(true);
@@ -57,11 +52,7 @@ export function ApiPage() {
{isLoading ? (
<div className="text-muted-foreground">Loading profiles...</div>
) : (
<ProfilesTable
data={data?.profiles || []}
onEdit={handleEdit}
onEditSettings={handleEditSettings}
/>
<ProfilesTable data={data?.profiles || []} onEditSettings={handleEditSettings} />
)}
<ProfileDialog open={dialogOpen} onClose={handleCloseDialog} profile={editingProfile} />