web / frontend /src /pages /SettingsPage.tsx
Chandima Prabhath
init
22b1735
raw
history blame
9.86 kB
import { useState, useRef } from "react";
import { Settings, Moon, Sun, Globe, Shield, Database, Cloud } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
import { Label } from "@/components/ui/label";
import { Separator } from "@/components/ui/separator";
import { Input } from "@/components/ui/input";
import { toast } from "@/components/ui/sonner";
import { storage, STORAGE_KEYS } from "@/lib/storage";
const SettingsPage = () => {
const [theme, setTheme] = useState(() => {
return storage.get<string>(STORAGE_KEYS.THEME) || (window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light");
});
const [apiEndpoint, setApiEndpoint] = useState(
storage.get<string>(STORAGE_KEYS.API_ENDPOINT) || "http://localhost:8000"
);
const fileInputRef = useRef<HTMLInputElement>(null);
const handleThemeChange = (newTheme: string) => {
setTheme(newTheme);
const root = window.document.documentElement;
if (newTheme === "dark") {
root.classList.add("dark");
} else if (newTheme === "light") {
root.classList.remove("dark");
} else {
// System theme
if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
root.classList.add("dark");
} else {
root.classList.remove("dark");
}
}
storage.set(STORAGE_KEYS.THEME, newTheme);
toast.success("Theme updated successfully");
};
const handleSaveEndpoint = () => {
storage.set(STORAGE_KEYS.API_ENDPOINT, apiEndpoint);
toast.success("API endpoint saved successfully");
};
const handleClearChats = () => {
storage.set(STORAGE_KEYS.CHATS, []);
toast.success("Chat history cleared successfully");
};
const handleClearSources = () => {
storage.set(STORAGE_KEYS.SOURCES, []);
toast.success("Sources cleared successfully");
};
const handleResetSettings = () => {
storage.remove(STORAGE_KEYS.THEME);
storage.remove(STORAGE_KEYS.API_ENDPOINT);
setApiEndpoint("http://localhost:8000");
setTheme(window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light");
toast.success("Settings reset to defaults");
};
const handleExportStorage = () => {
const data = storage.export();
const blob = new Blob([JSON.stringify(data, null, 2)], { type: "application/json" });
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = "insight-storage-export.json";
a.click();
URL.revokeObjectURL(url);
toast.success("Storage exported successfully");
};
const handleImportStorage = (event: React.ChangeEvent<HTMLInputElement>) => {
const file = event.target.files?.[0];
if (!file) return;
const reader = new FileReader();
reader.onload = (e) => {
try {
const result = e.target?.result as string;
const data = JSON.parse(result);
if (storage.import(data)) {
toast.success("Storage imported successfully. Please refresh the page.");
} else {
toast.error("Failed to import storage.");
}
} catch {
toast.error("Invalid file format.");
}
};
reader.readAsText(file);
event.target.value = "";
};
return (
<div className="container mx-auto px-4 py-8">
<div className="max-w-4xl mx-auto">
<h1 className="text-2xl font-bold mb-6 text-gradient flex items-center">
<Settings className="mr-2 h-5 w-5" />
System Settings
</h1>
<div className="grid gap-6">
<Card className="glass-effect">
<CardHeader className="border-b border-border/40 pb-4">
<CardTitle className="flex items-center">
<Moon className="mr-2 h-4 w-4" />
Appearance
</CardTitle>
<CardDescription>
Customize how Insight AI looks
</CardDescription>
</CardHeader>
<CardContent className="pt-4">
<RadioGroup
value={theme}
onValueChange={handleThemeChange}
className="space-y-4"
>
<div className="flex items-center space-x-2">
<RadioGroupItem value="light" id="light" />
<Label htmlFor="light" className="flex items-center cursor-pointer">
<Sun className="h-4 w-4 mr-2" />
Light
</Label>
</div>
<div className="flex items-center space-x-2">
<RadioGroupItem value="dark" id="dark" />
<Label htmlFor="dark" className="flex items-center cursor-pointer">
<Moon className="h-4 w-4 mr-2" />
Dark
</Label>
</div>
<div className="flex items-center space-x-2">
<RadioGroupItem value="system" id="system" />
<Label htmlFor="system" className="flex items-center cursor-pointer">
<Globe className="h-4 w-4 mr-2" />
System
</Label>
</div>
</RadioGroup>
</CardContent>
</Card>
<Card className="glass-effect">
<CardHeader className="border-b border-border/40 pb-4">
<CardTitle className="flex items-center">
<Database className="mr-2 h-4 w-4" />
API Configuration
</CardTitle>
<CardDescription>
Configure connection to the financial rulings database
</CardDescription>
</CardHeader>
<CardContent className="space-y-4 pt-4">
<div className="space-y-2">
<Label htmlFor="api-endpoint">API Endpoint</Label>
<div className="flex space-x-2">
<Input
id="api-endpoint"
value={apiEndpoint}
onChange={(e) => setApiEndpoint(e.target.value)}
placeholder="http://localhost:8000"
className="glass-input"
/>
<Button onClick={handleSaveEndpoint} variant="outline" className="tech-button">
<Cloud className="h-4 w-4 mr-2" />
Save
</Button>
</div>
</div>
</CardContent>
</Card>
<Card className="glass-effect">
<CardHeader className="border-b border-border/40 pb-4">
<CardTitle className="flex items-center">
<Shield className="mr-2 h-4 w-4" />
Privacy & Data
</CardTitle>
<CardDescription>
Manage your data and privacy settings
</CardDescription>
</CardHeader>
<CardContent className="pt-4 space-y-4">
<div className="space-y-2">
<h3 className="text-sm font-medium">Data Management</h3>
<div className="flex flex-wrap gap-3">
<Button
variant="outline"
onClick={handleClearChats}
className="tech-button"
>
Clear Chat History
</Button>
<Button
variant="outline"
onClick={handleClearSources}
className="tech-button"
>
Clear Source References
</Button>
<Button
variant="destructive"
onClick={handleResetSettings}
className="tech-button"
>
Reset All Settings
</Button>
</div>
</div>
</CardContent>
</Card>
<Card className="glass-effect">
<CardHeader className="border-b border-border/40 pb-4">
<CardTitle className="flex items-center">
<Cloud className="mr-2 h-4 w-4" />
Storage Export / Import
</CardTitle>
<CardDescription>
Backup or restore your application data
</CardDescription>
</CardHeader>
<CardContent className="pt-4 space-y-4">
<div className="flex flex-wrap gap-3">
<Button
variant="outline"
onClick={handleExportStorage}
className="tech-button"
>
Export Storage
</Button>
<Button
variant="outline"
onClick={() => fileInputRef.current?.click()}
className="tech-button"
>
Import Storage
</Button>
<input
ref={fileInputRef}
type="file"
accept="application/json"
style={{ display: "none" }}
onChange={handleImportStorage}
/>
</div>
<div className="text-xs text-muted-foreground">
Export will download your data as a JSON file. Import will overwrite your current data with the file contents.
</div>
</CardContent>
</Card>
</div>
</div>
</div>
);
};
export default SettingsPage;