Add src/app/settings/page.tsx
This commit is contained in:
444
src/app/settings/page.tsx
Normal file
444
src/app/settings/page.tsx
Normal file
@@ -0,0 +1,444 @@
|
||||
"use client";
|
||||
|
||||
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
|
||||
import NavbarStyleFullscreen from '@/components/navbar/NavbarStyleFullscreen/NavbarStyleFullscreen';
|
||||
import ContactCenter from '@/components/sections/contact/ContactCenter';
|
||||
import FooterBase from '@/components/sections/footer/FooterBase';
|
||||
import { Palette, Volume2, Zap, RotateCw, Save } from 'lucide-react';
|
||||
import { useState, useEffect } from 'react';
|
||||
|
||||
interface AppearanceSettings {
|
||||
colorTheme: string;
|
||||
fontFamily: string;
|
||||
layoutWidth: 'compact' | 'medium' | 'wide';
|
||||
darkMode: boolean;
|
||||
}
|
||||
|
||||
interface KokoSettings {
|
||||
movementSpeed: 'slow' | 'normal' | 'fast';
|
||||
personality: 'cheerful' | 'calm' | 'professional';
|
||||
interactionStyle: 'minimal' | 'balanced' | 'interactive';
|
||||
soundEnabled: boolean;
|
||||
voiceEnabled: boolean;
|
||||
}
|
||||
|
||||
interface VaultSettings {
|
||||
encryptionEnabled: boolean;
|
||||
autoBackup: boolean;
|
||||
backupFrequency: 'daily' | 'weekly' | 'monthly';
|
||||
compressionEnabled: boolean;
|
||||
}
|
||||
|
||||
const DEFAULT_APPEARANCE: AppearanceSettings = {
|
||||
colorTheme: 'grayPurpleAccent',
|
||||
fontFamily: 'inter',
|
||||
layoutWidth: 'compact',
|
||||
darkMode: false,
|
||||
};
|
||||
|
||||
const DEFAULT_KOKO: KokoSettings = {
|
||||
movementSpeed: 'normal',
|
||||
personality: 'cheerful',
|
||||
interactionStyle: 'balanced',
|
||||
soundEnabled: true,
|
||||
voiceEnabled: true,
|
||||
};
|
||||
|
||||
const DEFAULT_VAULT: VaultSettings = {
|
||||
encryptionEnabled: true,
|
||||
autoBackup: true,
|
||||
backupFrequency: 'weekly',
|
||||
compressionEnabled: true,
|
||||
};
|
||||
|
||||
export default function SettingsPage() {
|
||||
const [appearanceSettings, setAppearanceSettings] = useState<AppearanceSettings>(DEFAULT_APPEARANCE);
|
||||
const [kokoSettings, setKokoSettings] = useState<KokoSettings>(DEFAULT_KOKO);
|
||||
const [vaultSettings, setVaultSettings] = useState<VaultSettings>(DEFAULT_VAULT);
|
||||
const [activeTab, setActiveTab] = useState<'appearance' | 'koko' | 'vault'>('appearance');
|
||||
const [saved, setSaved] = useState(false);
|
||||
|
||||
// Load settings from localStorage on mount
|
||||
useEffect(() => {
|
||||
const savedAppearance = localStorage.getItem('appearanceSettings');
|
||||
const savedKoko = localStorage.getItem('kokoSettings');
|
||||
const savedVault = localStorage.getItem('vaultSettings');
|
||||
|
||||
if (savedAppearance) setAppearanceSettings(JSON.parse(savedAppearance));
|
||||
if (savedKoko) setKokoSettings(JSON.parse(savedKoko));
|
||||
if (savedVault) setVaultSettings(JSON.parse(savedVault));
|
||||
}, []);
|
||||
|
||||
// Save all settings to localStorage
|
||||
const handleSaveSettings = () => {
|
||||
localStorage.setItem('appearanceSettings', JSON.stringify(appearanceSettings));
|
||||
localStorage.setItem('kokoSettings', JSON.stringify(kokoSettings));
|
||||
localStorage.setItem('vaultSettings', JSON.stringify(vaultSettings));
|
||||
setSaved(true);
|
||||
setTimeout(() => setSaved(false), 3000);
|
||||
};
|
||||
|
||||
// Reset to defaults
|
||||
const handleResetSettings = () => {
|
||||
setAppearanceSettings(DEFAULT_APPEARANCE);
|
||||
setKokoSettings(DEFAULT_KOKO);
|
||||
setVaultSettings(DEFAULT_VAULT);
|
||||
localStorage.removeItem('appearanceSettings');
|
||||
localStorage.removeItem('kokoSettings');
|
||||
localStorage.removeItem('vaultSettings');
|
||||
};
|
||||
|
||||
return (
|
||||
<ThemeProvider
|
||||
defaultButtonVariant="hover-bubble"
|
||||
defaultTextAnimation="entrance-slide"
|
||||
borderRadius="soft"
|
||||
contentWidth="compact"
|
||||
sizing="medium"
|
||||
background="circleGradient"
|
||||
cardStyle="glass-depth"
|
||||
primaryButtonStyle="shadow"
|
||||
secondaryButtonStyle="radial-glow"
|
||||
headingFontWeight="medium"
|
||||
>
|
||||
<div id="nav" data-section="nav">
|
||||
<NavbarStyleFullscreen
|
||||
navItems={[
|
||||
{ name: "Home", id: "home" },
|
||||
{ name: "Storage", id: "storage" },
|
||||
{ name: "AI Chat", id: "chat" },
|
||||
{ name: "Customize", id: "customize" },
|
||||
{ name: "Settings", id: "settings" }
|
||||
]}
|
||||
brandName="Koko"
|
||||
bottomLeftText="AI-Powered Cloud Storage"
|
||||
bottomRightText="Free, Cross-Platform, Intelligent"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="settings-content" data-section="settings-content" className="min-h-screen bg-gradient-to-b from-background to-card">
|
||||
<div className="max-w-6xl mx-auto px-4 py-16">
|
||||
{/* Header */}
|
||||
<div className="mb-12">
|
||||
<h1 className="text-5xl font-bold mb-4 text-foreground">Settings & Customization</h1>
|
||||
<p className="text-lg text-foreground/80">Personalize your Koko experience exactly how you want it</p>
|
||||
</div>
|
||||
|
||||
{/* Tabs */}
|
||||
<div className="flex gap-4 mb-8 border-b border-accent/20">
|
||||
<button
|
||||
onClick={() => setActiveTab('appearance')}
|
||||
className={`pb-4 px-6 font-semibold transition-all ${
|
||||
activeTab === 'appearance'
|
||||
? 'text-primary-cta border-b-2 border-primary-cta'
|
||||
: 'text-foreground/60 hover:text-foreground'
|
||||
}`}
|
||||
>
|
||||
<div className="flex items-center gap-2">
|
||||
<Palette size={20} />
|
||||
Appearance
|
||||
</div>
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setActiveTab('koko')}
|
||||
className={`pb-4 px-6 font-semibold transition-all ${
|
||||
activeTab === 'koko'
|
||||
? 'text-primary-cta border-b-2 border-primary-cta'
|
||||
: 'text-foreground/60 hover:text-foreground'
|
||||
}`}
|
||||
>
|
||||
<div className="flex items-center gap-2">
|
||||
<Zap size={20} />
|
||||
Koko Behavior
|
||||
</div>
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setActiveTab('vault')}
|
||||
className={`pb-4 px-6 font-semibold transition-all ${
|
||||
activeTab === 'vault'
|
||||
? 'text-primary-cta border-b-2 border-primary-cta'
|
||||
: 'text-foreground/60 hover:text-foreground'
|
||||
}`}
|
||||
>
|
||||
<div className="flex items-center gap-2">
|
||||
<Volume2 size={20} />
|
||||
Vault Security
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Tab Content */}
|
||||
<div className="bg-card rounded-xl p-8 border border-accent/10 shadow-lg">
|
||||
{/* Appearance Settings */}
|
||||
{activeTab === 'appearance' && (
|
||||
<div className="space-y-8">
|
||||
<div>
|
||||
<label className="block text-sm font-semibold text-foreground mb-3">Color Theme</label>
|
||||
<select
|
||||
value={appearanceSettings.colorTheme}
|
||||
onChange={(e) => setAppearanceSettings({ ...appearanceSettings, colorTheme: e.target.value })}
|
||||
className="w-full px-4 py-3 rounded-lg bg-background border border-accent/20 text-foreground focus:outline-none focus:ring-2 focus:ring-primary-cta"
|
||||
>
|
||||
<option value="grayPurpleAccent">Purple Accent</option>
|
||||
<option value="grayBlueAccent">Blue Accent</option>
|
||||
<option value="grayGreenAccent">Green Accent</option>
|
||||
<option value="grayRedAccent">Red Accent</option>
|
||||
<option value="minimalDarkBlue">Dark Blue</option>
|
||||
<option value="minimalDarkGreen">Dark Green</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="block text-sm font-semibold text-foreground mb-3">Font Family</label>
|
||||
<select
|
||||
value={appearanceSettings.fontFamily}
|
||||
onChange={(e) => setAppearanceSettings({ ...appearanceSettings, fontFamily: e.target.value })}
|
||||
className="w-full px-4 py-3 rounded-lg bg-background border border-accent/20 text-foreground focus:outline-none focus:ring-2 focus:ring-primary-cta"
|
||||
>
|
||||
<option value="inter">Inter</option>
|
||||
<option value="poppins">Poppins</option>
|
||||
<option value="montserrat">Montserrat</option>
|
||||
<option value="roboto">Roboto</option>
|
||||
<option value="openSans">Open Sans</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="block text-sm font-semibold text-foreground mb-3">Layout Width</label>
|
||||
<div className="flex gap-4">
|
||||
{(['compact', 'medium', 'wide'] as const).map((width) => (
|
||||
<button
|
||||
key={width}
|
||||
onClick={() => setAppearanceSettings({ ...appearanceSettings, layoutWidth: width })}
|
||||
className={`flex-1 py-3 rounded-lg font-medium transition-all ${
|
||||
appearanceSettings.layoutWidth === width
|
||||
? 'bg-primary-cta text-primary-cta-text'
|
||||
: 'bg-background border border-accent/20 text-foreground hover:border-accent'
|
||||
}`}
|
||||
>
|
||||
{width.charAt(0).toUpperCase() + width.slice(1)}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="flex items-center gap-3 cursor-pointer">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={appearanceSettings.darkMode}
|
||||
onChange={(e) => setAppearanceSettings({ ...appearanceSettings, darkMode: e.target.checked })}
|
||||
className="w-5 h-5 rounded border-accent/20"
|
||||
/>
|
||||
<span className="text-sm font-semibold text-foreground">Dark Mode</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Koko Behavior Settings */}
|
||||
{activeTab === 'koko' && (
|
||||
<div className="space-y-8">
|
||||
<div>
|
||||
<label className="block text-sm font-semibold text-foreground mb-3">Movement Speed</label>
|
||||
<select
|
||||
value={kokoSettings.movementSpeed}
|
||||
onChange={(e) => setKokoSettings({ ...kokoSettings, movementSpeed: e.target.value as any })}
|
||||
className="w-full px-4 py-3 rounded-lg bg-background border border-accent/20 text-foreground focus:outline-none focus:ring-2 focus:ring-primary-cta"
|
||||
>
|
||||
<option value="slow">Slow (Calm & Deliberate)</option>
|
||||
<option value="normal">Normal (Balanced)</option>
|
||||
<option value="fast">Fast (Energetic)</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="block text-sm font-semibold text-foreground mb-3">Personality Traits</label>
|
||||
<select
|
||||
value={kokoSettings.personality}
|
||||
onChange={(e) => setKokoSettings({ ...kokoSettings, personality: e.target.value as any })}
|
||||
className="w-full px-4 py-3 rounded-lg bg-background border border-accent/20 text-foreground focus:outline-none focus:ring-2 focus:ring-primary-cta"
|
||||
>
|
||||
<option value="cheerful">Cheerful (Enthusiastic & Supportive)</option>
|
||||
<option value="calm">Calm (Composed & Thoughtful)</option>
|
||||
<option value="professional">Professional (Focused & Efficient)</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="block text-sm font-semibold text-foreground mb-3">Interaction Style</label>
|
||||
<select
|
||||
value={kokoSettings.interactionStyle}
|
||||
onChange={(e) => setKokoSettings({ ...kokoSettings, interactionStyle: e.target.value as any })}
|
||||
className="w-full px-4 py-3 rounded-lg bg-background border border-accent/20 text-foreground focus:outline-none focus:ring-2 focus:ring-primary-cta"
|
||||
>
|
||||
<option value="minimal">Minimal (Quiet, Observant)</option>
|
||||
<option value="balanced">Balanced (Responsive & Present)</option>
|
||||
<option value="interactive">Interactive (Proactive & Engaging)</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div className="space-y-3">
|
||||
<label className="flex items-center gap-3 cursor-pointer">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={kokoSettings.soundEnabled}
|
||||
onChange={(e) => setKokoSettings({ ...kokoSettings, soundEnabled: e.target.checked })}
|
||||
className="w-5 h-5 rounded border-accent/20"
|
||||
/>
|
||||
<span className="text-sm font-semibold text-foreground">Sound Effects</span>
|
||||
</label>
|
||||
<label className="flex items-center gap-3 cursor-pointer">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={kokoSettings.voiceEnabled}
|
||||
onChange={(e) => setKokoSettings({ ...kokoSettings, voiceEnabled: e.target.checked })}
|
||||
className="w-5 h-5 rounded border-accent/20"
|
||||
/>
|
||||
<span className="text-sm font-semibold text-foreground">Voice Responses</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Vault Security Settings */}
|
||||
{activeTab === 'vault' && (
|
||||
<div className="space-y-8">
|
||||
<div className="space-y-3">
|
||||
<label className="flex items-center gap-3 cursor-pointer">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={vaultSettings.encryptionEnabled}
|
||||
onChange={(e) => setVaultSettings({ ...vaultSettings, encryptionEnabled: e.target.checked })}
|
||||
className="w-5 h-5 rounded border-accent/20"
|
||||
/>
|
||||
<span className="text-sm font-semibold text-foreground">End-to-End Encryption (AES-256)</span>
|
||||
</label>
|
||||
<p className="text-xs text-foreground/60 ml-8">Encrypt your files with military-grade encryption</p>
|
||||
</div>
|
||||
|
||||
<div className="space-y-3">
|
||||
<label className="flex items-center gap-3 cursor-pointer">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={vaultSettings.autoBackup}
|
||||
onChange={(e) => setVaultSettings({ ...vaultSettings, autoBackup: e.target.checked })}
|
||||
className="w-5 h-5 rounded border-accent/20"
|
||||
/>
|
||||
<span className="text-sm font-semibold text-foreground">Automatic Backups</span>
|
||||
</label>
|
||||
{vaultSettings.autoBackup && (
|
||||
<div className="ml-8">
|
||||
<label className="block text-xs font-semibold text-foreground mb-2">Backup Frequency</label>
|
||||
<select
|
||||
value={vaultSettings.backupFrequency}
|
||||
onChange={(e) => setVaultSettings({ ...vaultSettings, backupFrequency: e.target.value as any })}
|
||||
className="w-full px-3 py-2 rounded-lg bg-background border border-accent/20 text-foreground text-sm focus:outline-none focus:ring-2 focus:ring-primary-cta"
|
||||
>
|
||||
<option value="daily">Daily</option>
|
||||
<option value="weekly">Weekly</option>
|
||||
<option value="monthly">Monthly</option>
|
||||
</select>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="space-y-3">
|
||||
<label className="flex items-center gap-3 cursor-pointer">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={vaultSettings.compressionEnabled}
|
||||
onChange={(e) => setVaultSettings({ ...vaultSettings, compressionEnabled: e.target.checked })}
|
||||
className="w-5 h-5 rounded border-accent/20"
|
||||
/>
|
||||
<span className="text-sm font-semibold text-foreground">Smart Compression</span>
|
||||
</label>
|
||||
<p className="text-xs text-foreground/60 ml-8">Automatically compress files to save storage space</p>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Action Buttons */}
|
||||
<div className="flex gap-4 mt-8">
|
||||
<button
|
||||
onClick={handleSaveSettings}
|
||||
className="flex items-center gap-2 px-6 py-3 bg-primary-cta text-primary-cta-text rounded-lg font-semibold hover:opacity-90 transition-opacity"
|
||||
>
|
||||
<Save size={20} />
|
||||
Save Settings
|
||||
</button>
|
||||
<button
|
||||
onClick={handleResetSettings}
|
||||
className="flex items-center gap-2 px-6 py-3 bg-background border border-accent/20 text-foreground rounded-lg font-semibold hover:bg-accent/10 transition-colors"
|
||||
>
|
||||
<RotateCw size={20} />
|
||||
Reset to Defaults
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Success Message */}
|
||||
{saved && (
|
||||
<div className="mt-6 p-4 bg-green-500/10 border border-green-500/30 rounded-lg text-green-700 font-semibold text-center">
|
||||
✓ Settings saved successfully!
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="contact" data-section="contact">
|
||||
<ContactCenter
|
||||
tag="Need Help?"
|
||||
title="Contact Our Support Team"
|
||||
description="Have questions about customization or need assistance? Our team is here to help you get the most out of Koko."
|
||||
background={{ variant: "radial-gradient" }}
|
||||
useInvertedBackground={true}
|
||||
inputPlaceholder="Enter your email"
|
||||
buttonText="Get Support"
|
||||
termsText="We'll respond to your inquiry within 24 hours."
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="footer" data-section="footer">
|
||||
<FooterBase
|
||||
logoText="Koko"
|
||||
copyrightText="© 2025 Koko AI Storage. All rights reserved."
|
||||
columns={[
|
||||
{
|
||||
title: "Product", items: [
|
||||
{ label: "Features", href: "/" },
|
||||
{ label: "Capabilities", href: "/" },
|
||||
{ label: "Customization", href: "/" },
|
||||
{ label: "Pricing", href: "/" }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Company", items: [
|
||||
{ label: "About Us", href: "#" },
|
||||
{ label: "Blog", href: "#" },
|
||||
{ label: "Careers", href: "#" },
|
||||
{ label: "Press", href: "#" }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Resources", items: [
|
||||
{ label: "Documentation", href: "#" },
|
||||
{ label: "API Reference", href: "#" },
|
||||
{ label: "Support", href: "/settings" },
|
||||
{ label: "Community", href: "#" }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Legal", items: [
|
||||
{ label: "Privacy Policy", href: "#" },
|
||||
{ label: "Terms of Service", href: "#" },
|
||||
{ label: "Security", href: "#" },
|
||||
{ label: "Contact", href: "/settings" }
|
||||
]
|
||||
}
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
</ThemeProvider>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user