"use client"; import React from 'react'; import { useStore } from '@/lib/store'; import { Save, Sparkles, Brain, Settings2, Moon, Sun, Monitor, Check } from 'lucide-react'; import { cn } from '@/lib/utils'; import { useTheme } from '@/components/theme-provider'; import { MobileCookieInstructions } from './MobileCookieInstructions'; type Provider = 'whisk' | 'meta'; const providers: { id: Provider; name: string; icon: any; description: string }[] = [ { id: 'whisk', name: 'Google Whisk', icon: Sparkles, description: 'ImageFX / Imagen 3' }, { id: 'meta', name: 'Meta AI', icon: Brain, description: 'Imagine / Emu' }, ]; export function Settings() { const { settings, setSettings } = useStore(); const { theme, setTheme } = useTheme(); const [mounted, setMounted] = React.useState(false); React.useEffect(() => { setMounted(true); }, []); const ThemeButton = ({ theme: t, icon: Icon, label }: { theme: 'light' | 'dark' | 'system', icon: any, label: string }) => ( setTheme(t)} className={cn( "flex items-center justify-center gap-2 p-3 rounded-xl border transition-all active:scale-95", mounted && theme === t ? "bg-primary text-primary-foreground border-primary" : "bg-card hover:bg-muted border-border text-muted-foreground" )} > {label} ); // Local state for form fields const [provider, setProvider] = React.useState(settings.provider || 'whisk'); const [whiskCookies, setWhiskCookies] = React.useState(settings.whiskCookies || ''); const [useMetaFreeWrapper, setUseMetaFreeWrapper] = React.useState(settings.useMetaFreeWrapper !== undefined ? settings.useMetaFreeWrapper : true); const [metaFreeWrapperUrl, setMetaFreeWrapperUrl] = React.useState(settings.metaFreeWrapperUrl || 'http://localhost:8000'); const [metaCookies, setMetaCookies] = React.useState(settings.metaCookies || ''); const [facebookCookies, setFacebookCookies] = React.useState(settings.facebookCookies || ''); const [saved, setSaved] = React.useState(false); const [whiskVerified, setWhiskVerified] = React.useState(false); const [metaVerified, setMetaVerified] = React.useState(false); const handleSave = () => { setSettings({ provider, whiskCookies, useMetaFreeWrapper, metaFreeWrapperUrl, metaCookies, facebookCookies }); setSaved(true); setTimeout(() => setSaved(false), 2000); }; return ( {/* Header Section */} Settings Configure your AI preferences and API credentials. {/* General Preferences Card */} Appearance Default Engine {providers.map((p) => ( setProvider(p.id)} className={cn( "flex items-center gap-4 p-4 rounded-2xl border-2 transition-all active:scale-[0.98] text-left", provider === p.id ? "border-primary bg-primary/5 ring-4 ring-primary/10" : "border-border/50 hover:border-primary/30 bg-background/50" )} > {p.name} {p.description} ))} {/* Provider Credentials Card */} API Credentials {saved ? "Saved Configuration" : "Save Configuration"} {/* Whisk Settings */} {provider === 'whisk' && ( Google Whisk Configuration { try { const text = await navigator.clipboard.readText(); setWhiskCookies(text); } catch (err) { console.error('Failed to read clipboard', err); alert('Please grant clipboard permissions to use this feature.'); } }} className="px-3 py-1 bg-muted/50 hover:bg-muted text-[10px] font-bold rounded-lg border border-border/50 transition-all flex items-center gap-1.5 active:scale-95" > Paste Cookies { const isValid = whiskCookies.includes('PHPSESSID') || whiskCookies.length > 100; if (isValid) { setWhiskVerified(true); setTimeout(() => setWhiskVerified(false), 3000); } else { alert("Whisk cookies might be incomplete."); } }} className={cn( "px-3 py-1 text-[10px] font-bold rounded-lg border transition-all active:scale-95 flex items-center gap-1.5", whiskVerified ? "bg-green-500/10 border-green-500/20 text-green-600 dark:text-green-400" : "bg-primary/10 hover:bg-primary/20 text-primary border-primary/20" )} > {whiskVerified ? : null} {whiskVerified ? "Verified" : "Verify"} Authentication Cookies setWhiskCookies(e.target.value)} placeholder="Paste your Whisk cookies here..." className="w-full h-32 bg-background/50 border border-border/50 rounded-2xl p-4 text-xs font-mono focus:ring-2 focus:ring-primary/20 focus:border-primary/50 outline-none resize-none transition-all" /> )} {/* Meta AI Settings */} {provider === 'meta' && ( Meta AI Configuration { const isValid = metaCookies.length > 50 && facebookCookies.length > 50; if (isValid) { setMetaVerified(true); setTimeout(() => setMetaVerified(false), 3000); } else { alert("Please ensure both Meta and Facebook cookies are pasted."); } }} className={cn( "px-3 py-1 text-[10px] font-bold rounded-lg border transition-all active:scale-95 flex items-center gap-1.5", metaVerified ? "bg-green-500/10 border-green-500/20 text-green-600 dark:text-green-400" : "bg-blue-500/10 hover:bg-blue-500/20 text-blue-600 dark:text-blue-400 border-blue-500/20" )} > {metaVerified ? : null} {metaVerified ? "Verified" : "Verify Duo"} {/* Advanced Configuration (Meta Specific) */} Advanced Host Configuration Local Docker Wrapper Internal API Bridge setUseMetaFreeWrapper(!useMetaFreeWrapper)} className={cn( "relative inline-flex h-6 w-11 items-center rounded-full transition-colors outline-none", useMetaFreeWrapper ? "bg-primary" : "bg-border" )} > {useMetaFreeWrapper && ( Wrapper Endpoint setMetaFreeWrapperUrl(e.target.value)} className="w-full p-3 rounded-xl bg-muted/30 border border-border/50 focus:ring-1 focus:ring-primary/50 outline-none font-mono text-xs" /> )} {/* Meta Cookies Fields */} Meta.ai Cookies { try { const text = await navigator.clipboard.readText(); setMetaCookies(text); } catch (err) { console.error('Clipboard error', err); alert('Clipboard permission denied.'); } }} className="text-[10px] font-bold text-primary hover:underline" > Paste setMetaCookies(e.target.value)} placeholder="Paste your Meta cookies..." className="w-full h-32 bg-background/50 border border-border/50 rounded-2xl p-4 text-xs font-mono focus:ring-2 focus:ring-primary/20 focus:border-primary/50 outline-none resize-none transition-all" /> Facebook.com Auth Cookies { try { const text = await navigator.clipboard.readText(); setFacebookCookies(text); } catch (err) { console.error('Clipboard error', err); alert('Clipboard permission denied.'); } }} className="text-[10px] font-bold text-primary hover:underline" > Paste setFacebookCookies(e.target.value)} placeholder="Paste your Facebook cookies (REQUIRED)..." className="w-full h-32 bg-background/50 border border-border/50 rounded-2xl p-4 text-xs font-mono focus:ring-2 focus:ring-primary/20 focus:border-primary/50 outline-none resize-none transition-all" /> )} ); }
Configure your AI preferences and API credentials.
{p.name}
{p.description}
Local Docker Wrapper
Internal API Bridge