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

refactor setupwizard ot use shared components

byarielm.fyi 394b8f79 7a1bfd08

verified
Changed files
+46 -69
src
components
+46 -69
src/components/SetupWizard.tsx
··· 6 6 import ProgressBar from "./common/ProgressBar"; 7 7 import Card from "./common/Card"; 8 8 import PlatformBadge from "./common/PlatformBadge"; 9 + import Toggle from "./common/Toggle"; 10 + import DropdownWithIcons from "./common/DropdownWithIcons"; 11 + import type { DropdownOptionWithIcon } from "./common/DropdownWithIcons"; 9 12 10 13 interface SetupWizardProps { 11 14 isOpen: boolean; ··· 71 74 ? Object.entries(PLATFORMS).filter(([key]) => selectedPlatforms.has(key)) 72 75 : Object.entries(PLATFORMS); 73 76 77 + // Prepare app options with icons for dropdown 78 + const appOptions: DropdownOptionWithIcon[] = Object.values(ATPROTO_APPS).map( 79 + (app) => ({ 80 + value: app.id, 81 + label: app.name, 82 + icon: app.icon, 83 + }) 84 + ); 85 + 74 86 return ( 75 87 <div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4"> 76 88 <Card ··· 100 112 current={wizardStep + 1} 101 113 total={wizardSteps.length} 102 114 variant="wizard" 103 - className="flex items-center space-x-2" 104 115 /> 105 116 <div className="mt-2 text-sm text-purple-750 dark:text-cyan-250"> 106 117 Step {wizardStep + 1} of {wizardSteps.length}:{" "} ··· 189 200 return ( 190 201 <div 191 202 key={key} 192 - className="flex items-center px-3 max-w-lg mx-sm border-cyan-500/30 dark:border-purple-500/30" 203 + className="flex items-center gap-3 px-3 max-w-lg mx-sm" 193 204 > 194 205 <PlatformBadge platformKey={key} size="sm" /> 195 - <select 206 + <DropdownWithIcons 196 207 value={ 197 208 platformDestinations[ 198 209 key as keyof PlatformDestinations 199 210 ] 200 211 } 201 - onChange={(e) => 212 + onChange={(value) => 202 213 setPlatformDestinations({ 203 214 ...platformDestinations, 204 - [key]: e.target.value, 215 + [key]: value, 205 216 }) 206 217 } 207 - className="px-3 py-2 ml-auto bg-white dark:bg-slate-800 border border-cyan-500/30 dark:border-purple-500/30 rounded-lg text-sm text-purple-950 dark:text-cyan-50 hover:border-cyan-400 dark:hover:border-purple-400 focus:outline-none focus:ring-2 focus:ring-orange-500 dark:focus:ring-amber-400 transition-colors" 208 - > 209 - {Object.values(ATPROTO_APPS).map((app) => ( 210 - <option key={app.id} value={app.id}> 211 - {app.name} 212 - </option> 213 - ))} 214 - </select> 218 + options={appOptions} 219 + className="ml-auto w-48" 220 + /> 215 221 </div> 216 222 ); 217 223 })} ··· 229 235 </p> 230 236 </div> 231 237 232 - <div className="space-y-3"> 233 - <div className="flex items-start space-x-3 px-4 py-3"> 234 - <input 235 - type="checkbox" 236 - checked={saveData} 237 - onChange={(e) => setSaveData(e.target.checked)} 238 - className="mt-1" 239 - id="save-data" 240 - /> 241 - <div className="flex-1"> 242 - <label 243 - htmlFor="save-data" 244 - className="font-medium text-purple-950 dark:text-cyan-50 cursor-pointer" 245 - > 246 - Save my data for future checks 247 - </label> 248 - <p className="text-sm text-purple-950 dark:text-cyan-250 mt-1"> 249 - Store your following lists so we can check for new matches 250 - later. You can delete anytime. 251 - </p> 252 - </div> 253 - </div> 238 + <div className="space-y-4 px-4 py-3"> 239 + <Toggle 240 + checked={saveData} 241 + onChange={setSaveData} 242 + label="Save my data for future checks" 243 + description="Store your following lists so we can check for new matches later. You can delete anytime." 244 + id="save-data" 245 + /> 254 246 255 - <div className="flex items-start space-x-3 px-4 py-3"> 256 - <input 257 - type="checkbox" 247 + <div> 248 + <Toggle 258 249 checked={enableAutomation} 259 - onChange={(e) => setEnableAutomation(e.target.checked)} 260 - className="mt-1" 250 + onChange={setEnableAutomation} 251 + label="Notify me about new matches" 252 + description="We'll check periodically and DM you when people you follow join the ATmosphere." 261 253 id="enable-automation" 262 254 /> 263 - <div className="flex-1"> 264 - <label 265 - htmlFor="enable-automation" 266 - className="font-medium text-purple-950 dark:text-cyan-50 cursor-pointer" 255 + {enableAutomation && ( 256 + <select 257 + value={automationFrequency} 258 + onChange={(e) => 259 + setAutomationFrequency( 260 + e.target.value as "Weekly" | "Monthly" | "Quarterly" 261 + ) 262 + } 263 + className="mt-3 ml-auto max-w-xs px-3 py-2 bg-white dark:bg-slate-800 border border-cyan-500/30 dark:border-purple-500/30 rounded-lg text-sm w-full text-purple-950 dark:text-cyan-50 hover:border-cyan-400 dark:hover:border-purple-400 focus:outline-none focus:ring-2 focus:ring-orange-500 dark:focus:ring-amber-400 transition-colors" 267 264 > 268 - Notify me about new matches 269 - </label> 270 - <p className="text-sm text-purple-750 dark:text-cyan-250 mt-1"> 271 - We'll check periodically and DM you when people you follow 272 - join the ATmosphere. 273 - </p> 274 - {enableAutomation && ( 275 - <select 276 - value={automationFrequency} 277 - onChange={(e) => 278 - setAutomationFrequency( 279 - e.target.value as 280 - | "Weekly" 281 - | "Monthly" 282 - | "Quarterly", 283 - ) 284 - } 285 - className="mt-2 px-3 py-2 bg-white dark:bg-slate-800 border border-cyan-500/30 dark:border-purple-500/30 rounded-lg text-sm w-full text-purple-950 dark:text-cyan-50 hover:border-cyan-400 dark:hover:border-purple-400 focus:outline-none focus:ring-2 focus:ring-orange-500 dark:focus:ring-amber-400 transition-colors" 286 - > 287 - <option value="daily">Check daily</option> 288 - <option value="weekly">Check weekly</option> 289 - <option value="monthly">Check monthly</option> 290 - </select> 291 - )} 292 - </div> 265 + <option value="daily">Check daily</option> 266 + <option value="weekly">Check weekly</option> 267 + <option value="monthly">Check monthly</option> 268 + </select> 269 + )} 293 270 </div> 294 271 </div> 295 272 </div>