Files
kandev/apps/web/components/settings/general-settings.tsx
T
2026-02-04 00:27:44 +00:00

168 lines
5.7 KiB
TypeScript

'use client';
import { useState } from 'react';
import { useTheme } from 'next-themes';
import { IconPalette, IconServer, IconKeyboard } from '@tabler/icons-react';
import { Card, CardContent, CardHeader, CardTitle } from '@kandev/ui/card';
import { Label } from '@kandev/ui/label';
import { Input } from '@kandev/ui/input';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@kandev/ui/select';
import { Separator } from '@kandev/ui/separator';
import { SettingsSection } from '@/components/settings/settings-section';
import { ShellSettingsCard } from '@/components/settings/shell-settings-card';
import { getBackendConfig } from '@/lib/config';
import { useAppStore } from '@/components/state-provider';
import { updateUserSettings } from '@/lib/api';
import type { Theme } from '@/lib/settings/types';
export function GeneralSettings() {
const { theme: currentTheme, setTheme } = useTheme();
const [backendUrl] = useState<string>(() => getBackendConfig().apiBaseUrl);
const displayBackendUrl = backendUrl.replace(/^https?:\/\//, '').replace(/\/$/, '');
const themeValue = currentTheme ?? 'system';
// User settings
const userSettings = useAppStore((state) => state.userSettings);
const setUserSettings = useAppStore((state) => state.setUserSettings);
const [isSavingSubmitKey, setIsSavingSubmitKey] = useState(false);
const handleChatSubmitKeyChange = async (value: 'enter' | 'cmd_enter') => {
if (isSavingSubmitKey) return;
setIsSavingSubmitKey(true);
const previousValue = userSettings.chatSubmitKey;
try {
setUserSettings({
...userSettings,
chatSubmitKey: value,
});
await updateUserSettings({
workspace_id: userSettings.workspaceId || '',
board_id: userSettings.boardId || '',
repository_ids: userSettings.repositoryIds || [],
chat_submit_key: value,
});
} catch {
setUserSettings({
...userSettings,
chatSubmitKey: previousValue,
});
} finally {
setIsSavingSubmitKey(false);
}
};
return (
<div className="space-y-8">
<div>
<h2 className="text-2xl font-bold">General Settings</h2>
<p className="text-sm text-muted-foreground mt-1">
Manage your application preferences and notifications
</p>
</div>
<Separator />
<SettingsSection
icon={<IconPalette className="h-5 w-5" />}
title="Appearance"
description="Customize how the application looks"
>
<Card>
<CardHeader>
<CardTitle className="text-base">Color Theme</CardTitle>
</CardHeader>
<CardContent>
<div className="space-y-2">
<Select value={themeValue} onValueChange={(value) => setTheme(value as Theme)}>
<SelectTrigger id="theme">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="system">System</SelectItem>
<SelectItem value="light">Light</SelectItem>
<SelectItem value="dark">Dark</SelectItem>
</SelectContent>
</Select>
</div>
</CardContent>
</Card>
</SettingsSection>
<Separator />
<ShellSettingsCard />
<Separator />
<SettingsSection
icon={<IconKeyboard className="h-5 w-5" />}
title="Chat Input"
description="Configure chat input behavior"
>
<Card>
<CardHeader>
<CardTitle className="text-base">Submit Shortcut</CardTitle>
</CardHeader>
<CardContent>
<div className="space-y-2">
<Label htmlFor="chat-submit-key">Message Submit Key</Label>
<Select
value={userSettings.chatSubmitKey}
onValueChange={(value) => handleChatSubmitKeyChange(value as 'enter' | 'cmd_enter')}
disabled={isSavingSubmitKey}
>
<SelectTrigger id="chat-submit-key">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="cmd_enter">Cmd/Ctrl+Enter to send</SelectItem>
<SelectItem value="enter">Enter to send</SelectItem>
</SelectContent>
</Select>
<p className="text-xs text-muted-foreground">
{userSettings.chatSubmitKey === 'cmd_enter'
? 'Press Cmd/Ctrl+Enter to send messages. Press Enter for newlines.'
: 'Press Enter to send messages. Press Shift+Enter for newlines.'}
</p>
</div>
</CardContent>
</Card>
</SettingsSection>
<Separator />
<SettingsSection
icon={<IconServer className="h-5 w-5" />}
title="Backend Connection"
description="Configure the backend server URL"
>
<Card>
<CardHeader>
<CardTitle className="text-base">Backend Server URL</CardTitle>
</CardHeader>
<CardContent>
<div className="space-y-2">
<Label htmlFor="backend-url">Server URL</Label>
<Input
id="backend-url"
type="url"
value={displayBackendUrl}
readOnly
disabled
placeholder="http://localhost:8080"
className="cursor-default"
/>
<p className="text-xs text-muted-foreground">
Backend URL is provided at runtime for SSR and WebSocket connections.
</p>
</div>
</CardContent>
</Card>
</SettingsSection>
</div>
);
}