Skip to content

Commit 8737cf9

Browse files
committed
Update avatar generation flow with preview
- Add showPreview state to control when to show the generated avatar - Change final step to show summary instead of preview - Update button text from 'Complete' to 'Generate my avatar' - Add generateAvatar function to show preview - Move actual avatar card to preview state with download button - Hide navigation when showing preview - Add smooth scale animation for preview transition - Separate 'Generate my avatar' and 'Download my avatar' actions
1 parent 857205d commit 8737cf9

File tree

1 file changed

+162
-87
lines changed

1 file changed

+162
-87
lines changed

src/app/my-avatar/page.tsx

Lines changed: 162 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ const WORKING_STYLE_OPTIONS = [
102102

103103
export default function MyAvatarPage() {
104104
const [currentStep, setCurrentStep] = useState(0);
105+
const [showPreview, setShowPreview] = useState(false);
105106
const [avatarData, setAvatarData] = useState<AvatarData>({
106107
primaryColor: '',
107108
secondaryColor: '',
@@ -145,6 +146,10 @@ export default function MyAvatarPage() {
145146
}
146147
};
147148

149+
const generateAvatar = () => {
150+
setShowPreview(true);
151+
};
152+
148153
const prevStep = () => {
149154
if (currentStep > 0) {
150155
setCurrentStep(currentStep - 1);
@@ -320,32 +325,36 @@ export default function MyAvatarPage() {
320325
return (
321326
<div className="space-y-8">
322327
<div className="text-center">
323-
<h2 className="text-3xl font-bold text-foreground mb-4">Your Designer Profile</h2>
324-
<p className="text-muted-foreground text-lg">Here&apos;s your completed avatar card</p>
328+
<h2 className="text-3xl font-bold text-foreground mb-4">Ready to Generate?</h2>
329+
<p className="text-muted-foreground text-lg">Review your information and generate your avatar card</p>
325330
</div>
326331

327332
<div className="max-w-2xl mx-auto">
328-
{/* Complete Profile Card */}
333+
{/* Summary Card */}
329334
<div className="bg-gradient-to-br from-background to-muted/20 p-8 rounded-2xl border border-border shadow-lg">
330-
<div className="flex items-center space-x-6 mb-6">
331-
<div className="relative">
332-
<Avatar name="Your Name" size={80} />
333-
<div className="absolute -bottom-1 -right-1 w-6 h-6 rounded-full border-2 border-background"
334-
style={{ backgroundColor: avatarData.primaryColor }} />
335+
<div className="space-y-4">
336+
<div>
337+
<h4 className="font-medium text-foreground mb-2">Design Philosophy</h4>
338+
<p className="text-accent capitalize">{avatarData.philosophy}</p>
335339
</div>
336-
<div className="flex-1">
337-
<h3 className="text-xl font-semibold text-foreground mb-1">{avatarData.role}</h3>
338-
<p className="text-muted-foreground text-sm mb-2">{avatarData.organizationDescription}</p>
339-
<div className="flex items-center space-x-2">
340-
<span className="text-xs text-muted-foreground">Philosophy:</span>
341-
<span className="text-xs font-medium text-accent capitalize">{avatarData.philosophy}</span>
342-
</div>
340+
341+
<div>
342+
<h4 className="font-medium text-foreground mb-2">Working Style</h4>
343+
<p className="text-muted-foreground capitalize">{avatarData.workingStyle.replace('-', ' ')}</p>
343344
</div>
344-
</div>
345-
346-
<div className="space-y-4">
345+
347346
<div>
348-
<h4 className="font-medium text-foreground mb-3">Expertise</h4>
347+
<h4 className="font-medium text-foreground mb-2">Role</h4>
348+
<p className="text-muted-foreground">{avatarData.role}</p>
349+
</div>
350+
351+
<div>
352+
<h4 className="font-medium text-foreground mb-2">Organization Description</h4>
353+
<p className="text-muted-foreground">{avatarData.organizationDescription}</p>
354+
</div>
355+
356+
<div>
357+
<h4 className="font-medium text-foreground mb-2">Expertise</h4>
349358
<div className="flex flex-wrap gap-2">
350359
{avatarData.keywords.filter(k => k.trim()).map((keyword, index) => (
351360
<span
@@ -357,29 +366,6 @@ export default function MyAvatarPage() {
357366
))}
358367
</div>
359368
</div>
360-
361-
<div className="pt-4 border-t border-border/50">
362-
<div className="flex items-center justify-between">
363-
<div>
364-
<h4 className="font-medium text-foreground mb-2">Design Style</h4>
365-
<div className="flex items-center space-x-3">
366-
<div className="flex space-x-1">
367-
<div
368-
className="w-4 h-4 rounded-full"
369-
style={{ backgroundColor: avatarData.primaryColor }}
370-
/>
371-
<div
372-
className="w-4 h-4 rounded-full"
373-
style={{ backgroundColor: avatarData.secondaryColor }}
374-
/>
375-
</div>
376-
<span className="text-sm text-muted-foreground capitalize">
377-
{avatarData.workingStyle.replace('-', ' ')} approach
378-
</span>
379-
</div>
380-
</div>
381-
</div>
382-
</div>
383369
</div>
384370
</div>
385371
</div>
@@ -397,59 +383,148 @@ export default function MyAvatarPage() {
397383
<div className="flex-1 flex items-center justify-center px-4 sm:px-6 lg:px-8 py-12">
398384
<div className="w-full max-w-4xl">
399385
<AnimatePresence mode="wait">
400-
<motion.div
401-
key={currentStep}
402-
initial={{ opacity: 0, x: 20 }}
403-
animate={{ opacity: 1, x: 0 }}
404-
exit={{ opacity: 0, x: -20 }}
405-
transition={{ duration: 0.3 }}
406-
>
407-
{renderStep()}
408-
</motion.div>
386+
{showPreview ? (
387+
<motion.div
388+
key="preview"
389+
initial={{ opacity: 0, scale: 0.95 }}
390+
animate={{ opacity: 1, scale: 1 }}
391+
exit={{ opacity: 0, scale: 0.95 }}
392+
transition={{ duration: 0.3 }}
393+
>
394+
<div className="space-y-8">
395+
<div className="text-center">
396+
<h2 className="text-3xl font-bold text-foreground mb-4">Your Designer Profile</h2>
397+
<p className="text-muted-foreground text-lg">Here&apos;s your completed avatar card</p>
398+
</div>
399+
400+
<div className="max-w-2xl mx-auto">
401+
{/* Complete Profile Card */}
402+
<div className="bg-gradient-to-br from-background to-muted/20 p-8 rounded-2xl border border-border shadow-lg">
403+
<div className="flex items-center space-x-6 mb-6">
404+
<div className="relative">
405+
<Avatar name="Your Name" size={80} />
406+
<div className="absolute -bottom-1 -right-1 w-6 h-6 rounded-full border-2 border-background"
407+
style={{ backgroundColor: avatarData.primaryColor }} />
408+
</div>
409+
<div className="flex-1">
410+
<h3 className="text-xl font-semibold text-foreground mb-1">{avatarData.role}</h3>
411+
<p className="text-muted-foreground text-sm mb-2">{avatarData.organizationDescription}</p>
412+
<div className="flex items-center space-x-2">
413+
<span className="text-xs text-muted-foreground">Philosophy:</span>
414+
<span className="text-xs font-medium text-accent capitalize">{avatarData.philosophy}</span>
415+
</div>
416+
</div>
417+
</div>
418+
419+
<div className="space-y-4">
420+
<div>
421+
<h4 className="font-medium text-foreground mb-3">Expertise</h4>
422+
<div className="flex flex-wrap gap-2">
423+
{avatarData.keywords.filter(k => k.trim()).map((keyword, index) => (
424+
<span
425+
key={index}
426+
className="px-3 py-1 bg-accent/10 text-accent rounded-full text-sm font-medium"
427+
>
428+
{keyword}
429+
</span>
430+
))}
431+
</div>
432+
</div>
433+
434+
<div className="pt-4 border-t border-border/50">
435+
<div className="flex items-center justify-between">
436+
<div>
437+
<h4 className="font-medium text-foreground mb-2">Design Style</h4>
438+
<div className="flex items-center space-x-3">
439+
<div className="flex space-x-1">
440+
<div
441+
className="w-4 h-4 rounded-full"
442+
style={{ backgroundColor: avatarData.primaryColor }}
443+
/>
444+
<div
445+
className="w-4 h-4 rounded-full"
446+
style={{ backgroundColor: avatarData.secondaryColor }}
447+
/>
448+
</div>
449+
<span className="text-sm text-muted-foreground capitalize">
450+
{avatarData.workingStyle.replace('-', ' ')} approach
451+
</span>
452+
</div>
453+
</div>
454+
</div>
455+
</div>
456+
</div>
457+
</div>
458+
459+
<motion.button
460+
whileHover={{ scale: 1.02 }}
461+
whileTap={{ scale: 0.98 }}
462+
onClick={generateXML}
463+
className="w-full mt-8 bg-accent text-white py-4 px-6 rounded-lg font-semibold hover:bg-accent/90 transition-colors flex items-center justify-center space-x-2"
464+
>
465+
<Download className="w-5 h-5" />
466+
<span>Download my avatar</span>
467+
</motion.button>
468+
</div>
469+
</div>
470+
</motion.div>
471+
) : (
472+
<motion.div
473+
key={currentStep}
474+
initial={{ opacity: 0, x: 20 }}
475+
animate={{ opacity: 1, x: 0 }}
476+
exit={{ opacity: 0, x: -20 }}
477+
transition={{ duration: 0.3 }}
478+
>
479+
{renderStep()}
480+
</motion.div>
481+
)}
409482
</AnimatePresence>
410483
</div>
411484
</div>
412485

413486
{/* Navigation */}
414-
<div className="fixed bottom-0 left-0 right-0 bg-background border-t border-border">
415-
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6">
416-
<div className="flex items-center justify-between">
417-
<motion.button
418-
whileHover={{ scale: 1.02 }}
419-
whileTap={{ scale: 0.98 }}
420-
onClick={prevStep}
421-
disabled={currentStep === 0}
422-
className={`flex items-center space-x-2 px-6 py-3 rounded-lg font-medium transition-colors ${
423-
currentStep === 0
424-
? 'text-muted-foreground cursor-not-allowed'
425-
: 'text-foreground hover:bg-muted'
426-
}`}
427-
>
428-
<ArrowLeft className="w-4 h-4" />
429-
<span>Previous</span>
430-
</motion.button>
487+
{!showPreview && (
488+
<div className="fixed bottom-0 left-0 right-0 bg-background border-t border-border">
489+
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6">
490+
<div className="flex items-center justify-between">
491+
<motion.button
492+
whileHover={{ scale: 1.02 }}
493+
whileTap={{ scale: 0.98 }}
494+
onClick={prevStep}
495+
disabled={currentStep === 0}
496+
className={`flex items-center space-x-2 px-6 py-3 rounded-lg font-medium transition-colors ${
497+
currentStep === 0
498+
? 'text-muted-foreground cursor-not-allowed'
499+
: 'text-foreground hover:bg-muted'
500+
}`}
501+
>
502+
<ArrowLeft className="w-4 h-4" />
503+
<span>Previous</span>
504+
</motion.button>
431505

432-
<motion.button
433-
whileHover={{ scale: 1.02 }}
434-
whileTap={{ scale: 0.98 }}
435-
onClick={currentStep === STEPS.length - 1 ? generateXML : nextStep}
436-
disabled={!isStepComplete(currentStep)}
437-
className={`flex items-center space-x-2 px-6 py-3 rounded-lg font-medium transition-colors ${
438-
!isStepComplete(currentStep)
439-
? 'text-muted-foreground cursor-not-allowed'
440-
: 'bg-accent text-white hover:bg-accent/90'
441-
}`}
442-
>
443-
<span>{currentStep === STEPS.length - 1 ? 'Complete' : 'Next'}</span>
444-
{currentStep === STEPS.length - 1 ? (
445-
<Download className="w-4 h-4" />
446-
) : (
447-
<ArrowRight className="w-4 h-4" />
448-
)}
449-
</motion.button>
506+
<motion.button
507+
whileHover={{ scale: 1.02 }}
508+
whileTap={{ scale: 0.98 }}
509+
onClick={currentStep === STEPS.length - 1 ? generateAvatar : nextStep}
510+
disabled={!isStepComplete(currentStep)}
511+
className={`flex items-center space-x-2 px-6 py-3 rounded-lg font-medium transition-colors ${
512+
!isStepComplete(currentStep)
513+
? 'text-muted-foreground cursor-not-allowed'
514+
: 'bg-accent text-white hover:bg-accent/90'
515+
}`}
516+
>
517+
<span>{currentStep === STEPS.length - 1 ? 'Generate my avatar' : 'Next'}</span>
518+
{currentStep === STEPS.length - 1 ? (
519+
<Sparkles className="w-4 h-4" />
520+
) : (
521+
<ArrowRight className="w-4 h-4" />
522+
)}
523+
</motion.button>
524+
</div>
450525
</div>
451526
</div>
452-
</div>
527+
)}
453528
</div>
454529
);
455530
}

0 commit comments

Comments
 (0)