22
33import { useMemo , useState } from "react"
44import { Button } from "@/components/ui/button"
5- import { cn } from "@/lib/utils"
6- import { ArrowLeft , Check , ExternalLink , Info } from "lucide-react"
5+ import { ArrowLeft } from "lucide-react"
76import * as simpleIcons from "simple-icons"
87import type { SimpleIcon } from "simple-icons"
98
@@ -15,6 +14,7 @@ import performanceData from "@/data/performance.json"
1514import securityData from "@/data/security.json"
1615import commitsData from "@/data/commits.json"
1716import filesData from "@/data/files.json"
17+ import { InstructionsAnswerCard } from "./instructions-answer-card"
1818
1919type IdeConfig = {
2020 id : string
@@ -358,6 +358,7 @@ export function InstructionsWizard({ onClose }: InstructionsWizardProps) {
358358 const [ responses , setResponses ] = useState < Responses > ( { } )
359359 const [ dynamicSteps , setDynamicSteps ] = useState < WizardStep [ ] > ( [ ] )
360360 const [ isComplete , setIsComplete ] = useState ( false )
361+ const [ showResetConfirm , setShowResetConfirm ] = useState ( false )
361362
362363 const wizardSteps = useMemo (
363364 ( ) => [ ...preFrameworkSteps , ...dynamicSteps , ...postFrameworkSteps ] ,
@@ -568,6 +569,19 @@ export function InstructionsWizard({ onClose }: InstructionsWizardProps) {
568569 setIsComplete ( false )
569570 }
570571
572+ const requestResetWizard = ( ) => {
573+ setShowResetConfirm ( true )
574+ }
575+
576+ const confirmResetWizard = ( ) => {
577+ resetWizard ( )
578+ setShowResetConfirm ( false )
579+ }
580+
581+ const cancelResetWizard = ( ) => {
582+ setShowResetConfirm ( false )
583+ }
584+
571585 const renderCompletion = ( ) => {
572586 const summary = wizardSteps . flatMap ( ( step ) =>
573587 step . questions . map ( ( question ) => {
@@ -622,7 +636,7 @@ export function InstructionsWizard({ onClose }: InstructionsWizardProps) {
622636 </ div >
623637
624638 < div className = "flex flex-wrap gap-2" >
625- < Button variant = "ghost" onClick = { resetWizard } >
639+ < Button variant = "ghost" onClick = { requestResetWizard } >
626640 Start Over
627641 </ Button >
628642 < Button onClick = { ( ) => onClose ?.( ) } >
@@ -698,79 +712,22 @@ export function InstructionsWizard({ onClose }: InstructionsWizardProps) {
698712 )
699713
700714 return (
701- < button
715+ < InstructionsAnswerCard
702716 key = { answer . value }
703- type = "button"
704717 onClick = { ( ) => {
705718 void handleAnswerClick ( answer )
706719 } }
707- aria-disabled = { answer . disabled }
708- className = { cn (
709- "group relative flex h-full items-center justify-between rounded-2xl border border-border/60 bg-background/90 px-5 py-4 text-left transition-all hover:border-primary/40 hover:shadow-md focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring" ,
710- answer . disabled &&
711- "cursor-not-allowed opacity-60 hover:border-border/60 hover:shadow-none focus-visible:ring-0" ,
712- isAnswerSelected ( answer . value ) &&
713- ! answer . disabled &&
714- "border-primary bg-primary/5 shadow-lg shadow-primary/20"
715- ) }
716- >
717- < div className = "flex items-center gap-3" >
718- { iconElement }
719- < div className = "flex items-center gap-2" >
720- < span className = "text-base font-medium text-foreground" >
721- { answer . label }
722- </ span >
723- { hasTooltipContent ? (
724- < span className = "relative flex items-center group/icon" >
725- < Info className = "h-4 w-4 cursor-pointer text-muted-foreground transition-colors group-hover/icon:text-primary" />
726- < div className = "pointer-events-none absolute left-0 top-full z-20 hidden w-60 rounded-xl border border-border/70 bg-popover p-3 text-xs leading-relaxed text-popover-foreground shadow-xl transition-all duration-150 ease-out group-hover/icon:flex group-hover/icon:flex-col group-hover/icon:pointer-events-auto group-hover/icon:opacity-100 group-hover/icon:translate-y-0 opacity-0 translate-y-2" >
727- { answer . infoLines ?. map ( ( line ) => (
728- < span key = { line } className = "text-foreground" >
729- { line }
730- </ span >
731- ) ) }
732- { answer . example ? (
733- < span className = "mt-1 text-muted-foreground" > { answer . example } </ span >
734- ) : null }
735- { answer . tags && answer . tags . length > 0 ? (
736- < div className = "mt-3 flex flex-wrap gap-1 text-[10px] uppercase tracking-wide text-muted-foreground/80" >
737- { answer . tags . map ( ( tag ) => (
738- < span key = { tag } className = "rounded-full bg-muted/80 px-2 py-0.5" >
739- { tag }
740- </ span >
741- ) ) }
742- </ div >
743- ) : null }
744- { answer . docs ? (
745- < a
746- href = { answer . docs }
747- target = "_blank"
748- rel = "noopener noreferrer"
749- className = "mt-3 inline-flex items-center gap-1 text-xs font-medium text-primary hover:underline"
750- >
751- < span > Open documentation</ span >
752- < ExternalLink className = "h-3.5 w-3.5" />
753- </ a >
754- ) : null }
755- </ div >
756- </ span >
757- ) : null }
758- { answer . disabledLabel ? (
759- < span className = "rounded-full bg-muted px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground/80" >
760- { answer . disabledLabel }
761- </ span >
762- ) : null }
763- </ div >
764- </ div >
765-
766- < div className = "flex items-center gap-2" >
767- { isAnswerSelected ( answer . value ) && ! answer . disabled ? (
768- < span className = "flex h-7 w-7 items-center justify-center rounded-full bg-primary text-primary-foreground" >
769- < Check className = "h-4 w-4" />
770- </ span >
771- ) : null }
772- </ div >
773- </ button >
720+ label = { answer . label }
721+ iconElement = { iconElement }
722+ hasTooltipContent = { hasTooltipContent }
723+ infoLines = { answer . infoLines }
724+ example = { answer . example }
725+ tags = { answer . tags }
726+ docs = { answer . docs }
727+ selected = { isAnswerSelected ( answer . value ) }
728+ disabled = { answer . disabled }
729+ disabledLabel = { answer . disabledLabel }
730+ />
774731 )
775732 } ) }
776733 </ div >
@@ -790,6 +747,27 @@ export function InstructionsWizard({ onClose }: InstructionsWizardProps) {
790747 </ section >
791748 </ >
792749 ) }
750+
751+ { showResetConfirm ? (
752+ < div className = "fixed inset-0 z-50 flex items-center justify-center bg-background/80 p-4 backdrop-blur-sm" >
753+ < div className = "w-full max-w-md space-y-4 rounded-2xl border border-border/70 bg-card/95 p-6 shadow-2xl" >
754+ < div className = "space-y-2" >
755+ < h3 className = "text-lg font-semibold text-foreground" > Start over?</ h3 >
756+ < p className = "text-sm text-muted-foreground" >
757+ This will clear all of your current selections. Are you sure you want to continue?
758+ </ p >
759+ </ div >
760+ < div className = "flex flex-wrap justify-end gap-2" >
761+ < Button variant = "ghost" onClick = { cancelResetWizard } >
762+ Keep My Answers
763+ </ Button >
764+ < Button variant = "destructive" onClick = { confirmResetWizard } >
765+ Reset Wizard
766+ </ Button >
767+ </ div >
768+ </ div >
769+ </ div >
770+ ) : null }
793771 </ div >
794772 )
795773}
0 commit comments