From 5f1c344406b41373a52c16cbca3f8f4eedf9c08e Mon Sep 17 00:00:00 2001 From: Leon Serfaty G Date: Thu, 17 Jul 2025 10:51:28 +0000 Subject: [PATCH] I see this error with the app, reported by NextJS, please fix it. The er --- .../cost-estimator/cost-estimator-form.tsx | 18 ++- .../cost-estimator/step-10-shopping-cart.tsx | 123 ++++++++++++++++++ ...tep-10-results.tsx => step-11-results.tsx} | 10 +- .../cost-estimator/step-8-branding.tsx | 1 + .../step-9-additional-features.tsx | 3 +- 5 files changed, 148 insertions(+), 7 deletions(-) create mode 100644 src/components/cost-estimator/step-10-shopping-cart.tsx rename src/components/cost-estimator/{step-10-results.tsx => step-11-results.tsx} (92%) diff --git a/src/components/cost-estimator/cost-estimator-form.tsx b/src/components/cost-estimator/cost-estimator-form.tsx index b5bd3a6..cc1036e 100644 --- a/src/components/cost-estimator/cost-estimator-form.tsx +++ b/src/components/cost-estimator/cost-estimator-form.tsx @@ -1,3 +1,4 @@ + "use client"; import React, { useState, useTransition, useMemo } from 'react'; @@ -10,7 +11,8 @@ import { Step6Animations } from './step-6-animations'; import { Step7Illustrations } from './step-7-illustrations'; import { Step8Branding } from './step-8-branding'; import { Step9AdditionalFeatures } from './step-9-additional-features'; -import { Step10Results, calculateTotalHours } from './step-10-results'; +import { Step10ShoppingCart } from './step-10-shopping-cart'; +import { Step11Results, calculateTotalHours } from './step-11-results'; import { Card, CardContent } from '@/components/ui/card'; import { AnimatePresence, motion } from 'framer-motion'; @@ -33,6 +35,7 @@ export type FormData = { illustrations: IllustrationSelection; branding: BrandingSelection; additionalFeatures: string[]; + shoppingCart: boolean | null; }; export function CostEstimatorForm() { @@ -52,6 +55,7 @@ export function CostEstimatorForm() { }, branding: null, additionalFeatures: [], + shoppingCart: null, }); const [isPending, startTransition] = useTransition(); @@ -87,6 +91,7 @@ export function CostEstimatorForm() { }, branding: null, additionalFeatures: [], + shoppingCart: null, }); setCurrentStep(1); } @@ -177,7 +182,16 @@ export function CostEstimatorForm() { ); case 10: return ( - + ); + case 11: + return ( + void; + onBack: () => void; + onUpdateData: (data: Partial) => void; + formData: FormData; +}; + +const designHoursMap = { custom: 60, mockups: 30, existing: 0 }; +const illustrationHoursMap = { '2d_static': 10, '2d_animated': 25, '3d_static': 20, '3d_animated': 40 }; +const brandingHoursMap = { 'full-cycle': 70, 'brush-up': 30, 'logo-only': 20, 'none': 0 }; +const featuresHoursMap: Record = { + 'registration': 10, + 'member-profiles': 20, + 'admin-panel': 28, + 'crm-integration': 31, + 'dashboard': 40, + 'blog': 35, + 'event-scheduling': 35, + 'reservations': 35, + 'chat-live-chat': 50, + 'image-video-galleries': 5, + 'location-based': 40, + 'live-streaming': 55, +}; +const shoppingCartHours = 45; + +const calculateHours = ( + formData: FormData, + shoppingCart: boolean | null +): number => { + const pageVal = formData.pageCount === 10 ? 50 : (formData.pageCount + 1) * 5 - 1; + const pageHours = pageVal * 6; + const stageHours = Math.round((formData.projectStage / 100) * 50); + const designHours = formData.designProcess ? designHoursMap[formData.designProcess] : 0; + const animationHours = formData.animatedElements ? 30 : 0; + + let illustrationTotalHours = 0; + if (formData.illustrations.has2d) { + if (formData.illustrations.is2dAnimated === 'static') illustrationTotalHours += illustrationHoursMap['2d_static']; + if (formData.illustrations.is2dAnimated === 'animated') illustrationTotalHours += illustrationHoursMap['2d_animated']; + } + if (formData.illustrations.has3d) { + if (formData.illustrations.is3dAnimated === 'static') illustrationTotalHours += illustrationHoursMap['3d_static']; + if (formData.illustrations.is3dAnimated === 'animated') illustrationTotalHours += illustrationHoursMap['3d_animated']; + } + + const brandingH = formData.branding ? (brandingHoursMap[formData.branding] ?? 0) : 0; + + const additionalFeaturesHours = formData.additionalFeatures.reduce((total, feature) => { + return total + (featuresHoursMap[feature] || 0); + }, 0); + + const cartHours = shoppingCart ? shoppingCartHours : 0; + + return pageHours + stageHours + designHours + animationHours + illustrationTotalHours + brandingH + additionalFeaturesHours + cartHours; +}; + +export function Step10ShoppingCart({ onNext, onBack, onUpdateData, formData }: Step10Props) { + const [selectedOption, setSelectedOption] = useState(formData.shoppingCart); + + const handleSelect = (option: boolean) => { + setSelectedOption(option); + onUpdateData({ shoppingCart: option }); + }; + + const estimatedHours = useMemo(() => { + return calculateHours(formData, selectedOption); + }, [selectedOption, formData]); + + return ( +
+

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

+
+ + +
+
+
+ + {estimatedHours}+ hours +
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+ ); +} diff --git a/src/components/cost-estimator/step-10-results.tsx b/src/components/cost-estimator/step-11-results.tsx similarity index 92% rename from src/components/cost-estimator/step-10-results.tsx rename to src/components/cost-estimator/step-11-results.tsx index 404e764..15bfd67 100644 --- a/src/components/cost-estimator/step-10-results.tsx +++ b/src/components/cost-estimator/step-11-results.tsx @@ -1,4 +1,3 @@ - "use client"; import type { FormData } from './cost-estimator-form'; @@ -7,7 +6,7 @@ import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/com import { PartyPopper, RefreshCw } from 'lucide-react'; import React from 'react'; -type Step10Props = { +type Step11Props = { formData: FormData; onReset: () => void; estimatedHours: number; @@ -30,6 +29,7 @@ const featuresHoursMap: Record = { 'location-based': 40, 'live-streaming': 55, }; +const shoppingCartHours = 45; export const calculateTotalHours = (formData: FormData): number => { @@ -55,12 +55,14 @@ export const calculateTotalHours = (formData: FormData): number => { return total + (featuresHoursMap[feature] || 0); }, 0); - return pageHours + stageHours + designHours + animationHours + illustrationTotalHours + brandingH + additionalFeaturesHours; + const cartHours = formData.shoppingCart ? shoppingCartHours : 0; + + return pageHours + stageHours + designHours + animationHours + illustrationTotalHours + brandingH + additionalFeaturesHours + cartHours; }; const HOURLY_RATE = 75; // Example hourly rate in USD -export function Step10Results({ formData, onReset, estimatedHours }: Step10Props) { +export function Step11Results({ formData, onReset, estimatedHours }: Step11Props) { const estimatedCost = estimatedHours * HOURLY_RATE; diff --git a/src/components/cost-estimator/step-8-branding.tsx b/src/components/cost-estimator/step-8-branding.tsx index 99361ed..b156f3a 100644 --- a/src/components/cost-estimator/step-8-branding.tsx +++ b/src/components/cost-estimator/step-8-branding.tsx @@ -102,6 +102,7 @@ export function Step8Branding({ onNext, onBack, onUpdateData, formData }: Step8P
+