diff --git a/src/components/cost-estimator/cost-estimator-form.tsx b/src/components/cost-estimator/cost-estimator-form.tsx index cc1036e..e6c9dd6 100644 --- a/src/components/cost-estimator/cost-estimator-form.tsx +++ b/src/components/cost-estimator/cost-estimator-form.tsx @@ -25,6 +25,11 @@ export type IllustrationSelection = { export type BrandingSelection = 'full-cycle' | 'brush-up' | 'logo-only' | 'none' | null; +export type ShoppingCartSelection = { + hasCart: boolean | null; + multiplePurchases: boolean | null; +} + export type FormData = { projectType: 'website' | 'mobile-app' | 'platform' | null; serviceType: 'entire-project' | 'development' | 'ui-ux-design' | 'identity-branding' | null; @@ -35,7 +40,7 @@ export type FormData = { illustrations: IllustrationSelection; branding: BrandingSelection; additionalFeatures: string[]; - shoppingCart: boolean | null; + shoppingCart: ShoppingCartSelection; }; export function CostEstimatorForm() { @@ -55,7 +60,10 @@ export function CostEstimatorForm() { }, branding: null, additionalFeatures: [], - shoppingCart: null, + shoppingCart: { + hasCart: null, + multiplePurchases: null, + }, }); const [isPending, startTransition] = useTransition(); @@ -91,7 +99,10 @@ export function CostEstimatorForm() { }, branding: null, additionalFeatures: [], - shoppingCart: null, + shoppingCart: { + hasCart: null, + multiplePurchases: null + }, }); setCurrentStep(1); } diff --git a/src/components/cost-estimator/step-10-shopping-cart.tsx b/src/components/cost-estimator/step-10-shopping-cart.tsx index 401efee..656edfb 100644 --- a/src/components/cost-estimator/step-10-shopping-cart.tsx +++ b/src/components/cost-estimator/step-10-shopping-cart.tsx @@ -1,10 +1,11 @@ "use client"; -import type { FormData } from './cost-estimator-form'; +import type { FormData, ShoppingCartSelection } from './cost-estimator-form'; import { Button } from '@/components/ui/button'; import { Gauge } from 'lucide-react'; import React, { useState, useMemo } from 'react'; +import { AnimatePresence, motion } from 'framer-motion'; type Step10Props = { onNext: () => void; @@ -30,11 +31,14 @@ const featuresHoursMap: Record = { 'location-based': 40, 'live-streaming': 55, }; -const shoppingCartHours = 45; +const shoppingCartHoursMap = { + simple: 45, + multiple: 20 +}; const calculateHours = ( formData: FormData, - shoppingCart: boolean | null + shoppingCart: ShoppingCartSelection | null ): number => { const pageVal = formData.pageCount === 10 ? 50 : (formData.pageCount + 1) * 5 - 1; const pageHours = pageVal * 6; @@ -58,43 +62,91 @@ const calculateHours = ( return total + (featuresHoursMap[feature] || 0); }, 0); - const cartHours = shoppingCart ? shoppingCartHours : 0; + let cartHours = 0; + if (shoppingCart?.hasCart) { + cartHours += shoppingCartHoursMap.simple; + if (shoppingCart.multiplePurchases) { + cartHours += shoppingCartHoursMap.multiple; + } + } return pageHours + stageHours + designHours + animationHours + illustrationTotalHours + brandingH + additionalFeaturesHours + cartHours; }; export function Step10ShoppingCart({ onNext, onBack, onUpdateData, formData }: Step10Props) { - const [selectedOption, setSelectedOption] = useState(formData.shoppingCart); + const [selections, setSelections] = useState(formData.shoppingCart); - const handleSelect = (option: boolean) => { - setSelectedOption(option); - onUpdateData({ shoppingCart: option }); + const handleSelect = (field: keyof ShoppingCartSelection, value: boolean) => { + const newSelections = { ...selections, [field]: value }; + if (field === 'hasCart' && value === false) { + newSelections.multiplePurchases = null; + } + setSelections(newSelections); + onUpdateData({ shoppingCart: newSelections }); }; const estimatedHours = useMemo(() => { - return calculateHours(formData, selectedOption); - }, [selectedOption, formData]); + return calculateHours(formData, selections); + }, [selections, formData]); + + const isNextDisabled = selections.hasCart === null || (selections.hasCart === true && selections.multiplePurchases === null); return ( -
-

Do you need a shopping cart for buying multiple products with one check-out?

-
- - +
+
+

Do you need a shopping cart for buying multiple products with one check-out?

+
+ + +
-
+ + + {selections.hasCart && ( + +
+

How about a shopping cart to make multiple purchases at once?

+
+ + +
+
+
+ )} +
+ +
{estimatedHours}+ hours @@ -113,7 +165,7 @@ export function Step10ShoppingCart({ onNext, onBack, onUpdateData, formData }: S
-
diff --git a/src/components/cost-estimator/step-11-results.tsx b/src/components/cost-estimator/step-11-results.tsx index 15bfd67..03a63e1 100644 --- a/src/components/cost-estimator/step-11-results.tsx +++ b/src/components/cost-estimator/step-11-results.tsx @@ -1,3 +1,4 @@ + "use client"; import type { FormData } from './cost-estimator-form'; @@ -29,7 +30,10 @@ const featuresHoursMap: Record = { 'location-based': 40, 'live-streaming': 55, }; -const shoppingCartHours = 45; +const shoppingCartHoursMap = { + simple: 45, + multiple: 20 +}; export const calculateTotalHours = (formData: FormData): number => { @@ -55,7 +59,13 @@ export const calculateTotalHours = (formData: FormData): number => { return total + (featuresHoursMap[feature] || 0); }, 0); - const cartHours = formData.shoppingCart ? shoppingCartHours : 0; + let cartHours = 0; + if (formData.shoppingCart?.hasCart) { + cartHours += shoppingCartHoursMap.simple; + if (formData.shoppingCart.multiplePurchases) { + cartHours += shoppingCartHoursMap.multiple; + } + } return pageHours + stageHours + designHours + animationHours + illustrationTotalHours + brandingH + additionalFeaturesHours + cartHours; };