feat(15): steps summary as dynamic fragment
defined in step1, reused in other steps
This commit is contained in:
		
							parent
							
								
									77e70c3536
								
							
						
					
					
						commit
						a52ab42c61
					
				| @ -829,6 +829,21 @@ video { | |||||||
|   background-color: rgb(255 255 255 / var(--tw-bg-opacity)); |   background-color: rgb(255 255 255 / var(--tw-bg-opacity)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | .\!bg-red-500 { | ||||||
|  |   --tw-bg-opacity: 1 !important; | ||||||
|  |   background-color: rgb(239 68 68 / var(--tw-bg-opacity)) !important; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .\!bg-white { | ||||||
|  |   --tw-bg-opacity: 1 !important; | ||||||
|  |   background-color: rgb(255 255 255 / var(--tw-bg-opacity)) !important; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .\!bg-light-blue { | ||||||
|  |   --tw-bg-opacity: 1 !important; | ||||||
|  |   background-color: hsl(206 94% 87% / var(--tw-bg-opacity)) !important; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| .bg-sidebar-mobile { | .bg-sidebar-mobile { | ||||||
|   background-image: url("images/bg-sidebar-mobile.svg"); |   background-image: url("images/bg-sidebar-mobile.svg"); | ||||||
| } | } | ||||||
| @ -939,6 +954,11 @@ video { | |||||||
|   color: rgb(255 255 255 / var(--tw-text-opacity)); |   color: rgb(255 255 255 / var(--tw-text-opacity)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | .\!text-marine-blue { | ||||||
|  |   --tw-text-opacity: 1 !important; | ||||||
|  |   color: hsl(213 96% 18% / var(--tw-text-opacity)) !important; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| .drop-shadow-xl { | .drop-shadow-xl { | ||||||
|   --tw-drop-shadow: drop-shadow(0 20px 13px rgb(0 0 0 / 0.03)) drop-shadow(0 8px 5px rgb(0 0 0 / 0.08)); |   --tw-drop-shadow: drop-shadow(0 20px 13px rgb(0 0 0 / 0.03)) drop-shadow(0 8px 5px rgb(0 0 0 / 0.08)); | ||||||
|   filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); |   filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); | ||||||
|  | |||||||
| @ -38,7 +38,7 @@ | |||||||
|     <form |     <form | ||||||
|       class="flex flex-col items-center w-screen h-screen md:grid md:items-start md:p-5 md:bg-white md:rounded-2xl md:grid-cols-[auto_1fr] md:w-desktop-form md:h-desktop-form md:drop-shadow-2xl" |       class="flex flex-col items-center w-screen h-screen md:grid md:items-start md:p-5 md:bg-white md:rounded-2xl md:grid-cols-[auto_1fr] md:w-desktop-form md:h-desktop-form md:drop-shadow-2xl" | ||||||
|       id="form-step" |       id="form-step" | ||||||
|       th:fragment="formFragment(formData.userAnswers)" |       th:fragment="formFragment(formData)" | ||||||
|       hx-post="/submit-step/1/2" |       hx-post="/submit-step/1/2" | ||||||
|       hx-swap="outerHTML" |       hx-swap="outerHTML" | ||||||
|       action="/submit-step/1/2" |       action="/submit-step/1/2" | ||||||
| @ -47,48 +47,70 @@ | |||||||
|       <summary |       <summary | ||||||
|         class="w-full h-44 bg-no-repeat md:row-span-2 bg-sidebar-mobile marker:text-white md:bg-sidebar-desktop md:h-[568px] md:w-[274px]" |         class="w-full h-44 bg-no-repeat md:row-span-2 bg-sidebar-mobile marker:text-white md:bg-sidebar-desktop md:h-[568px] md:w-[274px]" | ||||||
|         id="sidebar" |         id="sidebar" | ||||||
|  |         th:fragment="stepsSummary(formData)" | ||||||
|       > |       > | ||||||
|         <ol |         <ol | ||||||
|           class="grid grid-cols-[repeat(4,_auto)] gap-x-5 content-center items-center place-content-center h-24 md:flex-col md:h-full md:grid-rows-[repeat(4,_auto)] md:grid-cols-1 md:content-start md:p-10 md:gap-y-7 text-white text-sm uppercase" |           class="grid grid-cols-[repeat(4,_auto)] gap-x-5 content-center items-center place-content-center h-24 md:flex-col md:h-full md:grid-rows-[repeat(4,_auto)] md:grid-cols-1 md:content-start md:p-10 md:gap-y-7 text-white text-sm uppercase" | ||||||
|         > |         > | ||||||
|           <li class="items-center md:grid md:gap-x-4 md:grid-cols-[auto_1fr]"> |           <li | ||||||
|  |             class="items-center md:grid md:gap-x-4 md:grid-cols-[auto_1fr]" | ||||||
|  |             th:each="stepNum: ${formData.stepsAmount}" | ||||||
|  |           > | ||||||
|             <div |             <div | ||||||
|               class="grid place-content-center w-8 h-8 text-white rounded-full border border-white" |               class="grid place-content-center w-8 h-8 font-bold text-white rounded-full border border-white" | ||||||
|  |               th:classappend="${stepNum.index} == ${formData.userAnswers.currentStep} ? '!bg-light-blue !text-marine-blue'" | ||||||
|  |               th:text="${stepNum.index}" | ||||||
|             > |             > | ||||||
|               1 |               1 | ||||||
|             </div> |             </div> | ||||||
|             <p class="hidden md:flex md:flex-col"> |             <p class="hidden md:flex md:flex-col"> | ||||||
|               <span class="text-light-gray">Step 1</span><span class="font-bold">Your info</span> |               <span class="text-light-gray" | ||||||
|  |                 >Step <span th:text="${stepNum.index}">1</span></span | ||||||
|  |               ><span class="font-bold" th:text="${stepNum.name}" | ||||||
|  |                 >Your info</span | ||||||
|  |               > | ||||||
|             </p> |             </p> | ||||||
|           </li> |           </li> | ||||||
|           <li class="items-center md:grid md:gap-x-4 md:grid-cols-[auto_1fr]"> |           <li | ||||||
|  |             class="items-center md:grid md:gap-x-4 md:grid-cols-[auto_1fr]" | ||||||
|  |             th:remove="all" | ||||||
|  |           > | ||||||
|             <div |             <div | ||||||
|               class="grid place-content-center w-8 h-8 text-white rounded-full border border-white" |               class="grid place-content-center w-8 h-8 text-white rounded-full border border-white" | ||||||
|             > |             > | ||||||
|               2 |               2 | ||||||
|             </div> |             </div> | ||||||
|             <p class="hidden md:flex md:flex-col"> |             <p class="hidden md:flex md:flex-col"> | ||||||
|               <span class="text-light-gray">Step 2</span><span class="font-bold">Select plan</span> |               <span class="text-light-gray">Step 2</span | ||||||
|  |               ><span class="font-bold">Select plan</span> | ||||||
|             </p> |             </p> | ||||||
|           </li> |           </li> | ||||||
|           <li class="items-center md:grid md:gap-x-4 md:grid-cols-[auto_1fr]"> |           <li | ||||||
|  |             class="items-center md:grid md:gap-x-4 md:grid-cols-[auto_1fr]" | ||||||
|  |             th:remove="all" | ||||||
|  |           > | ||||||
|             <div |             <div | ||||||
|               class="grid place-content-center w-8 h-8 text-white rounded-full border border-white" |               class="grid place-content-center w-8 h-8 text-white rounded-full border border-white" | ||||||
|             > |             > | ||||||
|               3 |               3 | ||||||
|             </div> |             </div> | ||||||
|             <p class="hidden md:flex md:flex-col"> |             <p class="hidden md:flex md:flex-col"> | ||||||
|               <span class="text-light-gray">Step 3</span><span class="font-bold">Add-ons</span> |               <span class="text-light-gray">Step 3</span | ||||||
|  |               ><span class="font-bold">Add-ons</span> | ||||||
|             </p> |             </p> | ||||||
|           </li> |           </li> | ||||||
|           <li class="items-center md:grid md:gap-x-4 md:grid-cols-[auto_1fr]"> |           <li | ||||||
|  |             class="items-center md:grid md:gap-x-4 md:grid-cols-[auto_1fr]" | ||||||
|  |             th:remove="all" | ||||||
|  |           > | ||||||
|             <div |             <div | ||||||
|               class="grid place-content-center w-8 h-8 text-white rounded-full border border-white" |               class="grid place-content-center w-8 h-8 text-white rounded-full border border-white" | ||||||
|             > |             > | ||||||
|               4 |               4 | ||||||
|             </div> |             </div> | ||||||
|             <p class="hidden md:flex md:flex-col"> |             <p class="hidden md:flex md:flex-col"> | ||||||
|               <span class="text-light-gray">Step 4</span><span class="font-bold">summary</span> |               <span class="text-light-gray">Step 4</span | ||||||
|  |               ><span class="font-bold">summary</span> | ||||||
|             </p> |             </p> | ||||||
|           </li> |           </li> | ||||||
|         </ol> |         </ol> | ||||||
| @ -98,11 +120,15 @@ | |||||||
|         class="flex flex-col py-8 px-6 -mt-20 w-11/12 bg-white rounded-xl md:px-24 md:mt-0 md:w-full drop-shadow-xl md:drop-shadow-none" |         class="flex flex-col py-8 px-6 -mt-20 w-11/12 bg-white rounded-xl md:px-24 md:mt-0 md:w-full drop-shadow-xl md:drop-shadow-none" | ||||||
|       > |       > | ||||||
|         <!-- Step 1 start --> |         <!-- Step 1 start --> | ||||||
|         <h1 class="text-2xl font-bold md:text-4xl text-marine-blue">Personal info</h1> |         <h1 class="text-2xl font-bold md:text-4xl text-marine-blue"> | ||||||
|  |           Personal info | ||||||
|  |         </h1> | ||||||
|         <p class="py-3 text-cool-gray"> |         <p class="py-3 text-cool-gray"> | ||||||
|           Please provide your name, email address, and phone number. |           Please provide your name, email address, and phone number. | ||||||
|         </p> |         </p> | ||||||
|         <label for="name" class="pt-3 text-sm md:pt-5 md:pb-2 text-marine-blue">Name</label> |         <label for="name" class="pt-3 text-sm md:pt-5 md:pb-2 text-marine-blue" | ||||||
|  |           >Name</label | ||||||
|  |         > | ||||||
|         <input |         <input | ||||||
|           id="name" |           id="name" | ||||||
|           th:value="${formData.userAnswers.step1.name}" |           th:value="${formData.userAnswers.step1.name}" | ||||||
| @ -146,7 +172,7 @@ | |||||||
|           type="submit" |           type="submit" | ||||||
|           class="grid place-content-center mr-3 w-24 h-10 text-sm font-semibold text-white rounded md:mr-24 md:w-32 md:h-12 md:text-base md:rounded-lg bg-marine-blue" |           class="grid place-content-center mr-3 w-24 h-10 text-sm font-semibold text-white rounded md:mr-24 md:w-32 md:h-12 md:text-base md:rounded-lg bg-marine-blue" | ||||||
|           value="Next Step" |           value="Next Step" | ||||||
|           > |         /> | ||||||
|         <a |         <a | ||||||
|           th:remove="all" |           th:remove="all" | ||||||
|           href="step2.html" |           href="step2.html" | ||||||
|  | |||||||
| @ -43,11 +43,12 @@ | |||||||
|         hx-swap="outerHTML" |         hx-swap="outerHTML" | ||||||
|         action="/submit-step/2/3" |         action="/submit-step/2/3" | ||||||
|         method="post" |         method="post" | ||||||
|         th:fragment="formFragment(formData.userAnswers)" |         th:fragment="formFragment(formData)" | ||||||
|       > |       > | ||||||
|         <summary |         <summary | ||||||
|           class="w-full h-44 bg-no-repeat md:row-span-2 bg-sidebar-mobile marker:text-white md:bg-sidebar-desktop md:h-[568px] md:w-[274px]" |           class="w-full h-44 bg-no-repeat md:row-span-2 bg-sidebar-mobile marker:text-white md:bg-sidebar-desktop md:h-[568px] md:w-[274px]" | ||||||
|           id="sidebar" |           id="sidebar" | ||||||
|  |           th:replace="~{step1::stepsSummary (${formData})}" | ||||||
|         > |         > | ||||||
|           <ol |           <ol | ||||||
|             class="grid grid-cols-[repeat(4,_auto)] gap-x-5 content-center items-center place-content-center h-24 md:flex-col md:h-full md:grid-rows-[repeat(4,_auto)] md:grid-cols-1 md:content-start md:p-10 md:gap-y-7 text-white text-sm uppercase" |             class="grid grid-cols-[repeat(4,_auto)] gap-x-5 content-center items-center place-content-center h-24 md:flex-col md:h-full md:grid-rows-[repeat(4,_auto)] md:grid-cols-1 md:content-start md:p-10 md:gap-y-7 text-white text-sm uppercase" | ||||||
|  | |||||||
| @ -43,11 +43,12 @@ | |||||||
|         hx-swap="outerHTML" |         hx-swap="outerHTML" | ||||||
|         action="/submit-step/3/4" |         action="/submit-step/3/4" | ||||||
|         method="post" |         method="post" | ||||||
|         th:fragment="formFragment(formData.userAnswers)" |         th:fragment="formFragment(formData)" | ||||||
|       > |       > | ||||||
|         <summary |         <summary | ||||||
|           class="w-full h-44 bg-no-repeat md:row-span-2 bg-sidebar-mobile marker:text-white md:bg-sidebar-desktop md:h-[568px] md:w-[274px]" |           class="w-full h-44 bg-no-repeat md:row-span-2 bg-sidebar-mobile marker:text-white md:bg-sidebar-desktop md:h-[568px] md:w-[274px]" | ||||||
|           id="sidebar" |           id="sidebar" | ||||||
|  |           th:replace="~{step1::stepsSummary (${formData})}" | ||||||
|         > |         > | ||||||
|           <ol |           <ol | ||||||
|             class="grid grid-cols-[repeat(4,_auto)] gap-x-5 content-center items-center place-content-center h-24 md:flex-col md:h-full md:grid-rows-[repeat(4,_auto)] md:grid-cols-1 md:content-start md:p-10 md:gap-y-7 text-white text-sm uppercase" |             class="grid grid-cols-[repeat(4,_auto)] gap-x-5 content-center items-center place-content-center h-24 md:flex-col md:h-full md:grid-rows-[repeat(4,_auto)] md:grid-cols-1 md:content-start md:p-10 md:gap-y-7 text-white text-sm uppercase" | ||||||
|  | |||||||
| @ -48,6 +48,7 @@ | |||||||
|         <summary |         <summary | ||||||
|           class="w-full h-44 bg-no-repeat md:row-span-2 bg-sidebar-mobile marker:text-white md:bg-sidebar-desktop md:h-[568px] md:w-[274px]" |           class="w-full h-44 bg-no-repeat md:row-span-2 bg-sidebar-mobile marker:text-white md:bg-sidebar-desktop md:h-[568px] md:w-[274px]" | ||||||
|           id="sidebar" |           id="sidebar" | ||||||
|  |           th:replace="~{step1::stepsSummary (${formData})}" | ||||||
|         > |         > | ||||||
|           <ol |           <ol | ||||||
|             class="grid grid-cols-[repeat(4,_auto)] gap-x-5 content-center items-center place-content-center h-24 md:flex-col md:h-full md:grid-rows-[repeat(4,_auto)] md:grid-cols-1 md:content-start md:p-10 md:gap-y-7 text-white text-sm uppercase" |             class="grid grid-cols-[repeat(4,_auto)] gap-x-5 content-center items-center place-content-center h-24 md:flex-col md:h-full md:grid-rows-[repeat(4,_auto)] md:grid-cols-1 md:content-start md:p-10 md:gap-y-7 text-white text-sm uppercase" | ||||||
|  | |||||||
| @ -44,6 +44,7 @@ | |||||||
|         <summary |         <summary | ||||||
|           class="w-full h-44 bg-no-repeat md:row-span-2 bg-sidebar-mobile marker:text-white md:bg-sidebar-desktop md:h-[568px] md:w-[274px]" |           class="w-full h-44 bg-no-repeat md:row-span-2 bg-sidebar-mobile marker:text-white md:bg-sidebar-desktop md:h-[568px] md:w-[274px]" | ||||||
|           id="sidebar" |           id="sidebar" | ||||||
|  |           th:replace="~{step1::stepsSummary (${formData})}" | ||||||
|         > |         > | ||||||
|           <ol |           <ol | ||||||
|             class="grid grid-cols-[repeat(4,_auto)] gap-x-5 content-center items-center place-content-center h-24 md:flex-col md:h-full md:grid-rows-[repeat(4,_auto)] md:grid-cols-1 md:content-start md:p-10 md:gap-y-7 text-white text-sm uppercase" |             class="grid grid-cols-[repeat(4,_auto)] gap-x-5 content-center items-center place-content-center h-24 md:flex-col md:h-full md:grid-rows-[repeat(4,_auto)] md:grid-cols-1 md:content-start md:p-10 md:gap-y-7 text-white text-sm uppercase" | ||||||
|  | |||||||
| @ -19,6 +19,8 @@ object Models { | |||||||
|   final case class FormData( |   final case class FormData( | ||||||
|       userAnswers: Answers |       userAnswers: Answers | ||||||
|   ) { |   ) { | ||||||
|  |     val stepsAmount = Steps.values.toList.asJava | ||||||
|  | 
 | ||||||
|     // yeah, in real world it will not be this simple |     // yeah, in real world it will not be this simple | ||||||
|     def yearlyCost(monthlyCost: Int): Int = 10 * monthlyCost |     def yearlyCost(monthlyCost: Int): Int = 10 * monthlyCost | ||||||
| 
 | 
 | ||||||
| @ -94,6 +96,16 @@ object Models { | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   /** | ||||||
|  |    * TODO would be nice to connect answers to the steps enum | ||||||
|  |    * in some helpful way. | ||||||
|  |    */ | ||||||
|  |   enum Steps(val index: Int, val name: String): | ||||||
|  |     case Step1 extends Steps(1, "Your info") | ||||||
|  |     case Step2 extends Steps(2, "Select plan") | ||||||
|  |     case Step3 extends Steps(3, "Add-ons") | ||||||
|  |     case Step4 extends Steps(4, "Summary") | ||||||
|  | 
 | ||||||
|   enum PlanType(val monthlyCost: Int): |   enum PlanType(val monthlyCost: Int): | ||||||
|     case Arcade extends PlanType(9) |     case Arcade extends PlanType(9) | ||||||
|     case Advanced extends PlanType(12) |     case Advanced extends PlanType(12) | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user