33 <header class =" header" >
44 <div class =" logo" >
55 <h1 >FastAPI Forge</h1 >
6- <a class =" github-icon" href =" https://github.com/mslaursen/fastapi-forge" target =" _blank" >
6+ <a class =" github-icon" href =" https://github.com/mslaursen/fastapi-forge" target =" _blank" rel = " noopener noreferrer " >
77 <svg
88 width =" 20"
99 height =" 20"
2020 </svg >
2121 </a >
2222 </div >
23+ <div class =" step-wizard" >
24+ <div class =" step-indicators" >
25+ <div class =" step-action" >
26+ <button :disabled =" currentStep <= 0" @click =" prevStep" class =" btn prev-btn" aria-label =" Previous step" ><</button >
27+ </div >
28+ <div
29+ v-for =" (step, index) in steps"
30+ :key =" index"
31+ :class =" ['step', { active: currentStep === index, completed: currentStep > index }]"
32+ @click =" goToStep(index)"
33+ :aria-label =" 'Go to step ' + (index + 1)"
34+ ></div >
35+ <div class =" step-action" >
36+ <button :disabled =" currentStep >= steps.length - 1" @click =" nextStep" class =" btn next-btn" aria-label =" Next step" >></button >
37+ </div >
38+ </div >
39+ </div >
2340 </header >
41+
2442 <main class =" main" >
25- <div class =" content" >
26- <StepWizard :steps =" steps" />
43+ <div class =" step- content" >
44+ <component :is =" steps[currentStep] " />
2745 </div >
2846 </main >
47+
48+ <GlobalModal ref =" modalRef" />
2949 </div >
30- <GlobalModal ref =" modalRef" />
3150</template >
3251
3352<script setup lang="ts">
34- import StepWizard from " ./components/StepWizard.vue"
3553import ProjectNameStep from " ./components/steps/ProjectNameStep.vue"
3654import DatabaseStep from " ./components/steps/DatabaseStep.vue"
3755import SchemaStep from " ./components/steps/SchemaStep.vue"
3856import FeatureSelectionStep from " ./components/steps/FeatureSelectionStep.vue"
3957import GenerationStep from " ./components/steps/GenerationStep.vue"
4058import GlobalModal from " @/components/modal/GlobalModal.vue"
41-
42- import type { Component } from " vue"
59+ import { ref , type Component } from " vue"
4360
4461const steps: Component [] = [ProjectNameStep , DatabaseStep , SchemaStep , FeatureSelectionStep , GenerationStep ]
62+ const currentStep = ref (0 )
63+ const goToStep = (index : number ) => {
64+ if (index >= 0 && index < steps .length ) {
65+ currentStep .value = index
66+ }
67+ }
68+ const nextStep = () => {
69+ if (currentStep .value < steps .length - 1 ) {
70+ currentStep .value ++
71+ }
72+ }
73+ const prevStep = () => {
74+ if (currentStep .value > 0 ) {
75+ currentStep .value --
76+ }
77+ }
4578 </script >
4679
47- <style >
80+ <style >
4881html ,
4982body {
5083 height : 100% ;
@@ -58,27 +91,41 @@ body {
5891 background-color : var (--color-background );
5992}
6093
94+ .step-content {
95+ margin-bottom : 3rem ;
96+ display : flex ;
97+ justify-content : center ;
98+ }
99+
61100.header {
62101 height : 60px ;
63102 position : sticky ;
64103 flex-shrink : 0 ;
65104 background-color : #ffffff ;
66105 border-bottom : 4px solid black ;
67- top : 0 ;
68- display : flex ;
69- align-items : center ;
70- }
71-
72- .content {
73- flex-grow : 1 ;
74- padding : 1rem ;
106+ display : grid ;
107+ grid-template-columns : 1fr auto 1fr ;
108+ padding : 0 1rem ;
75109}
76110
77111.logo {
78112 display : flex ;
79113 align-items : center ;
80114 gap : 0.5rem ;
81- margin-left : 1rem ;
115+ grid-column : 1 ;
116+ height : 60px ;
117+ }
118+
119+ .step-wizard {
120+ grid-column : 2 ;
121+ display : flex ;
122+ justify-content : center ;
123+ align-items : center ;
124+ }
125+
126+ .main {
127+ flex-grow : 1 ;
128+ padding : 1rem ;
82129}
83130
84131.github-icon {
@@ -104,4 +151,67 @@ body {
104151.github-icon :focus {
105152 color : black ;
106153}
107- </style >
154+
155+ .step-indicators {
156+ display : flex ;
157+ justify-content : center ;
158+ align-items : center ;
159+ gap : 1rem ;
160+ }
161+
162+ .step {
163+ caret-color : transparent ;
164+ width : 50px ;
165+ height : 50px ;
166+ border-radius : 50% ;
167+ background-color : lightgray ;
168+ border : 2px solid black ;
169+ box-shadow : 2px 2px 0px rgba (0 , 0 , 0 , 1 );
170+ transition :
171+ transform 0.1s ease-out ,
172+ box-shadow 0.1s ;
173+ }
174+
175+ .step :hover {
176+ background-color : darkgray ;
177+ box-shadow : 0px 0px 0px rgba (0 , 0 , 0 , 1 );
178+ transform : translate (2px , 2px );
179+ cursor : pointer ;
180+ }
181+
182+ .step.active {
183+ background-color : var (--color-primary );
184+ }
185+
186+ .step.completed {
187+ background-color : var (--color-success );
188+ }
189+
190+ .step-action {
191+ display : flex ;
192+ justify-content : center ;
193+ }
194+
195+ .next-btn ,
196+ .prev-btn ,
197+ .finish-btn {
198+ caret-color : transparent ;
199+ padding : 0.5rem 1rem ;
200+ border : 2px solid black ;
201+ border-radius : 4px ;
202+ background-color : var (--color-background );
203+ box-shadow : 3px 3px 0px rgba (0 , 0 , 0 , 1 );
204+ transition :
205+ transform 0.1s ease-in-out ,
206+ box-shadow 0.1s ;
207+ font-weight : bold ;
208+ }
209+
210+ .next-btn :hover ,
211+ .prev-btn :hover ,
212+ .finish-btn :hover {
213+ transform : translate (2px , 2px );
214+ box-shadow : 0px 0px 0px rgba (0 , 0 , 0 , 1 );
215+ cursor : pointer ;
216+ }
217+ </style >
0 commit comments