ATlast — you'll never need to find your favorites on another platform again. Find your favs in the ATmosphere.
atproto

update setup wizard colors (they still ugly)

authored by byarielm.fyi and committed by byarielm.fyi 6382e985 7dde603b

verified
Changed files
+392 -59
src
+57 -25
src/components/SetupWizard.tsx
··· 21 21 22 22 export default function SetupWizard({ isOpen, onClose, onComplete, currentSettings }: SetupWizardProps) { 23 23 const [wizardStep, setWizardStep] = useState(0); 24 - const [selectedPlatform, setSelectedPlatform] = useState<string | null>(null); 24 + const [selectedPlatforms, setSelectedPlatforms] = useState<Set<string>>(new Set()); 25 25 const [platformDestinations, setPlatformDestinations] = useState<PlatformDestinations>( 26 26 currentSettings.platformDestinations 27 27 ); ··· 42 42 onClose(); 43 43 }; 44 44 45 + const togglePlatform = (platformKey: string) => { 46 + const newSelected = new Set(selectedPlatforms); 47 + if (newSelected.has(platformKey)) { 48 + newSelected.delete(platformKey); 49 + } else { 50 + newSelected.add(platformKey); 51 + } 52 + setSelectedPlatforms(newSelected); 53 + }; 54 + 55 + // Get platforms to show on destinations page (only selected ones) 56 + const platformsToShow = selectedPlatforms.size > 0 57 + ? Object.entries(PLATFORMS).filter(([key]) => selectedPlatforms.has(key)) 58 + : Object.entries(PLATFORMS); 59 + 45 60 return ( 46 61 <div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4"> 47 - <div className="bg-white dark:bg-gray-800 rounded-2xl max-w-2xl w-full shadow-2xl max-h-[90vh] overflow-y-auto"> 62 + <div className="bg-white dark:bg-gray-800 rounded-2xl max-w-2xl w-full shadow-2xl max-h-[90vh] flex flex-col"> 48 63 {/* Header */} 49 - <div className="p-6 border-b border-gray-200 dark:border-gray-700 sticky top-0 bg-white dark:bg-gray-800 z-10"> 64 + <div className="p-6 border-b border-gray-200 dark:border-gray-700 flex-shrink-0"> 50 65 <div className="flex items-center justify-between mb-4"> 51 66 <div className="flex items-center space-x-3"> 52 - <div className="w-10 h-10 bg-gradient-to-br from-blue-500 to-purple-600 rounded-xl flex items-center justify-center"> 67 + <div className="w-10 h-10 bg-gradient-to-br from-firefly-amber via-firefly-orange to-firefly-pink rounded-xl flex items-center justify-center shadow-md"> 53 68 <Heart className="w-5 h-5 text-white" /> 54 69 </div> 55 70 <h2 className="text-2xl font-bold text-gray-900 dark:text-gray-100">Setup Assistant</h2> ··· 64 79 <div key={idx} className="flex-1"> 65 80 <div 66 81 className={`h-2 rounded-full transition-all ${ 67 - idx <= wizardStep ? 'bg-gradient-to-r from-blue-500 to-purple-600' : 'bg-gray-200 dark:bg-gray-700' 82 + idx <= wizardStep ? 'bg-gradient-to-r from-firefly-cyan via-firefly-orange to-firefly-pink' : 'bg-gray-200 dark:bg-gray-700' 68 83 }`} 69 84 /> 70 85 </div> ··· 75 90 </div> 76 91 </div> 77 92 78 - {/* Content */} 79 - <div className="p-6 min-h-[300px]"> 93 + {/* Content - Scrollable */} 94 + <div className="p-6 overflow-y-auto flex-1"> 80 95 {wizardStep === 0 && ( 81 96 <div className="text-center space-y-4"> 82 97 <div className="text-6xl mb-4">👋</div> ··· 92 107 <div className="space-y-4"> 93 108 <h3 className="text-xl font-bold text-gray-900 dark:text-gray-100">Which platforms will you import from?</h3> 94 109 <p className="text-sm text-gray-600 dark:text-gray-400"> 95 - Select the platforms you follow people on. We'll help you find them on the ATmosphere. 110 + Select one or more platforms you follow people on. We'll help you find them on the ATmosphere. 96 111 </p> 97 112 <div className="grid grid-cols-3 gap-3 mt-4"> 98 113 {Object.entries(PLATFORMS).map(([key, p]) => { 99 114 const Icon = p.icon; 115 + const isSelected = selectedPlatforms.has(key); 100 116 return ( 101 117 <button 102 118 key={key} 103 - onClick={() => setSelectedPlatform(key)} 104 - className={`p-4 rounded-xl border-2 transition-all ${ 105 - selectedPlatform === key 106 - ? 'border-blue-500 bg-blue-50 dark:bg-blue-900/20' 107 - : 'border-gray-200 dark:border-gray-700 hover:border-blue-300' 119 + onClick={() => togglePlatform(key)} 120 + className={`p-4 rounded-xl border-2 transition-all relative ${ 121 + isSelected 122 + ? 'border-firefly-orange bg-firefly-orange/10 dark:bg-firefly-orange/20' 123 + : 'border-gray-200 dark:border-gray-700 hover:border-firefly-cyan' 108 124 }`} 109 125 > 126 + {isSelected && ( 127 + <div className="absolute -top-2 -right-2 w-6 h-6 bg-firefly-orange rounded-full flex items-center justify-center"> 128 + <Check className="w-4 h-4 text-white" /> 129 + </div> 130 + )} 110 131 <Icon className="w-8 h-8 mx-auto mb-2 text-gray-700 dark:text-gray-300" /> 111 132 <div className="text-sm font-medium text-gray-900 dark:text-gray-100">{p.name}</div> 112 133 </button> 113 134 ); 114 135 })} 115 136 </div> 137 + {selectedPlatforms.size > 0 && ( 138 + <div className="mt-4 p-3 bg-firefly-amber/10 dark:bg-firefly-amber/20 rounded-lg border border-firefly-amber/30"> 139 + <p className="text-sm text-gray-700 dark:text-gray-300"> 140 + ✨ {selectedPlatforms.size} platform{selectedPlatforms.size !== 1 ? 's' : ''} selected 141 + </p> 142 + </div> 143 + )} 116 144 </div> 117 145 )} 118 146 ··· 123 151 Choose which ATmosphere app to use for each platform. You can change this later. 124 152 </p> 125 153 <div className="space-y-3 mt-4"> 126 - {Object.entries(PLATFORMS).map(([key, p]) => { 154 + {platformsToShow.map(([key, p]) => { 127 155 const Icon = p.icon; 128 156 return ( 129 157 <div key={key} className="flex items-center justify-between p-4 bg-gray-50 dark:bg-gray-900 rounded-xl"> ··· 155 183 )} 156 184 157 185 {wizardStep === 3 && ( 158 - <div className="space-y-6"> 186 + <div className="space-y-4"> 159 187 <div> 160 188 <h3 className="text-xl font-bold text-gray-900 dark:text-gray-100 mb-2">Privacy & Automation</h3> 161 189 <p className="text-sm text-gray-600 dark:text-gray-400">Control how your data is used.</p> 162 190 </div> 163 191 164 - <div className="space-y-4"> 165 - <div className="p-4 bg-blue-50 dark:bg-blue-900/20 rounded-xl"> 192 + <div className="space-y-3"> 193 + <div className="p-4 bg-firefly-cyan/10 dark:bg-firefly-cyan/20 rounded-xl border border-firefly-cyan/30"> 166 194 <div className="flex items-start space-x-3"> 167 195 <input 168 196 type="checkbox" ··· 182 210 </div> 183 211 </div> 184 212 185 - <div className="p-4 bg-purple-50 dark:bg-purple-900/20 rounded-xl"> 213 + <div className="p-4 bg-firefly-pink/10 dark:bg-firefly-pink/20 rounded-xl border border-firefly-pink/30"> 186 214 <div className="flex items-start space-x-3"> 187 215 <input 188 216 type="checkbox" ··· 223 251 <p className="text-gray-600 dark:text-gray-400 max-w-md mx-auto"> 224 252 Your preferences have been saved. You can change them anytime in Settings. 225 253 </p> 226 - <div className="bg-gradient-to-r from-blue-50 to-purple-50 dark:from-blue-900/20 dark:to-purple-900/20 rounded-xl p-4 mt-4"> 254 + <div className="bg-gradient-to-r from-firefly-cyan/20 via-firefly-orange/20 to-firefly-pink/20 dark:from-firefly-cyan/10 dark:via-firefly-orange/10 dark:to-firefly-pink/10 rounded-xl p-4 mt-4 border border-firefly-orange/30"> 227 255 <h4 className="font-semibold text-gray-900 dark:text-gray-100 mb-2">Quick Summary:</h4> 228 256 <ul className="text-sm text-gray-600 dark:text-gray-400 space-y-1 text-left max-w-sm mx-auto"> 229 257 <li className="flex items-center space-x-2"> 230 - <Check className="w-4 h-4 text-green-500" /> 258 + <Check className="w-4 h-4 text-firefly-orange" /> 231 259 <span>Data saving: {saveData ? 'Enabled' : 'Disabled'}</span> 232 260 </li> 233 261 <li className="flex items-center space-x-2"> 234 - <Check className="w-4 h-4 text-green-500" /> 262 + <Check className="w-4 h-4 text-firefly-orange" /> 235 263 <span>Automation: {enableAutomation ? 'Enabled' : 'Disabled'}</span> 236 264 </li> 237 265 <li className="flex items-center space-x-2"> 238 - <Check className="w-4 h-4 text-green-500" /> 266 + <Check className="w-4 h-4 text-firefly-orange" /> 267 + <span>Platforms: {selectedPlatforms.size > 0 ? selectedPlatforms.size : 'All'} selected</span> 268 + </li> 269 + <li className="flex items-center space-x-2"> 270 + <Check className="w-4 h-4 text-firefly-orange" /> 239 271 <span>Ready to upload your first file!</span> 240 272 </li> 241 273 </ul> ··· 245 277 </div> 246 278 247 279 {/* Footer */} 248 - <div className="p-6 border-t border-gray-200 dark:border-gray-700 flex items-center justify-between sticky bottom-0 bg-white dark:bg-gray-800"> 280 + <div className="p-6 border-t border-gray-200 dark:border-gray-700 flex items-center justify-between flex-shrink-0"> 249 281 <button 250 282 onClick={() => wizardStep > 0 && setWizardStep(wizardStep - 1)} 251 283 disabled={wizardStep === 0} 252 - className="px-4 py-2 text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100 disabled:opacity-30 disabled:cursor-not-allowed" 284 + className="px-4 py-2 text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100 disabled:opacity-30 disabled:cursor-not-allowed transition-colors" 253 285 > 254 286 Back 255 287 </button> ··· 261 293 handleComplete(); 262 294 } 263 295 }} 264 - className="px-6 py-2 bg-gradient-to-r from-blue-500 to-purple-600 text-white rounded-lg font-medium hover:from-blue-600 hover:to-purple-700 transition-all flex items-center space-x-2" 296 + className="px-6 py-2 bg-gradient-to-r from-firefly-amber via-firefly-orange to-firefly-pink text-white rounded-lg font-medium hover:shadow-lg transition-all flex items-center space-x-2" 265 297 > 266 298 <span>{wizardStep === wizardSteps.length - 1 ? 'Get Started' : 'Next'}</span> 267 299 {wizardStep < wizardSteps.length - 1 && <ChevronRight className="w-4 h-4" />}
+33 -34
src/pages/Home.tsx
··· 7 7 import { ATPROTO_APPS } from "../constants/atprotoApps"; 8 8 import type { Upload as UploadType } from "../types"; 9 9 import type { UserSettings } from "../types/settings"; 10 + import SettingsPage from "./Settings"; 10 11 11 12 interface atprotoSession { 12 13 did: string; ··· 113 114 ]; 114 115 115 116 return ( 116 - // Updated background from changes.js 117 117 <div className="min-h-screen bg-gradient-to-br from-gray-50 to-gray-100 dark:from-gray-900 dark:to-gray-800"> 118 118 <SetupWizard 119 119 isOpen={showWizard} ··· 124 124 125 125 {/* Header */} 126 126 <div className="bg-white dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700"> 127 - {/* Updated AppHeader props from changes.js */} 128 127 <AppHeader 129 128 session={session} 130 129 onLogout={onLogout} ··· 164 163 165 164 {/* Tab Content */} 166 165 <div className="max-w-6xl mx-auto px-4 py-8"> 167 - {/* Upload Tab */} 168 166 {activeTab === 'upload' && ( 169 167 <div className="space-y-6"> 170 - {/* Setup Assistant */} 168 + {/* Setup Assistant Banner - Only show if wizard not completed */} 171 169 {!userSettings.wizardCompleted && ( 172 - <div className="bg-gradient-to-r from-blue-500 to-purple-600 rounded-2xl p-6 text-white"> 170 + <div className="bg-firefly-banner dark:bg-firefly-banner-dark rounded-2xl p-6 text-white"> 173 171 <div className="flex flex-col md:flex-row items-start md:items-center justify-between gap-4"> 174 172 <div className="flex-1"> 175 173 <h2 className="text-2xl font-bold mb-2">Need help getting started?</h2> ··· 177 175 </div> 178 176 <button 179 177 onClick={() => setShowWizard(true)} 180 - className="bg-white text-blue-600 px-6 py-3 rounded-xl font-semibold hover:bg-blue-50 transition-all flex items-center space-x-2 whitespace-nowrap" 178 + className="bg-white text-slate-900 px-6 py-3 rounded-xl font-semibold hover:bg-slate-100 transition-all flex items-center space-x-2 whitespace-nowrap shadow-lg" 181 179 > 182 180 <span>Start Setup</span> 183 181 <ChevronRight className="w-4 h-4" /> ··· 187 185 )} 188 186 189 187 {/* Upload Section */} 190 - <div className="bg-white/95 dark:bg-slate-800/95 backdrop-blur-xl rounded-2xl shadow-lg p-6 border-2 border-slate-200 dark:border-slate-700"> 191 - <div className="flex items-center space-x-3 mb-4"> 192 - <div 193 - className={`w-12 h-12 bg-gradient-to-br from-firefly-amber to-firefly-orange rounded-xl flex items-center justify-center shadow-md ${ 194 - reducedMotion ? '' : 'animate-glow-pulse' 195 - }`} 196 - > 197 - <Upload className="w-6 h-6 text-slate-900" /> 188 + <div className="bg-white dark:bg-gray-800 rounded-2xl shadow-lg p-6 border-2 border-slate-200 dark:border-slate-700"> 189 + <div className="flex items-center justify-between mb-4"> 190 + <div className="flex items-center space-x-3"> 191 + <div className="w-12 h-12 bg-gradient-to-br from-firefly-amber via-firefly-orange to-firefly-pink rounded-xl flex items-center justify-center shadow-md"> 192 + <Upload className="w-6 h-6 text-white" /> 193 + </div> 194 + <div> 195 + <h2 className="text-xl font-bold text-gray-900 dark:text-gray-100"> 196 + Upload Following Data 197 + </h2> 198 + <p className="text-sm text-gray-600 dark:text-gray-400"> 199 + Find your people on the ATmosphere 200 + </p> 201 + </div> 198 202 </div> 199 - <div> 200 - <h2 className="text-xl font-bold text-slate-900 dark:text-slate-100"> 201 - Light Up Your Network 202 - </h2> 203 - <p className="text-sm text-slate-700 dark:text-slate-300"> 204 - Upload your data to find your fireflies 205 - </p> 206 - </div> 203 + {userSettings.wizardCompleted && ( 204 + <button 205 + onClick={() => setShowWizard(true)} 206 + className="text-sm text-firefly-orange hover:text-firefly-pink font-medium transition-colors flex items-center space-x-1" 207 + > 208 + <Settings className="w-4 h-4" /> 209 + <span>Reconfigure</span> 210 + </button> 211 + )} 207 212 </div> 208 213 209 - <p className="text-slate-700 dark:text-slate-300 mb-6"> 210 - Click a platform below to upload your exported data and discover matches in the ATmosphere 211 - </p> 212 - 213 214 <PlatformSelector onPlatformSelect={handlePlatformSelect} /> 214 215 215 216 <input ··· 301 302 </div> 302 303 )} 303 304 304 - {/* Settings Tab - Placeholder */} 305 + {/* Settings Tab */} 305 306 {activeTab === 'settings' && ( 306 - <div className="bg-white dark:bg-gray-800 rounded-2xl shadow-lg p-6"> 307 - <div className="flex items-center space-x-3 mb-6"> 308 - <Settings className="w-6 h-6 text-gray-600 dark:text-gray-400" /> 309 - <h2 className="text-xl font-bold text-gray-900 dark:text-gray-100">Settings</h2> 310 - </div> 311 - <p className="text-gray-600 dark:text-gray-400">Settings page coming soon...</p> 312 - </div> 307 + <SettingsPage 308 + userSettings={userSettings} 309 + onSettingsUpdate={onSettingsUpdate} 310 + onOpenWizard={() => setShowWizard(true)} 311 + /> 313 312 )} 314 313 315 314 {/* Guides Tab - Placeholder */}
+302
src/pages/Settings.tsx
··· 1 + import { Settings as SettingsIcon, Sparkles, Shield, Bell, Trash2, Download, ChevronRight } from "lucide-react"; 2 + import { PLATFORMS } from "../constants/platforms"; 3 + import { ATPROTO_APPS } from "../constants/atprotoApps"; 4 + import type { UserSettings, PlatformDestinations } from "../types/settings"; 5 + 6 + interface SettingsPageProps { 7 + userSettings: UserSettings; 8 + onSettingsUpdate: (settings: Partial<UserSettings>) => void; 9 + onOpenWizard: () => void; 10 + } 11 + 12 + export default function SettingsPage({ userSettings, onSettingsUpdate, onOpenWizard }: SettingsPageProps) { 13 + const handleDestinationChange = (platform: string, destination: string) => { 14 + onSettingsUpdate({ 15 + platformDestinations: { 16 + ...userSettings.platformDestinations, 17 + [platform]: destination, 18 + }, 19 + }); 20 + }; 21 + 22 + const handleExportSettings = () => { 23 + const dataStr = JSON.stringify(userSettings, null, 2); 24 + const dataUri = 'data:application/json;charset=utf-8,' + encodeURIComponent(dataStr); 25 + const exportFileDefaultName = 'atlast-settings.json'; 26 + 27 + const linkElement = document.createElement('a'); 28 + linkElement.setAttribute('href', dataUri); 29 + linkElement.setAttribute('download', exportFileDefaultName); 30 + linkElement.click(); 31 + }; 32 + 33 + const handleResetSettings = () => { 34 + if (confirm('Are you sure you want to reset all settings to defaults? This cannot be undone.')) { 35 + // Import DEFAULT_SETTINGS 36 + const { DEFAULT_SETTINGS } = require('../types/settings'); 37 + onSettingsUpdate({ 38 + ...DEFAULT_SETTINGS, 39 + wizardCompleted: true, // Keep wizard completed 40 + }); 41 + } 42 + }; 43 + 44 + return ( 45 + <div className="space-y-6"> 46 + {/* Setup Wizard Card */} 47 + <div className="bg-white dark:bg-gray-800 rounded-2xl shadow-lg p-6 border-2 border-slate-200 dark:border-slate-700"> 48 + <div className="flex items-center space-x-3 mb-4"> 49 + <div className="w-12 h-12 bg-gradient-to-br from-firefly-amber via-firefly-orange to-firefly-pink rounded-xl flex items-center justify-center shadow-md"> 50 + <Sparkles className="w-6 h-6 text-white" /> 51 + </div> 52 + <div> 53 + <h2 className="text-xl font-bold text-gray-900 dark:text-gray-100">Setup Assistant</h2> 54 + <p className="text-sm text-gray-600 dark:text-gray-400">Quick configuration wizard</p> 55 + </div> 56 + </div> 57 + 58 + <button 59 + onClick={onOpenWizard} 60 + className="w-full p-4 bg-gradient-to-r from-firefly-amber/10 via-firefly-orange/10 to-firefly-pink/10 border-2 border-firefly-orange/30 rounded-xl hover:border-firefly-orange hover:shadow-md transition-all text-left" 61 + > 62 + <div className="flex items-center justify-between"> 63 + <div> 64 + <h3 className="font-semibold text-gray-900 dark:text-gray-100 mb-1">Run Setup Wizard</h3> 65 + <p className="text-sm text-gray-600 dark:text-gray-400"> 66 + Configure platform destinations, privacy, and automation settings 67 + </p> 68 + </div> 69 + <ChevronRight className="w-5 h-5 text-firefly-orange flex-shrink-0" /> 70 + </div> 71 + </button> 72 + </div> 73 + 74 + {/* Platform Destinations */} 75 + <div className="bg-white dark:bg-gray-800 rounded-2xl shadow-lg p-6 border-2 border-slate-200 dark:border-slate-700"> 76 + <div className="flex items-center space-x-3 mb-4"> 77 + <div className="w-12 h-12 bg-gradient-to-br from-firefly-cyan to-firefly-pink rounded-xl flex items-center justify-center shadow-md"> 78 + <SettingsIcon className="w-6 h-6 text-white" /> 79 + </div> 80 + <div> 81 + <h2 className="text-xl font-bold text-gray-900 dark:text-gray-100">Match Destinations</h2> 82 + <p className="text-sm text-gray-600 dark:text-gray-400">Where matches should go for each platform</p> 83 + </div> 84 + </div> 85 + 86 + <div className="space-y-3"> 87 + {Object.entries(PLATFORMS).map(([key, p]) => { 88 + const Icon = p.icon; 89 + const currentDestination = userSettings.platformDestinations[key as keyof PlatformDestinations]; 90 + const destinationApp = ATPROTO_APPS[currentDestination]; 91 + 92 + return ( 93 + <div key={key} className="flex items-center justify-between p-4 bg-gray-50 dark:bg-gray-900 rounded-xl hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors"> 94 + <div className="flex items-center space-x-3 flex-1"> 95 + <Icon className="w-6 h-6 text-gray-700 dark:text-gray-300 flex-shrink-0" /> 96 + <div className="flex-1 min-w-0"> 97 + <div className="font-medium text-gray-900 dark:text-gray-100">{p.name}</div> 98 + <div className="text-xs text-gray-500 dark:text-gray-400 mt-0.5"> 99 + Currently: {destinationApp?.icon} {destinationApp?.name} 100 + </div> 101 + </div> 102 + </div> 103 + <select 104 + value={currentDestination} 105 + onChange={(e) => handleDestinationChange(key, e.target.value)} 106 + className="px-3 py-2 bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-600 rounded-lg text-sm text-gray-900 dark:text-gray-100 hover:border-firefly-orange focus:outline-none focus:ring-2 focus:ring-firefly-orange transition-colors" 107 + > 108 + {Object.values(ATPROTO_APPS).map((app) => ( 109 + <option key={app.id} value={app.id}> 110 + {app.icon} {app.name} 111 + </option> 112 + ))} 113 + </select> 114 + </div> 115 + ); 116 + })} 117 + </div> 118 + 119 + <div className="mt-4 p-3 bg-firefly-amber/10 dark:bg-firefly-amber/20 rounded-lg border border-firefly-amber/30"> 120 + <p className="text-sm text-gray-700 dark:text-gray-300"> 121 + 💡 <strong>Tip:</strong> Choose different apps for different platforms based on content type. 122 + For example, send TikTok matches to Spark for video content. 123 + </p> 124 + </div> 125 + </div> 126 + 127 + {/* Privacy & Data */} 128 + <div className="bg-white dark:bg-gray-800 rounded-2xl shadow-lg p-6 border-2 border-slate-200 dark:border-slate-700"> 129 + <div className="flex items-center space-x-3 mb-4"> 130 + <div className="w-12 h-12 bg-gradient-to-br from-firefly-cyan to-firefly-orange rounded-xl flex items-center justify-center shadow-md"> 131 + <Shield className="w-6 h-6 text-white" /> 132 + </div> 133 + <div> 134 + <h2 className="text-xl font-bold text-gray-900 dark:text-gray-100">Privacy & Data</h2> 135 + <p className="text-sm text-gray-600 dark:text-gray-400">Control how your data is stored</p> 136 + </div> 137 + </div> 138 + 139 + <div className="space-y-3"> 140 + <div className="p-4 bg-firefly-cyan/10 dark:bg-firefly-cyan/20 rounded-xl border border-firefly-cyan/30"> 141 + <div className="flex items-start justify-between"> 142 + <div className="flex-1"> 143 + <div className="font-medium text-gray-900 dark:text-gray-100 mb-1">Save my data</div> 144 + <p className="text-sm text-gray-600 dark:text-gray-400"> 145 + Store your following lists for periodic re-checking and new match notifications 146 + </p> 147 + </div> 148 + <label className="relative inline-flex items-center cursor-pointer ml-4"> 149 + <input 150 + type="checkbox" 151 + checked={userSettings.saveData} 152 + onChange={(e) => onSettingsUpdate({ saveData: e.target.checked })} 153 + className="sr-only peer" 154 + /> 155 + <div className="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-firefly-orange/30 rounded-full peer dark:bg-gray-700 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-firefly-orange"></div> 156 + </label> 157 + </div> 158 + </div> 159 + 160 + {!userSettings.saveData && ( 161 + <div className="p-3 bg-yellow-50 dark:bg-yellow-900/20 rounded-lg border border-yellow-200 dark:border-yellow-800"> 162 + <p className="text-sm text-yellow-800 dark:text-yellow-200"> 163 + ⚠️ <strong>Note:</strong> Disabling data storage will prevent periodic checks and automation features. 164 + </p> 165 + </div> 166 + )} 167 + </div> 168 + </div> 169 + 170 + {/* Automation */} 171 + <div className="bg-white dark:bg-gray-800 rounded-2xl shadow-lg p-6 border-2 border-slate-200 dark:border-slate-700"> 172 + <div className="flex items-center space-x-3 mb-4"> 173 + <div className="w-12 h-12 bg-gradient-to-br from-firefly-pink to-firefly-orange rounded-xl flex items-center justify-center shadow-md"> 174 + <Bell className="w-6 h-6 text-white" /> 175 + </div> 176 + <div> 177 + <h2 className="text-xl font-bold text-gray-900 dark:text-gray-100">Automation</h2> 178 + <p className="text-sm text-gray-600 dark:text-gray-400">Automated checks and notifications</p> 179 + </div> 180 + </div> 181 + 182 + <div className="space-y-3"> 183 + <div className="p-4 bg-firefly-pink/10 dark:bg-firefly-pink/20 rounded-xl border border-firefly-pink/30"> 184 + <div className="flex items-start justify-between"> 185 + <div className="flex-1"> 186 + <div className="font-medium text-gray-900 dark:text-gray-100 mb-1">Notify about new matches</div> 187 + <p className="text-sm text-gray-600 dark:text-gray-400"> 188 + Get DMs when people you follow join the ATmosphere 189 + </p> 190 + </div> 191 + <label className="relative inline-flex items-center cursor-pointer ml-4"> 192 + <input 193 + type="checkbox" 194 + checked={userSettings.enableAutomation} 195 + onChange={(e) => onSettingsUpdate({ enableAutomation: e.target.checked })} 196 + className="sr-only peer" 197 + disabled={!userSettings.saveData} 198 + /> 199 + <div className="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-firefly-pink/30 rounded-full peer dark:bg-gray-700 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-firefly-pink peer-disabled:opacity-50 peer-disabled:cursor-not-allowed"></div> 200 + </label> 201 + </div> 202 + 203 + {userSettings.enableAutomation && ( 204 + <div className="mt-4 pt-4 border-t border-firefly-pink/20"> 205 + <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2"> 206 + Check frequency 207 + </label> 208 + <select 209 + value={userSettings.automationFrequency} 210 + onChange={(e) => onSettingsUpdate({ automationFrequency: e.target.value as 'weekly' | 'monthly' | 'quarterly' })} 211 + className="w-full px-3 py-2 bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-600 rounded-lg text-sm text-gray-900 dark:text-gray-100 hover:border-firefly-pink focus:outline-none focus:ring-2 focus:ring-firefly-pink" 212 + > 213 + <option value="daily">Weekly - Check every week for new matches</option> 214 + <option value="weekly">Monthly - Check once per month</option> 215 + <option value="monthly">Quarterly - Check once per quarter</option> 216 + </select> 217 + </div> 218 + )} 219 + </div> 220 + 221 + {!userSettings.saveData && ( 222 + <div className="p-3 bg-gray-50 dark:bg-gray-900 rounded-lg border border-gray-200 dark:border-gray-700"> 223 + <p className="text-sm text-gray-600 dark:text-gray-400"> 224 + 💡 Enable "Save my data" to use automation features 225 + </p> 226 + </div> 227 + )} 228 + </div> 229 + </div> 230 + 231 + {/* Data Management */} 232 + <div className="bg-white dark:bg-gray-800 rounded-2xl shadow-lg p-6 border-2 border-slate-200 dark:border-slate-700"> 233 + <div className="flex items-center space-x-3 mb-4"> 234 + <div className="w-12 h-12 bg-gradient-to-br from-gray-400 to-gray-600 rounded-xl flex items-center justify-center shadow-md"> 235 + <Download className="w-6 h-6 text-white" /> 236 + </div> 237 + <div> 238 + <h2 className="text-xl font-bold text-gray-900 dark:text-gray-100">Data Management</h2> 239 + <p className="text-sm text-gray-600 dark:text-gray-400">Export or reset your settings</p> 240 + </div> 241 + </div> 242 + 243 + <div className="space-y-3"> 244 + <button 245 + onClick={handleExportSettings} 246 + className="w-full p-4 bg-gray-50 dark:bg-gray-900 rounded-xl border border-gray-200 dark:border-gray-700 hover:border-firefly-cyan hover:bg-gray-100 dark:hover:bg-gray-800 transition-all text-left" 247 + > 248 + <div className="flex items-center justify-between"> 249 + <div> 250 + <h3 className="font-semibold text-gray-900 dark:text-gray-100 mb-1">Export Settings</h3> 251 + <p className="text-sm text-gray-600 dark:text-gray-400"> 252 + Download your settings as a JSON file 253 + </p> 254 + </div> 255 + <Download className="w-5 h-5 text-gray-400 flex-shrink-0" /> 256 + </div> 257 + </button> 258 + 259 + <button 260 + onClick={handleResetSettings} 261 + className="w-full p-4 bg-red-50 dark:bg-red-900/20 rounded-xl border border-red-200 dark:border-red-800 hover:border-red-400 hover:bg-red-100 dark:hover:bg-red-900/30 transition-all text-left" 262 + > 263 + <div className="flex items-center justify-between"> 264 + <div> 265 + <h3 className="font-semibold text-red-700 dark:text-red-400 mb-1">Reset All Settings</h3> 266 + <p className="text-sm text-red-600 dark:text-red-300"> 267 + Restore all settings to default values 268 + </p> 269 + </div> 270 + <Trash2 className="w-5 h-5 text-red-400 flex-shrink-0" /> 271 + </div> 272 + </button> 273 + </div> 274 + </div> 275 + 276 + {/* Current Configuration Summary */} 277 + <div className="bg-gradient-to-r from-firefly-cyan/10 via-firefly-orange/10 to-firefly-pink/10 dark:from-firefly-cyan/5 dark:via-firefly-orange/5 dark:to-firefly-pink/5 rounded-2xl p-6 border-2 border-firefly-orange/30"> 278 + <h3 className="font-semibold text-gray-900 dark:text-gray-100 mb-3">Current Configuration</h3> 279 + <div className="grid md:grid-cols-3 gap-4 text-sm"> 280 + <div> 281 + <div className="text-gray-600 dark:text-gray-400 mb-1">Data Storage</div> 282 + <div className="font-medium text-gray-900 dark:text-gray-100"> 283 + {userSettings.saveData ? '✅ Enabled' : '❌ Disabled'} 284 + </div> 285 + </div> 286 + <div> 287 + <div className="text-gray-600 dark:text-gray-400 mb-1">Automation</div> 288 + <div className="font-medium text-gray-900 dark:text-gray-100"> 289 + {userSettings.enableAutomation ? `✅ ${userSettings.automationFrequency}` : '❌ Disabled'} 290 + </div> 291 + </div> 292 + <div> 293 + <div className="text-gray-600 dark:text-gray-400 mb-1">Wizard</div> 294 + <div className="font-medium text-gray-900 dark:text-gray-100"> 295 + {userSettings.wizardCompleted ? '✅ Completed' : '⏳ Pending'} 296 + </div> 297 + </div> 298 + </div> 299 + </div> 300 + </div> 301 + ); 302 + }