this is how the result page should look like
This commit is contained in:
+2
-3
@@ -23,13 +23,12 @@
|
|||||||
--border: 226 30% 85%;
|
--border: 226 30% 85%;
|
||||||
--input: 226 30% 85%;
|
--input: 226 30% 85%;
|
||||||
--ring: 221 100% 58%;
|
--ring: 221 100% 58%;
|
||||||
--radius: 0.5rem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.dark {
|
.dark {
|
||||||
--background: 222 47% 11%;
|
--background: 222 47% 11%;
|
||||||
--foreground: 0 0% 98%;
|
--foreground: 0 0% 98%;
|
||||||
--card: 222 47% 11%;
|
--card: 224 35% 15%;
|
||||||
--card-foreground: 0 0% 98%;
|
--card-foreground: 0 0% 98%;
|
||||||
--popover: 222 47% 11%;
|
--popover: 222 47% 11%;
|
||||||
--popover-foreground: 0 0% 98%;
|
--popover-foreground: 0 0% 98%;
|
||||||
@@ -43,7 +42,7 @@
|
|||||||
--accent-foreground: 0 0% 98%;
|
--accent-foreground: 0 0% 98%;
|
||||||
--destructive: 0 62.8% 30.6%;
|
--destructive: 0 62.8% 30.6%;
|
||||||
--destructive-foreground: 0 0% 98%;
|
--destructive-foreground: 0 0% 98%;
|
||||||
--border: 222 25% 20%;
|
--border: 224 35% 20%;
|
||||||
--input: 222 25% 20%;
|
--input: 222 25% 20%;
|
||||||
--ring: 221 100% 58%;
|
--ring: 221 100% 58%;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -13,7 +13,7 @@ export default function RootLayout({
|
|||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
}>) {
|
}>) {
|
||||||
return (
|
return (
|
||||||
<html lang="en">
|
<html lang="en" className="dark">
|
||||||
<head>
|
<head>
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossOrigin="anonymous" />
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossOrigin="anonymous" />
|
||||||
|
|||||||
@@ -107,8 +107,7 @@ export function CostEstimatorForm() {
|
|||||||
setCurrentStep(1);
|
setCurrentStep(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
const estimatedHours = useMemo(() => calculateTotalHours(formData), [formData]);
|
const { customHours, readyMadeHours } = useMemo(() => calculateTotalHours(formData), [formData]);
|
||||||
|
|
||||||
|
|
||||||
const renderStep = () => {
|
const renderStep = () => {
|
||||||
switch (currentStep) {
|
switch (currentStep) {
|
||||||
@@ -203,9 +202,9 @@ export function CostEstimatorForm() {
|
|||||||
case 11:
|
case 11:
|
||||||
return (
|
return (
|
||||||
<Step11Results
|
<Step11Results
|
||||||
formData={formData}
|
|
||||||
onReset={handleReset}
|
onReset={handleReset}
|
||||||
estimatedHours={estimatedHours}
|
customHours={customHours}
|
||||||
|
readyMadeHours={readyMadeHours}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
default:
|
default:
|
||||||
@@ -218,9 +217,11 @@ export function CostEstimatorForm() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const isResultsStep = currentStep === 11;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card className="mt-8 w-full max-w-4xl shadow-2xl overflow-hidden">
|
<Card className={`mt-8 w-full max-w-4xl shadow-2xl overflow-hidden ${isResultsStep ? 'bg-transparent border-none' : ''}`}>
|
||||||
<CardContent className="p-4 sm:p-8">
|
<CardContent className={`p-4 sm:p-8 ${isResultsStep ? 'p-0 sm:p-0' : ''}`}>
|
||||||
<AnimatePresence mode="wait">
|
<AnimatePresence mode="wait">
|
||||||
<motion.div
|
<motion.div
|
||||||
key={currentStep}
|
key={currentStep}
|
||||||
|
|||||||
@@ -3,14 +3,15 @@
|
|||||||
|
|
||||||
import type { FormData } from './cost-estimator-form';
|
import type { FormData } from './cost-estimator-form';
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/components/ui/card';
|
import { Card, CardContent } from '@/components/ui/card';
|
||||||
import { PartyPopper, RefreshCw } from 'lucide-react';
|
import { Info, Mail, RefreshCw } from 'lucide-react';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { Tooltip, TooltipProvider, TooltipTrigger, TooltipContent } from '@/components/ui/tooltip';
|
||||||
|
|
||||||
type Step11Props = {
|
type Step11Props = {
|
||||||
formData: FormData;
|
|
||||||
onReset: () => void;
|
onReset: () => void;
|
||||||
estimatedHours: number;
|
customHours: number;
|
||||||
|
readyMadeHours: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
const designHoursMap = { custom: 60, mockups: 30, existing: 0 };
|
const designHoursMap = { custom: 60, mockups: 30, existing: 0 };
|
||||||
@@ -36,7 +37,7 @@ const shoppingCartHoursMap = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
export const calculateTotalHours = (formData: FormData): number => {
|
export const calculateTotalHours = (formData: FormData) => {
|
||||||
const pageVal = formData.pageCount === 10 ? 50 : (formData.pageCount + 1) * 5 - 1;
|
const pageVal = formData.pageCount === 10 ? 50 : (formData.pageCount + 1) * 5 - 1;
|
||||||
const pageHours = pageVal * 6;
|
const pageHours = pageVal * 6;
|
||||||
const stageHours = Math.round((formData.projectStage / 100) * 50);
|
const stageHours = Math.round((formData.projectStage / 100) * 50);
|
||||||
@@ -67,38 +68,70 @@ export const calculateTotalHours = (formData: FormData): number => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return pageHours + stageHours + designHours + animationHours + illustrationTotalHours + brandingH + additionalFeaturesHours + cartHours;
|
const customHours = pageHours + stageHours + designHours + animationHours + illustrationTotalHours + brandingH + additionalFeaturesHours + cartHours;
|
||||||
|
const readyMadeHours = Math.round(customHours * 0.4);
|
||||||
|
|
||||||
|
return { customHours, readyMadeHours };
|
||||||
};
|
};
|
||||||
|
|
||||||
const HOURLY_RATE = 75; // Example hourly rate in USD
|
export function Step11Results({ onReset, customHours, readyMadeHours }: Step11Props) {
|
||||||
|
|
||||||
export function Step11Results({ formData, onReset, estimatedHours }: Step11Props) {
|
|
||||||
|
|
||||||
const estimatedCost = estimatedHours * HOURLY_RATE;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col items-center text-center">
|
<div className="flex flex-col items-center text-center">
|
||||||
<div className="rounded-full bg-primary/10 p-4 mb-4">
|
<h2 className="font-headline text-3xl font-bold tracking-tight text-foreground">A rough estimate of your project:</h2>
|
||||||
<PartyPopper className="h-12 w-12 text-primary" />
|
|
||||||
</div>
|
|
||||||
<h2 className="font-headline text-3xl font-bold tracking-tight">Your Estimate is Ready!</h2>
|
|
||||||
<p className="mt-2 text-muted-foreground">Based on your selections, here's our initial estimate.</p>
|
|
||||||
|
|
||||||
<Card className="mt-8 w-full max-w-md">
|
<div className="mt-8 grid w-full grid-cols-1 gap-6 md:grid-cols-2">
|
||||||
<CardHeader>
|
<Card className="bg-card text-card-foreground p-6">
|
||||||
<CardTitle className="text-muted-foreground tracking-normal font-medium">Estimated Cost</CardTitle>
|
<CardContent className="p-0">
|
||||||
<CardDescription>This is an approximation. Final cost may vary.</CardDescription>
|
<div className="flex justify-between items-start">
|
||||||
</CardHeader>
|
<p className="text-sm text-muted-foreground">Develop the project using ready-made tools</p>
|
||||||
<CardContent className="text-center">
|
<TooltipProvider>
|
||||||
<p className="text-5xl font-bold text-primary">${estimatedCost.toLocaleString()}</p>
|
<Tooltip>
|
||||||
<p className="text-lg text-muted-foreground mt-2">({estimatedHours}+ hours)</p>
|
<TooltipTrigger asChild>
|
||||||
|
<button type="button" className="text-muted-foreground hover:text-foreground">
|
||||||
|
<Info className="h-4 w-4" />
|
||||||
|
</button>
|
||||||
|
</TooltipTrigger>
|
||||||
|
<TooltipContent>
|
||||||
|
<p>Lower cost option using pre-built templates and components.</p>
|
||||||
|
</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
|
</div>
|
||||||
|
<p className="text-5xl font-bold text-foreground mt-4">{readyMadeHours}+ hours</p>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
|
<Card className="bg-card text-card-foreground p-6">
|
||||||
|
<CardContent className="p-0">
|
||||||
|
<div className="flex justify-between items-start">
|
||||||
|
<p className="text-sm text-muted-foreground">Custom development</p>
|
||||||
|
<TooltipProvider>
|
||||||
|
<Tooltip>
|
||||||
|
<TooltipTrigger asChild>
|
||||||
|
<button type="button" className="text-muted-foreground hover:text-foreground">
|
||||||
|
<Info className="h-4 w-4" />
|
||||||
|
</button>
|
||||||
|
</TooltipTrigger>
|
||||||
|
<TooltipContent>
|
||||||
|
<p>Higher cost option with fully custom design and features.</p>
|
||||||
|
</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
|
</div>
|
||||||
|
<p className="text-5xl font-bold text-foreground mt-4">{customHours}+ hours</p>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="mt-8">
|
<p className="mt-6 text-sm text-muted-foreground">If you need a detailed estimate for your project, we can send it to your email.</p>
|
||||||
<Button onClick={onReset} size="lg">
|
|
||||||
<RefreshCw className="mr-2 h-4 w-4" />
|
<div className="mt-8 flex items-center gap-4">
|
||||||
Start Over
|
<Button size="lg" variant="outline">
|
||||||
|
<Mail className="mr-2 h-4 w-4" />
|
||||||
|
Send Estimate on Email
|
||||||
|
</Button>
|
||||||
|
<Button onClick={onReset} size="lg" variant="link" className="text-muted-foreground">
|
||||||
|
Start over
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user