Compare commits
72 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a47ad5e45c | |||
| 38c2395af7 | |||
| f9992c9ede | |||
| 948c03de1b | |||
| 4894289474 | |||
| 80866a3e03 | |||
| efebcf43b8 | |||
| f36cf02edf | |||
| d91004e743 | |||
| 9cbf340415 | |||
| 80d0b0f892 | |||
| 48fb3e1732 | |||
| ad754dd709 | |||
| 2299dfe84f | |||
| 747dcf9b5c | |||
| b32eeb18ab | |||
| 38bc1b4db2 | |||
| 200cb2241b | |||
| a3e87a1aab | |||
| 435d5101c6 | |||
| 78fe25a4e3 | |||
| 074367ddcb | |||
| 84ae956b02 | |||
| 528a390803 | |||
| 4caad74ce5 | |||
| 020ab825e4 | |||
| 88fbdba7a5 | |||
| 56455037d8 | |||
| c7a8f2b3d2 | |||
| f399d78a2d | |||
| eacaaeabae | |||
| e686d786d5 | |||
| 5db6ec02af | |||
| f9dd40028c | |||
| f09ba6a84f | |||
| 5a2e6242db | |||
| f41affbb81 | |||
| 24d2de83ce | |||
| 62461a3437 | |||
| b5d972637d | |||
| 94632a6f95 | |||
| 4395fbdebe | |||
| 1298943ab5 | |||
| 5b901e3a5f | |||
| df3b14698d | |||
| 6e2e76fb75 | |||
| 167e59949c | |||
| ef78a75fc9 | |||
| 1fa246aaad | |||
| 85842b6c48 | |||
| 1ef0e5ad68 | |||
| 7166574432 | |||
| 8842bdfd51 | |||
| 4043fe8ce1 | |||
| f3067600b1 | |||
| b13f3004b1 | |||
| 84e04a021c | |||
| f767aca7b4 | |||
| c4a1befe4f | |||
| 7654764260 | |||
| b075ceee3b | |||
| 4c499007fc | |||
| 1827497685 | |||
| c1ff6f5357 | |||
| fe9aeb820c | |||
| 00d663f166 | |||
| 48f271b34f | |||
| a9a3dc03a8 | |||
| 761ae2ea9c | |||
| 49b424c3f1 | |||
| fb3978a89d | |||
| 56fe4bdf01 |
@@ -1,72 +0,0 @@
|
||||
/** @type {import('next').NextConfig} */
|
||||
const nextConfig = {
|
||||
images: {
|
||||
remotePatterns: [
|
||||
{
|
||||
protocol: 'https',
|
||||
hostname: 'webuild-dev.s3.eu-north-1.amazonaws.com',
|
||||
pathname: '/**',
|
||||
},
|
||||
{
|
||||
protocol: 'https',
|
||||
hostname: '*.cloudinary.com',
|
||||
pathname: '/**',
|
||||
},
|
||||
{
|
||||
protocol: 'https',
|
||||
hostname: 'images.unsplash.com',
|
||||
pathname: '/**',
|
||||
},
|
||||
],
|
||||
unoptimized: false,
|
||||
formats: ['image/avif', 'image/webp'],
|
||||
deviceSizes: [320, 420, 640, 768, 1024, 1280, 1536],
|
||||
imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
|
||||
},
|
||||
compress: true,
|
||||
swcMinify: true,
|
||||
reactStrictMode: true,
|
||||
poweredByHeader: false,
|
||||
productionBrowserSourceMaps: false,
|
||||
experimental: {
|
||||
optimizePackageImports: [
|
||||
'@radix-ui/react-dialog',
|
||||
'@radix-ui/react-dropdown-menu',
|
||||
'@radix-ui/react-slider',
|
||||
'lucide-react',
|
||||
],
|
||||
},
|
||||
headers: async () => [
|
||||
{
|
||||
source: '/:path*',
|
||||
headers: [
|
||||
{
|
||||
key: 'X-DNS-Prefetch-Control',
|
||||
value: 'on',
|
||||
},
|
||||
{
|
||||
key: 'X-Frame-Options',
|
||||
value: 'SAMEORIGIN',
|
||||
},
|
||||
{
|
||||
key: 'X-Content-Type-Options',
|
||||
value: 'nosniff',
|
||||
},
|
||||
{
|
||||
key: 'X-XSS-Protection',
|
||||
value: '1; mode=block',
|
||||
},
|
||||
{
|
||||
key: 'Referrer-Policy',
|
||||
value: 'strict-origin-when-cross-origin',
|
||||
},
|
||||
{
|
||||
key: 'Permissions-Policy',
|
||||
value: 'geolocation=(), microphone=(), camera=()',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
module.exports = nextConfig;
|
||||
@@ -1,40 +0,0 @@
|
||||
"use client";
|
||||
|
||||
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
|
||||
import MediaAbout from "@/components/sections/about/MediaAbout";
|
||||
|
||||
const AboutPage = () => {
|
||||
return (
|
||||
<ThemeProvider
|
||||
defaultButtonVariant="hover-magnetic"
|
||||
defaultTextAnimation="entrance-slide"
|
||||
borderRadius="rounded"
|
||||
contentWidth="medium"
|
||||
sizing="medium"
|
||||
background="circleGradient"
|
||||
cardStyle="glass-elevated"
|
||||
primaryButtonStyle="gradient"
|
||||
secondaryButtonStyle="glass"
|
||||
headingFontWeight="normal"
|
||||
>
|
||||
<div id="nav" data-section="nav" />
|
||||
<div id="about-hero" data-section="about-hero">
|
||||
<MediaAbout
|
||||
title="Elevate Your Experience"
|
||||
description="Discover a new way to connect, create, and inspire with our innovative solutions."
|
||||
tag="About Us"
|
||||
imageSrc="/about-hero.jpg"
|
||||
imageAlt="Our team in action"
|
||||
buttons={[{ text: "Shop Now", href: "/shop" }]}
|
||||
useInvertedBackground={false}
|
||||
/>
|
||||
</div>
|
||||
<div id="features" data-section="features" />
|
||||
<div id="testimonials" data-section="testimonials" />
|
||||
<div id="contact" data-section="contact" />
|
||||
<div id="footer" data-section="footer" />
|
||||
</ThemeProvider>
|
||||
);
|
||||
};
|
||||
|
||||
export default AboutPage;
|
||||
@@ -1,179 +0,0 @@
|
||||
"use client";
|
||||
|
||||
import { useParams } from "next/navigation";
|
||||
import { MapPin, Award, Users, TrendingUp } from "lucide-react";
|
||||
|
||||
interface BrandModel {
|
||||
id: string;
|
||||
name: string;
|
||||
year: string;
|
||||
price: string;
|
||||
image: string;
|
||||
}
|
||||
|
||||
interface BrandInfo {
|
||||
name: string;
|
||||
founded: string;
|
||||
headquarters: string;
|
||||
description: string;
|
||||
history: string;
|
||||
stats: {
|
||||
yearsInBusiness: string;
|
||||
vehiclesSold: string;
|
||||
countries: string;
|
||||
awards: string;
|
||||
};
|
||||
models: BrandModel[];
|
||||
}
|
||||
|
||||
const mockBrandData: { [key: string]: BrandInfo } = {
|
||||
tesla: {
|
||||
name: "Tesla", founded: "2003", headquarters: "Palo Alto, California", description: "Leading electric vehicle manufacturer revolutionizing sustainable transportation.", history:
|
||||
"Tesla was founded in 2003 by Martin Eberhard and Marc Tarpenning. Named after inventor Nikola Tesla, the company was established to prove that electric vehicles can be both high-performance and desirable. In 2004, Elon Musk joined as chairman and led Series A funding. Tesla has since become the world's most valuable automaker, pioneering the mass production of electric vehicles and accelerating the global transition to sustainable energy.", stats: {
|
||||
yearsInBusiness: "21+", vehiclesSold: "3.5M+", countries: "100+", awards: "150+"},
|
||||
models: [
|
||||
{ id: "1", name: "Model S", year: "2024", price: "$89,990", image: "https://images.unsplash.com/photo-1560958089-b8a63dd8b50b?w=600" },
|
||||
{ id: "2", name: "Model 3", year: "2024", price: "$43,990", image: "https://images.unsplash.com/photo-1516814050195-3a03d82e059d?w=600" },
|
||||
{ id: "3", name: "Model X", year: "2024", price: "$104,990", image: "https://images.unsplash.com/photo-1552820728-8ac41f1ce891?w=600" },
|
||||
{ id: "4", name: "Model Y", year: "2024", price: "$52,990", image: "https://images.unsplash.com/photo-1560958089-fcbb3cce6c55?w=600" },
|
||||
],
|
||||
},
|
||||
bmw: {
|
||||
name: "BMW", founded: "1916", headquarters: "Munich, Germany", description: "Premium German automaker known for innovative design and performance.", history:
|
||||
"BMW (Bayerische Motoren Werke AG) was founded in 1916 as an aircraft engine manufacturer. The company transitioned to automobile production in 1929, establishing itself as a leader in luxury vehicles. BMW is renowned for its engineering excellence, innovative technology, and the iconic 'Ultimate Driving Machine' philosophy. Today, BMW stands as one of the world's leading premium automakers with a global presence.", stats: {
|
||||
yearsInBusiness: "108+", vehiclesSold: "2.5M+", countries: "140+", awards: "200+"},
|
||||
models: [
|
||||
{ id: "1", name: "M440i xDrive", year: "2024", price: "$67,500", image: "https://images.unsplash.com/photo-1469854523086-cc02fe5d8800?w=600" },
|
||||
{ id: "2", name: "X5 M", year: "2024", price: "$115,900", image: "https://images.unsplash.com/photo-1558618666-fcd25c85cd64?w=600" },
|
||||
{ id: "3", name: "i7", year: "2024", price: "$99,650", image: "https://images.unsplash.com/photo-1533473359331-35b3c3f0f038?w=600" },
|
||||
{ id: "4", name: "Z4 M440i", year: "2024", price: "$79,500", image: "https://images.unsplash.com/photo-1552820728-8ac41f1ce891?w=600" },
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
export default function BrandPage() {
|
||||
const params = useParams();
|
||||
const brandKey = (params.brand as string)?.toLowerCase() || "";
|
||||
const brand = mockBrandData[brandKey];
|
||||
|
||||
if (!brand) {
|
||||
return (
|
||||
<div className="min-h-screen flex items-center justify-center">
|
||||
<div className="text-center">
|
||||
<h1 className="text-4xl font-bold mb-4">Brand Not Found</h1>
|
||||
<p className="text-gray-600 mb-8">The brand you're looking for doesn't exist.</p>
|
||||
<a href="/" className="px-6 py-3 bg-accent text-white rounded-lg">Back to Home</a>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-background">
|
||||
{/* Brand Header */}
|
||||
<div className="bg-gradient-to-br from-card to-background py-16 px-4">
|
||||
<div className="max-w-6xl mx-auto">
|
||||
<a href="/" className="text-accent hover:underline mb-6 inline-block">← Back</a>
|
||||
<h1 className="text-5xl font-bold mb-4">{brand.name}</h1>
|
||||
<p className="text-xl text-gray-600 mb-8">{brand.description}</p>
|
||||
<div className="flex flex-wrap gap-6 text-sm">
|
||||
<div className="flex items-center gap-2">
|
||||
<Award size={20} className="text-accent" />
|
||||
<span>Founded {brand.founded}</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<MapPin size={20} className="text-accent" />
|
||||
<span>{brand.headquarters}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Main Content */}
|
||||
<div className="max-w-6xl mx-auto px-4 py-16">
|
||||
{/* Brand History */}
|
||||
<section className="mb-20">
|
||||
<h2 className="text-4xl font-bold mb-8">Our Story</h2>
|
||||
<div className="grid md:grid-cols-3 gap-8 mb-12">
|
||||
<div className="md:col-span-2">
|
||||
<p className="text-lg text-gray-700 leading-relaxed mb-6">{brand.history}</p>
|
||||
</div>
|
||||
<div className="bg-card p-8 rounded-lg h-fit">
|
||||
<h3 className="text-2xl font-bold mb-6">By the Numbers</h3>
|
||||
<div className="space-y-6">
|
||||
<div>
|
||||
<div className="flex items-center gap-2 mb-2">
|
||||
<TrendingUp size={20} className="text-accent" />
|
||||
<span className="text-sm text-gray-600">Years in Business</span>
|
||||
</div>
|
||||
<p className="text-3xl font-bold">{brand.stats.yearsInBusiness}</p>
|
||||
</div>
|
||||
<div>
|
||||
<div className="flex items-center gap-2 mb-2">
|
||||
<Users size={20} className="text-accent" />
|
||||
<span className="text-sm text-gray-600">Vehicles Sold</span>
|
||||
</div>
|
||||
<p className="text-3xl font-bold">{brand.stats.vehiclesSold}</p>
|
||||
</div>
|
||||
<div>
|
||||
<div className="flex items-center gap-2 mb-2">
|
||||
<MapPin size={20} className="text-accent" />
|
||||
<span className="text-sm text-gray-600">Countries Served</span>
|
||||
</div>
|
||||
<p className="text-3xl font-bold">{brand.stats.countries}</p>
|
||||
</div>
|
||||
<div>
|
||||
<div className="flex items-center gap-2 mb-2">
|
||||
<Award size={20} className="text-accent" />
|
||||
<span className="text-sm text-gray-600">Awards Won</span>
|
||||
</div>
|
||||
<p className="text-3xl font-bold">{brand.stats.awards}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* All Models */}
|
||||
<section>
|
||||
<h2 className="text-4xl font-bold mb-12">All {brand.name} Models</h2>
|
||||
<div className="grid md:grid-cols-2 lg:grid-cols-4 gap-6">
|
||||
{brand.models.map((model) => (
|
||||
<div key={model.id} className="bg-card rounded-lg overflow-hidden hover:shadow-lg transition group cursor-pointer">
|
||||
<div className="aspect-video bg-gray-200 overflow-hidden mb-4">
|
||||
<img
|
||||
src={model.image}
|
||||
alt={model.name}
|
||||
className="w-full h-full object-cover group-hover:scale-105 transition"
|
||||
/>
|
||||
</div>
|
||||
<div className="p-6">
|
||||
<p className="text-sm text-accent mb-1">{model.year}</p>
|
||||
<h3 className="text-xl font-bold mb-2">{model.name}</h3>
|
||||
<p className="text-lg font-semibold text-accent mb-4">{model.price}</p>
|
||||
<a
|
||||
href={`/cars/${model.id}`}
|
||||
className="block text-accent hover:underline font-semibold"
|
||||
>
|
||||
View Details →
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* CTA Section */}
|
||||
<section className="mt-20 bg-card p-12 rounded-lg text-center">
|
||||
<h3 className="text-3xl font-bold mb-4">Ready to Explore?</h3>
|
||||
<p className="text-gray-600 mb-8 max-w-2xl mx-auto">
|
||||
Discover the perfect {brand.name} vehicle for your lifestyle. Our expert team is ready to help you find the right model.
|
||||
</p>
|
||||
<button className="px-8 py-4 bg-accent text-white font-semibold rounded-lg hover:bg-accent/90 transition">
|
||||
Schedule a Test Drive
|
||||
</button>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,11 +1,18 @@
|
||||
"use client";
|
||||
|
||||
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
|
||||
import NavbarLayoutFloatingOverlay from '@/components/navbar/NavbarLayoutFloatingOverlay/NavbarLayoutFloatingOverlay';
|
||||
|
||||
const BrandsPage = () => {
|
||||
const testCarImages = [
|
||||
'https://images.unsplash.com/photo-1552519507-da3a142c6e3d?w=800&q=80',
|
||||
'https://images.unsplash.com/photo-1494976866105-d32a481b81b4?w=800&q=80',
|
||||
'https://images.unsplash.com/photo-1527524330007-3ea4e06ed667?w=800&q=80',
|
||||
];
|
||||
|
||||
export default function BrandsPage() {
|
||||
return (
|
||||
<ThemeProvider
|
||||
defaultButtonVariant="hover-magnetic"
|
||||
defaultButtonVariant="text-stagger"
|
||||
defaultTextAnimation="entrance-slide"
|
||||
borderRadius="rounded"
|
||||
contentWidth="medium"
|
||||
@@ -16,10 +23,24 @@ const BrandsPage = () => {
|
||||
secondaryButtonStyle="glass"
|
||||
headingFontWeight="normal"
|
||||
>
|
||||
<div id="nav" data-section="nav" />
|
||||
<div id="brands" data-section="brands" />
|
||||
<div id="nav" data-section="nav">
|
||||
<NavbarLayoutFloatingOverlay
|
||||
navItems={[
|
||||
{ name: "Home", id: "/" },
|
||||
{ name: "Browse", id: "browse" },
|
||||
{ name: "Compare", id: "compare" },
|
||||
]}
|
||||
brandName="Webild"
|
||||
button={{ text: "Search", href: "search" }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="min-h-screen flex items-center justify-center p-4">
|
||||
<div className="text-center">
|
||||
<h1 className="text-4xl font-bold mb-4">Car Brands</h1>
|
||||
<p className="text-lg text-gray-600">Browse all car brands in our database</p>
|
||||
</div>
|
||||
</div>
|
||||
</ThemeProvider>
|
||||
);
|
||||
};
|
||||
|
||||
export default BrandsPage;
|
||||
}
|
||||
|
||||
@@ -1,11 +1,18 @@
|
||||
"use client";
|
||||
|
||||
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
|
||||
import NavbarLayoutFloatingOverlay from '@/components/navbar/NavbarLayoutFloatingOverlay/NavbarLayoutFloatingOverlay';
|
||||
|
||||
const BrowsePage = () => {
|
||||
const testCarImages = [
|
||||
'https://images.unsplash.com/photo-1552519507-da3a142c6e3d?w=800&q=80',
|
||||
'https://images.unsplash.com/photo-1494976866105-d32a481b81b4?w=800&q=80',
|
||||
'https://images.unsplash.com/photo-1527524330007-3ea4e06ed667?w=800&q=80',
|
||||
];
|
||||
|
||||
export default function BrowsePage() {
|
||||
return (
|
||||
<ThemeProvider
|
||||
defaultButtonVariant="hover-magnetic"
|
||||
defaultButtonVariant="text-stagger"
|
||||
defaultTextAnimation="entrance-slide"
|
||||
borderRadius="rounded"
|
||||
contentWidth="medium"
|
||||
@@ -16,10 +23,24 @@ const BrowsePage = () => {
|
||||
secondaryButtonStyle="glass"
|
||||
headingFontWeight="normal"
|
||||
>
|
||||
<div id="nav" data-section="nav" />
|
||||
<div id="browse" data-section="browse" />
|
||||
<div id="nav" data-section="nav">
|
||||
<NavbarLayoutFloatingOverlay
|
||||
navItems={[
|
||||
{ name: "Home", id: "/" },
|
||||
{ name: "Browse", id: "browse" },
|
||||
{ name: "Compare", id: "compare" },
|
||||
]}
|
||||
brandName="Webild"
|
||||
button={{ text: "Search", href: "search" }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="min-h-screen flex items-center justify-center p-4">
|
||||
<div className="text-center">
|
||||
<h1 className="text-4xl font-bold mb-4">Browse Cars</h1>
|
||||
<p className="text-lg text-gray-600">Explore our complete vehicle catalog</p>
|
||||
</div>
|
||||
</div>
|
||||
</ThemeProvider>
|
||||
);
|
||||
};
|
||||
|
||||
export default BrowsePage;
|
||||
}
|
||||
|
||||
@@ -1,270 +1,382 @@
|
||||
"use client";
|
||||
'use client';
|
||||
|
||||
import { useParams } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
import { ChevronLeft, ChevronRight, Heart, Share2, MapPin, Fuel, Gauge, Calendar } from "lucide-react";
|
||||
import { useState, useEffect } from 'react';
|
||||
import Link from 'next/link';
|
||||
import { useParams } from 'next/navigation';
|
||||
|
||||
interface CarDetail {
|
||||
interface Car {
|
||||
id: string;
|
||||
name: string;
|
||||
price: string;
|
||||
rating: number;
|
||||
description: string;
|
||||
images: Array<{ src: string; alt: string }>;
|
||||
specs: {
|
||||
year: string;
|
||||
mileage: string;
|
||||
transmission: string;
|
||||
fuelType: string;
|
||||
engine: string;
|
||||
color: string;
|
||||
};
|
||||
features: string[];
|
||||
variants?: Array<{
|
||||
label: string;
|
||||
options: string[];
|
||||
selected: string;
|
||||
}>;
|
||||
make: string;
|
||||
model: string;
|
||||
year: number;
|
||||
price: number;
|
||||
image: string;
|
||||
transmission: string;
|
||||
fuel: string;
|
||||
mileage: number;
|
||||
bodyType?: string;
|
||||
color?: string;
|
||||
vin?: string;
|
||||
engineSize?: number;
|
||||
horsepower?: number;
|
||||
torque?: number;
|
||||
topSpeed?: number;
|
||||
acceleration?: number;
|
||||
mpg?: number;
|
||||
seating?: number;
|
||||
luggage?: number;
|
||||
wheelbase?: number;
|
||||
length?: number;
|
||||
width?: number;
|
||||
height?: number;
|
||||
weight?: number;
|
||||
fuelCapacity?: number;
|
||||
safetyRating?: number;
|
||||
features?: string[];
|
||||
}
|
||||
|
||||
const mockCarData: { [key: string]: CarDetail } = {
|
||||
"1": {
|
||||
id: "1", name: "2024 Tesla Model S", price: "$89,990", rating: 5,
|
||||
description: "Experience the future of electric vehicles with cutting-edge technology and exceptional performance.", images: [
|
||||
{ src: "https://images.unsplash.com/photo-1560958089-b8a63dd8b50b?w=800", alt: "Tesla Model S Front" },
|
||||
{ src: "https://images.unsplash.com/photo-1516814050195-3a03d82e059d?w=800", alt: "Tesla Model S Side" },
|
||||
{ src: "https://images.unsplash.com/photo-1552820728-8ac41f1ce891?w=800", alt: "Tesla Model S Interior" },
|
||||
],
|
||||
specs: {
|
||||
year: "2024", mileage: "5,200 miles", transmission: "Automatic", fuelType: "Electric", engine: "Dual Motor", color: "Solid Black"},
|
||||
const carsDatabase: Record<string, Car> = {
|
||||
'1': {
|
||||
id: '1',
|
||||
make: 'Toyota',
|
||||
model: 'Camry',
|
||||
year: 2024,
|
||||
price: 32000,
|
||||
image: '/car-camry.jpg',
|
||||
transmission: 'Automatic',
|
||||
fuel: 'Hybrid',
|
||||
mileage: 0,
|
||||
bodyType: 'Sedan',
|
||||
color: 'Pearl White',
|
||||
vin: 'T123456789ABC',
|
||||
engineSize: 2.5,
|
||||
horsepower: 208,
|
||||
torque: 180,
|
||||
topSpeed: 112,
|
||||
acceleration: 8.2,
|
||||
mpg: 52,
|
||||
seating: 5,
|
||||
luggage: 15.1,
|
||||
wheelbase: 112.2,
|
||||
length: 191.1,
|
||||
width: 71.7,
|
||||
height: 57.5,
|
||||
weight: 3415,
|
||||
fuelCapacity: 14.5,
|
||||
safetyRating: 5,
|
||||
features: [
|
||||
"Autopilot Advanced", "Premium Audio System", "Panoramic Sunroof", "19-inch Wheel Set", "Premium Interior", "Over-the-Air Updates", "Supercharger Access", "Enhanced Autopilot"],
|
||||
'Hybrid Engine',
|
||||
'Toyota Safety Sense',
|
||||
'Adaptive Cruise Control',
|
||||
'Lane Departure Alert',
|
||||
'Bluetooth Connectivity',
|
||||
'Touchscreen Display',
|
||||
'Heated Seats',
|
||||
'Power Windows',
|
||||
],
|
||||
},
|
||||
"2": {
|
||||
id: "2", name: "2024 BMW M440i xDrive", price: "$67,500", rating: 5,
|
||||
description: "German engineering meets performance with the new M440i xDrive.", images: [
|
||||
{ src: "https://images.unsplash.com/photo-1469854523086-cc02fe5d8800?w=800", alt: "BMW M440i Front" },
|
||||
{ src: "https://images.unsplash.com/photo-1558618666-fcd25c85cd64?w=800", alt: "BMW M440i Side" },
|
||||
{ src: "https://images.unsplash.com/photo-1533473359331-35b3c3f0f038?w=800", alt: "BMW M440i Interior" },
|
||||
],
|
||||
specs: {
|
||||
year: "2024", mileage: "8,100 miles", transmission: "Automatic", fuelType: "Gasoline", engine: "3.0L Twin-Turbo", color: "Alpine White"},
|
||||
'2': {
|
||||
id: '2',
|
||||
make: 'Honda',
|
||||
model: 'Civic',
|
||||
year: 2024,
|
||||
price: 28000,
|
||||
image: '/car-civic.jpg',
|
||||
transmission: 'Manual',
|
||||
fuel: 'Gasoline',
|
||||
mileage: 0,
|
||||
bodyType: 'Sedan',
|
||||
color: 'Sonic Gray',
|
||||
vin: 'H987654321DEF',
|
||||
engineSize: 2.0,
|
||||
horsepower: 158,
|
||||
torque: 138,
|
||||
topSpeed: 125,
|
||||
acceleration: 8.5,
|
||||
mpg: 32,
|
||||
seating: 5,
|
||||
luggage: 12.3,
|
||||
wheelbase: 106.3,
|
||||
length: 182.2,
|
||||
width: 70.8,
|
||||
height: 56.0,
|
||||
weight: 3040,
|
||||
fuelCapacity: 12.3,
|
||||
safetyRating: 5,
|
||||
features: [
|
||||
"M Sport Brake Package", "Premium Sound System", "Adaptive M Suspension", "20-inch M Light Alloy Wheels", "Harman Kardon Audio", "Gesture Control", "Head-Up Display", "Premium Leather Interior"],
|
||||
'Honda Sensing',
|
||||
'Collision Mitigation Braking',
|
||||
'Road Departure Mitigation',
|
||||
'Apple CarPlay',
|
||||
'Android Auto',
|
||||
'Rearview Camera',
|
||||
'Sunroof',
|
||||
'Alloy Wheels',
|
||||
],
|
||||
},
|
||||
'3': {
|
||||
id: '3',
|
||||
make: 'BMW',
|
||||
model: '3 Series',
|
||||
year: 2024,
|
||||
price: 45000,
|
||||
image: '/car-bmw.jpg',
|
||||
transmission: 'Automatic',
|
||||
fuel: 'Diesel',
|
||||
mileage: 0,
|
||||
bodyType: 'Sedan',
|
||||
color: 'Jet Black',
|
||||
vin: 'B456789012GHI',
|
||||
engineSize: 2.0,
|
||||
horsepower: 190,
|
||||
torque: 295,
|
||||
topSpeed: 130,
|
||||
acceleration: 7.2,
|
||||
mpg: 45,
|
||||
seating: 5,
|
||||
luggage: 13.6,
|
||||
wheelbase: 112.8,
|
||||
length: 184.4,
|
||||
width: 71.7,
|
||||
height: 56.3,
|
||||
weight: 3550,
|
||||
fuelCapacity: 13.2,
|
||||
safetyRating: 5,
|
||||
features: [
|
||||
'BMW iDrive',
|
||||
'Adaptive Headlights',
|
||||
'Premium Sound System',
|
||||
'Panoramic Sunroof',
|
||||
'Power Seats',
|
||||
'Climate Control',
|
||||
'Gesture Control',
|
||||
'Head-Up Display',
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
export default function CarDetailPage() {
|
||||
const params = useParams();
|
||||
const carId = params.id as string;
|
||||
const car = mockCarData[carId];
|
||||
const [currentImageIndex, setCurrentImageIndex] = useState(0);
|
||||
const [isFavorited, setIsFavorited] = useState(false);
|
||||
const [car, setCar] = useState<Car | null>(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
const id = params.id as string;
|
||||
const carData = carsDatabase[id];
|
||||
if (carData) {
|
||||
setCar(carData);
|
||||
}
|
||||
setLoading(false);
|
||||
}, [params.id]);
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<div className="min-h-screen bg-gradient-to-br from-slate-50 to-slate-100 flex items-center justify-center">
|
||||
<div className="text-2xl text-gray-600">Loading...</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (!car) {
|
||||
return (
|
||||
<div className="min-h-screen flex items-center justify-center">
|
||||
<div className="text-center">
|
||||
<h1 className="text-4xl font-bold mb-4">Car Not Found</h1>
|
||||
<p className="text-gray-600 mb-8">The car you're looking for doesn't exist.</p>
|
||||
<a href="/" className="px-6 py-3 bg-accent text-white rounded-lg">Back to Home</a>
|
||||
<div className="min-h-screen bg-gradient-to-br from-slate-50 to-slate-100 p-8">
|
||||
<div className="max-w-7xl mx-auto text-center py-12">
|
||||
<h1 className="text-4xl font-bold text-gray-900 mb-4">Car Not Found</h1>
|
||||
<p className="text-xl text-gray-600 mb-8">The car you're looking for doesn't exist.</p>
|
||||
<Link href="/">
|
||||
<button className="bg-blue-600 text-white font-semibold py-2 px-6 rounded-lg hover:bg-blue-700 transition-colors duration-200">
|
||||
Back to Cars
|
||||
</button>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const nextImage = () => {
|
||||
setCurrentImageIndex((prev) => (prev + 1) % car.images.length);
|
||||
};
|
||||
|
||||
const prevImage = () => {
|
||||
setCurrentImageIndex((prev) => (prev - 1 + car.images.length) % car.images.length);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-background">
|
||||
<div className="max-w-6xl mx-auto px-4 py-8">
|
||||
<div className="min-h-screen bg-gradient-to-br from-slate-50 to-slate-100 p-8">
|
||||
<div className="max-w-7xl mx-auto">
|
||||
{/* Header */}
|
||||
<div className="mb-8">
|
||||
<a href="/" className="text-accent hover:underline mb-4 inline-block">← Back</a>
|
||||
<h1 className="text-4xl font-bold mb-2">{car.name}</h1>
|
||||
<p className="text-xl text-accent font-semibold">{car.price}</p>
|
||||
<Link href="/">
|
||||
<button className="text-blue-600 hover:text-blue-700 font-semibold mb-4">
|
||||
← Back to Cars
|
||||
</button>
|
||||
</Link>
|
||||
<h1 className="text-5xl font-bold text-gray-900">
|
||||
{car.year} {car.make} {car.model}
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
{/* Image Gallery */}
|
||||
<div className="mb-12">
|
||||
<div className="relative bg-card rounded-lg overflow-hidden mb-6">
|
||||
<div className="aspect-video flex items-center justify-center bg-gray-100 relative">
|
||||
<img
|
||||
src={car.images[currentImageIndex].src}
|
||||
alt={car.images[currentImageIndex].alt}
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
<button
|
||||
onClick={() => setIsFavorited(!isFavorited)}
|
||||
className="absolute top-4 right-4 p-3 bg-white rounded-full shadow-lg hover:bg-gray-100 transition"
|
||||
aria-label="Add to favorites"
|
||||
>
|
||||
<Heart
|
||||
size={24}
|
||||
className={isFavorited ? "fill-red-500 text-red-500" : "text-gray-600"}
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Navigation Buttons */}
|
||||
{car.images.length > 1 && (
|
||||
<>
|
||||
<button
|
||||
onClick={prevImage}
|
||||
className="absolute left-4 top-1/2 -translate-y-1/2 bg-white/80 hover:bg-white p-2 rounded-full transition"
|
||||
aria-label="Previous image"
|
||||
>
|
||||
<ChevronLeft size={24} />
|
||||
</button>
|
||||
<button
|
||||
onClick={nextImage}
|
||||
className="absolute right-4 top-1/2 -translate-y-1/2 bg-white/80 hover:bg-white p-2 rounded-full transition"
|
||||
aria-label="Next image"
|
||||
>
|
||||
<ChevronRight size={24} />
|
||||
</button>
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* Image Counter */}
|
||||
<div className="absolute bottom-4 right-4 bg-black/60 text-white px-3 py-1 rounded-full text-sm">
|
||||
{currentImageIndex + 1} / {car.images.length}
|
||||
{/* Main Content */}
|
||||
<div className="grid grid-cols-1 lg:grid-cols-3 gap-8 mb-8">
|
||||
{/* Image and Price Section */}
|
||||
<div className="lg:col-span-1">
|
||||
<div className="bg-white rounded-lg shadow-lg overflow-hidden sticky top-8">
|
||||
<div className="h-64 bg-gray-200 flex items-center justify-center">
|
||||
<div className="text-gray-500 text-center">
|
||||
<div className="text-sm">Car Image</div>
|
||||
<div className="text-xs text-gray-400">Main View</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="p-6">
|
||||
<div className="mb-6">
|
||||
<p className="text-3xl font-bold text-gray-900 mb-2">
|
||||
${car.price.toLocaleString()}
|
||||
</p>
|
||||
<p className="text-sm text-gray-600 mb-4">Starting Price</p>
|
||||
<button className="w-full bg-blue-600 text-white font-semibold py-3 px-4 rounded-lg hover:bg-blue-700 transition-colors duration-200 mb-2">
|
||||
Get Quote
|
||||
</button>
|
||||
<button className="w-full bg-gray-200 text-gray-900 font-semibold py-3 px-4 rounded-lg hover:bg-gray-300 transition-colors duration-200">
|
||||
Schedule Test Drive
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Thumbnail Gallery */}
|
||||
{car.images.length > 1 && (
|
||||
<div className="flex gap-3 overflow-x-auto pb-2">
|
||||
{car.images.map((image, index) => (
|
||||
<button
|
||||
key={index}
|
||||
onClick={() => setCurrentImageIndex(index)}
|
||||
className={`flex-shrink-0 w-24 h-24 rounded-lg overflow-hidden border-2 transition ${
|
||||
index === currentImageIndex ? "border-accent" : "border-gray-200"
|
||||
}`}
|
||||
>
|
||||
<img src={image.src} alt={image.alt} className="w-full h-full object-cover" />
|
||||
</button>
|
||||
{/* Details Section */}
|
||||
<div className="lg:col-span-2 space-y-8">
|
||||
{/* Quick Facts */}
|
||||
<div className="bg-white rounded-lg shadow-lg p-8">
|
||||
<h2 className="text-2xl font-bold text-gray-900 mb-6">Quick Facts</h2>
|
||||
<div className="grid grid-cols-2 md:grid-cols-3 gap-6">
|
||||
<div>
|
||||
<p className="text-sm text-gray-600 mb-1">Body Type</p>
|
||||
<p className="text-lg font-semibold text-gray-900">{car.bodyType || 'N/A'}</p>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-sm text-gray-600 mb-1">Transmission</p>
|
||||
<p className="text-lg font-semibold text-gray-900">{car.transmission}</p>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-sm text-gray-600 mb-1">Fuel Type</p>
|
||||
<p className="text-lg font-semibold text-gray-900">{car.fuel}</p>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-sm text-gray-600 mb-1">Seating</p>
|
||||
<p className="text-lg font-semibold text-gray-900">{car.seating || 'N/A'} Seats</p>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-sm text-gray-600 mb-1">Color</p>
|
||||
<p className="text-lg font-semibold text-gray-900">{car.color || 'N/A'}</p>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-sm text-gray-600 mb-1">Safety Rating</p>
|
||||
<p className="text-lg font-semibold text-gray-900">
|
||||
{car.safetyRating ? `${car.safetyRating}/5 ⭐` : 'N/A'}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Engine Specifications */}
|
||||
<div className="bg-white rounded-lg shadow-lg p-8">
|
||||
<h2 className="text-2xl font-bold text-gray-900 mb-6">Engine Specifications</h2>
|
||||
<div className="grid grid-cols-2 md:grid-cols-3 gap-6">
|
||||
<div>
|
||||
<p className="text-sm text-gray-600 mb-1">Engine Size</p>
|
||||
<p className="text-lg font-semibold text-gray-900">{car.engineSize || 'N/A'} L</p>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-sm text-gray-600 mb-1">Horsepower</p>
|
||||
<p className="text-lg font-semibold text-gray-900">{car.horsepower || 'N/A'} hp</p>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-sm text-gray-600 mb-1">Torque</p>
|
||||
<p className="text-lg font-semibold text-gray-900">{car.torque || 'N/A'} lb-ft</p>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-sm text-gray-600 mb-1">Top Speed</p>
|
||||
<p className="text-lg font-semibold text-gray-900">{car.topSpeed || 'N/A'} mph</p>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-sm text-gray-600 mb-1">0-60 Acceleration</p>
|
||||
<p className="text-lg font-semibold text-gray-900">{car.acceleration || 'N/A'} sec</p>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-sm text-gray-600 mb-1">Fuel Efficiency</p>
|
||||
<p className="text-lg font-semibold text-gray-900">{car.mpg || 'N/A'} MPG</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Dimensions and Capacity */}
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-8 mb-8">
|
||||
<div className="bg-white rounded-lg shadow-lg p-8">
|
||||
<h2 className="text-2xl font-bold text-gray-900 mb-6">Dimensions</h2>
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<div>
|
||||
<p className="text-sm text-gray-600 mb-1">Length</p>
|
||||
<p className="text-lg font-semibold text-gray-900">{car.length || 'N/A'} in</p>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-sm text-gray-600 mb-1">Width</p>
|
||||
<p className="text-lg font-semibold text-gray-900">{car.width || 'N/A'} in</p>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-sm text-gray-600 mb-1">Height</p>
|
||||
<p className="text-lg font-semibold text-gray-900">{car.height || 'N/A'} in</p>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-sm text-gray-600 mb-1">Wheelbase</p>
|
||||
<p className="text-lg font-semibold text-gray-900">{car.wheelbase || 'N/A'} in</p>
|
||||
</div>
|
||||
<div className="col-span-2">
|
||||
<p className="text-sm text-gray-600 mb-1">Weight</p>
|
||||
<p className="text-lg font-semibold text-gray-900">{car.weight || 'N/A'} lbs</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="bg-white rounded-lg shadow-lg p-8">
|
||||
<h2 className="text-2xl font-bold text-gray-900 mb-6">Capacity</h2>
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<div>
|
||||
<p className="text-sm text-gray-600 mb-1">Luggage Space</p>
|
||||
<p className="text-lg font-semibold text-gray-900">{car.luggage || 'N/A'} cu ft</p>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-sm text-gray-600 mb-1">Fuel Tank</p>
|
||||
<p className="text-lg font-semibold text-gray-900">{car.fuelCapacity || 'N/A'} gal</p>
|
||||
</div>
|
||||
<div className="col-span-2">
|
||||
<p className="text-sm text-gray-600 mb-1">VIN</p>
|
||||
<p className="text-lg font-semibold text-gray-900 break-all">{car.vin || 'N/A'}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Features */}
|
||||
{car.features && car.features.length > 0 && (
|
||||
<div className="bg-white rounded-lg shadow-lg p-8 mb-8">
|
||||
<h2 className="text-2xl font-bold text-gray-900 mb-6">Features & Amenities</h2>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||
{car.features.map((feature, index) => (
|
||||
<div key={index} className="flex items-center p-3 bg-blue-50 rounded-lg">
|
||||
<span className="text-blue-600 mr-3">✓</span>
|
||||
<p className="text-gray-900 font-medium">{feature}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="grid md:grid-cols-2 gap-12">
|
||||
{/* Left Column - Specs & Features */}
|
||||
<div>
|
||||
{/* Description */}
|
||||
<div className="mb-8">
|
||||
<h2 className="text-2xl font-bold mb-4">Overview</h2>
|
||||
<p className="text-gray-600 mb-6">{car.description}</p>
|
||||
</div>
|
||||
|
||||
{/* Key Specifications */}
|
||||
<div className="mb-8">
|
||||
<h2 className="text-2xl font-bold mb-6">Key Specifications</h2>
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<div className="bg-card p-4 rounded-lg">
|
||||
<div className="flex items-center gap-2 mb-2">
|
||||
<Calendar size={20} className="text-accent" />
|
||||
<span className="text-sm text-gray-600">Year</span>
|
||||
</div>
|
||||
<p className="font-semibold">{car.specs.year}</p>
|
||||
</div>
|
||||
<div className="bg-card p-4 rounded-lg">
|
||||
<div className="flex items-center gap-2 mb-2">
|
||||
<Gauge size={20} className="text-accent" />
|
||||
<span className="text-sm text-gray-600">Mileage</span>
|
||||
</div>
|
||||
<p className="font-semibold">{car.specs.mileage}</p>
|
||||
</div>
|
||||
<div className="bg-card p-4 rounded-lg">
|
||||
<div className="flex items-center gap-2 mb-2">
|
||||
<Fuel size={20} className="text-accent" />
|
||||
<span className="text-sm text-gray-600">Fuel Type</span>
|
||||
</div>
|
||||
<p className="font-semibold">{car.specs.fuelType}</p>
|
||||
</div>
|
||||
<div className="bg-card p-4 rounded-lg">
|
||||
<div className="flex items-center gap-2 mb-2">
|
||||
<MapPin size={20} className="text-accent" />
|
||||
<span className="text-sm text-gray-600">Transmission</span>
|
||||
</div>
|
||||
<p className="font-semibold">{car.specs.transmission}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Additional Specs */}
|
||||
<div className="bg-card p-6 rounded-lg mb-8">
|
||||
<h3 className="text-lg font-bold mb-4">Additional Details</h3>
|
||||
<div className="space-y-3">
|
||||
<div className="flex justify-between">
|
||||
<span className="text-gray-600">Engine:</span>
|
||||
<span className="font-semibold">{car.specs.engine}</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<span className="text-gray-600">Color:</span>
|
||||
<span className="font-semibold">{car.specs.color}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Right Column - Features & CTA */}
|
||||
<div>
|
||||
{/* Features */}
|
||||
<div className="mb-8">
|
||||
<h2 className="text-2xl font-bold mb-6">Features & Amenities</h2>
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
{car.features.map((feature, index) => (
|
||||
<div key={index} className="flex items-center gap-2 p-3 bg-card rounded-lg">
|
||||
<div className="w-5 h-5 rounded-full bg-accent flex items-center justify-center flex-shrink-0">
|
||||
<span className="text-white text-sm">✓</span>
|
||||
</div>
|
||||
<span className="text-sm">{feature}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Call to Action */}
|
||||
<div className="sticky bottom-0 md:static bg-background space-y-4 p-4 md:p-0 -mx-4 md:mx-0 md:bg-transparent">
|
||||
<button className="w-full bg-accent text-white font-semibold py-4 rounded-lg hover:bg-accent/90 transition">
|
||||
Request Information
|
||||
</button>
|
||||
<button className="w-full border-2 border-accent text-accent font-semibold py-4 rounded-lg hover:bg-accent/5 transition flex items-center justify-center gap-2">
|
||||
<Share2 size={20} />
|
||||
Share Vehicle
|
||||
</button>
|
||||
<button className="w-full bg-card text-foreground font-semibold py-4 rounded-lg hover:bg-gray-100 transition">
|
||||
View Similar Vehicles
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Related Section */}
|
||||
<div className="mt-16 pt-16 border-t">
|
||||
<h2 className="text-3xl font-bold mb-8">Compare Similar Vehicles</h2>
|
||||
<div className="grid md:grid-cols-3 gap-6">
|
||||
{[1, 2, 3].map((i) => (
|
||||
<div key={i} className="bg-card rounded-lg overflow-hidden hover:shadow-lg transition">
|
||||
<div className="aspect-video bg-gray-200"></div>
|
||||
<div className="p-4">
|
||||
<h3 className="font-bold text-lg mb-2">Similar Model {i}</h3>
|
||||
<p className="text-accent font-semibold">$XX,XXX</p>
|
||||
<a href="#" className="mt-4 block text-accent hover:underline font-semibold">
|
||||
View Details →
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
{/* CTA Section */}
|
||||
<div className="bg-gradient-to-r from-blue-600 to-blue-800 rounded-lg shadow-lg p-8 text-white text-center mb-8">
|
||||
<h3 className="text-2xl font-bold mb-2">Interested in this vehicle?</h3>
|
||||
<p className="text-blue-100 mb-6">Contact our sales team to schedule a test drive or request more information.</p>
|
||||
<div className="flex flex-col md:flex-row gap-4 justify-center">
|
||||
<button className="bg-white text-blue-600 font-semibold py-3 px-8 rounded-lg hover:bg-blue-50 transition-colors duration-200">
|
||||
Contact Sales
|
||||
</button>
|
||||
<button className="bg-blue-700 text-white font-semibold py-3 px-8 rounded-lg hover:bg-blue-900 transition-colors duration-200 border border-blue-400">
|
||||
View Similar Models
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
46
src/app/cars/page.tsx
Normal file
46
src/app/cars/page.tsx
Normal file
@@ -0,0 +1,46 @@
|
||||
"use client";
|
||||
|
||||
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
|
||||
import NavbarLayoutFloatingOverlay from '@/components/navbar/NavbarLayoutFloatingOverlay/NavbarLayoutFloatingOverlay';
|
||||
|
||||
const testCarImages = [
|
||||
'https://images.unsplash.com/photo-1552519507-da3a142c6e3d?w=800&q=80',
|
||||
'https://images.unsplash.com/photo-1494976866105-d32a481b81b4?w=800&q=80',
|
||||
'https://images.unsplash.com/photo-1527524330007-3ea4e06ed667?w=800&q=80',
|
||||
];
|
||||
|
||||
export default function CarsPage() {
|
||||
return (
|
||||
<ThemeProvider
|
||||
defaultButtonVariant="text-stagger"
|
||||
defaultTextAnimation="entrance-slide"
|
||||
borderRadius="rounded"
|
||||
contentWidth="medium"
|
||||
sizing="medium"
|
||||
background="circleGradient"
|
||||
cardStyle="glass-elevated"
|
||||
primaryButtonStyle="gradient"
|
||||
secondaryButtonStyle="glass"
|
||||
headingFontWeight="normal"
|
||||
>
|
||||
<div id="nav" data-section="nav">
|
||||
<NavbarLayoutFloatingOverlay
|
||||
navItems={[
|
||||
{ name: "Home", id: "/" },
|
||||
{ name: "Browse", id: "browse" },
|
||||
{ name: "Compare", id: "compare" },
|
||||
]}
|
||||
brandName="Webild"
|
||||
button={{ text: "Search", href: "search" }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="min-h-screen flex items-center justify-center p-4">
|
||||
<div className="text-center">
|
||||
<h1 className="text-4xl font-bold mb-4">Cars</h1>
|
||||
<p className="text-lg text-gray-600">Detailed car information and specifications</p>
|
||||
</div>
|
||||
</div>
|
||||
</ThemeProvider>
|
||||
);
|
||||
}
|
||||
@@ -1,11 +1,19 @@
|
||||
"use client";
|
||||
|
||||
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
|
||||
import NavbarLayoutFloatingOverlay from '@/components/navbar/NavbarLayoutFloatingOverlay/NavbarLayoutFloatingOverlay';
|
||||
import { Scale } from 'lucide-react';
|
||||
|
||||
const ComparePage = () => {
|
||||
const testCarImages = [
|
||||
'https://images.unsplash.com/photo-1552519507-da3a142c6e3d?w=800&q=80',
|
||||
'https://images.unsplash.com/photo-1494976866105-d32a481b81b4?w=800&q=80',
|
||||
'https://images.unsplash.com/photo-1527524330007-3ea4e06ed667?w=800&q=80',
|
||||
];
|
||||
|
||||
export default function ComparePage() {
|
||||
return (
|
||||
<ThemeProvider
|
||||
defaultButtonVariant="hover-magnetic"
|
||||
defaultButtonVariant="text-stagger"
|
||||
defaultTextAnimation="entrance-slide"
|
||||
borderRadius="rounded"
|
||||
contentWidth="medium"
|
||||
@@ -16,10 +24,27 @@ const ComparePage = () => {
|
||||
secondaryButtonStyle="glass"
|
||||
headingFontWeight="normal"
|
||||
>
|
||||
<div id="nav" data-section="nav" />
|
||||
<div id="compare" data-section="compare" />
|
||||
<div id="nav" data-section="nav">
|
||||
<NavbarLayoutFloatingOverlay
|
||||
navItems={[
|
||||
{ name: "Home", id: "/" },
|
||||
{ name: "Browse", id: "browse" },
|
||||
{ name: "Compare", id: "compare" },
|
||||
]}
|
||||
brandName="Webild"
|
||||
button={{ text: "Search", href: "search" }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="min-h-screen flex items-center justify-center p-4">
|
||||
<div className="text-center">
|
||||
<h1 className="text-4xl font-bold mb-4 flex items-center justify-center gap-2">
|
||||
<Scale className="w-8 h-8" />
|
||||
Compare Cars
|
||||
</h1>
|
||||
<p className="text-lg text-gray-600">Side-by-side vehicle comparison tool</p>
|
||||
</div>
|
||||
</div>
|
||||
</ThemeProvider>
|
||||
);
|
||||
};
|
||||
|
||||
export default ComparePage;
|
||||
}
|
||||
|
||||
46
src/app/database/page.tsx
Normal file
46
src/app/database/page.tsx
Normal file
@@ -0,0 +1,46 @@
|
||||
"use client";
|
||||
|
||||
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
|
||||
import NavbarLayoutFloatingOverlay from '@/components/navbar/NavbarLayoutFloatingOverlay/NavbarLayoutFloatingOverlay';
|
||||
|
||||
const testCarImages = [
|
||||
'https://images.unsplash.com/photo-1552519507-da3a142c6e3d?w=800&q=80',
|
||||
'https://images.unsplash.com/photo-1494976866105-d32a481b81b4?w=800&q=80',
|
||||
'https://images.unsplash.com/photo-1527524330007-3ea4e06ed667?w=800&q=80',
|
||||
];
|
||||
|
||||
export default function DatabasePage() {
|
||||
return (
|
||||
<ThemeProvider
|
||||
defaultButtonVariant="text-stagger"
|
||||
defaultTextAnimation="entrance-slide"
|
||||
borderRadius="rounded"
|
||||
contentWidth="medium"
|
||||
sizing="medium"
|
||||
background="circleGradient"
|
||||
cardStyle="glass-elevated"
|
||||
primaryButtonStyle="gradient"
|
||||
secondaryButtonStyle="glass"
|
||||
headingFontWeight="normal"
|
||||
>
|
||||
<div id="nav" data-section="nav">
|
||||
<NavbarLayoutFloatingOverlay
|
||||
navItems={[
|
||||
{ name: "Home", id: "/" },
|
||||
{ name: "Browse", id: "browse" },
|
||||
{ name: "Compare", id: "compare" },
|
||||
]}
|
||||
brandName="Webild"
|
||||
button={{ text: "Search", href: "search" }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="min-h-screen flex items-center justify-center p-4">
|
||||
<div className="text-center">
|
||||
<h1 className="text-4xl font-bold mb-4">Car Database</h1>
|
||||
<p className="text-lg text-gray-600">Complete vehicle database with advanced search</p>
|
||||
</div>
|
||||
</div>
|
||||
</ThemeProvider>
|
||||
);
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
"use client";
|
||||
|
||||
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
|
||||
|
||||
const DetailsPage = () => {
|
||||
return (
|
||||
<ThemeProvider
|
||||
defaultButtonVariant="hover-magnetic"
|
||||
defaultTextAnimation="entrance-slide"
|
||||
borderRadius="rounded"
|
||||
contentWidth="medium"
|
||||
sizing="medium"
|
||||
background="circleGradient"
|
||||
cardStyle="glass-elevated"
|
||||
primaryButtonStyle="gradient"
|
||||
secondaryButtonStyle="glass"
|
||||
headingFontWeight="normal"
|
||||
>
|
||||
<div id="nav" data-section="nav" />
|
||||
<div id="details" data-section="details" />
|
||||
</ThemeProvider>
|
||||
);
|
||||
};
|
||||
|
||||
export default DetailsPage;
|
||||
@@ -1,8 +1,8 @@
|
||||
import type { Metadata } from "next";
|
||||
import "./styles/globals.css";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Create Next App", description: "Generated by create next app"
|
||||
};
|
||||
title: "Webild - Car Database & Comparison Platform", description: "Comprehensive car database with detailed specifications, pricing, and comparison tools."};
|
||||
|
||||
export default function RootLayout({
|
||||
children,
|
||||
@@ -10,10 +10,8 @@ export default function RootLayout({
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<html lang="en" suppressHydrationWarning>
|
||||
<body>
|
||||
{children}
|
||||
|
||||
<html lang="en">
|
||||
<body>{children}
|
||||
<script
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: `
|
||||
|
||||
133
src/app/page.tsx
133
src/app/page.tsx
@@ -1,10 +1,135 @@
|
||||
"use client";
|
||||
|
||||
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
|
||||
import HeroSplitTestimonial from '@/components/sections/hero/HeroSplitTestimonial';
|
||||
import FeatureCardEight from '@/components/sections/feature/FeatureCardEight';
|
||||
import TestimonialCardSixteen from '@/components/sections/testimonial/TestimonialCardSixteen';
|
||||
import NavbarLayoutFloatingOverlay from '@/components/navbar/NavbarLayoutFloatingOverlay/NavbarLayoutFloatingOverlay';
|
||||
import { Heart } from 'lucide-react';
|
||||
|
||||
const testCarImages = [
|
||||
'https://images.unsplash.com/photo-1552519507-da3a142c6e3d?w=800&q=80',
|
||||
'https://images.unsplash.com/photo-1494976866105-d32a481b81b4?w=800&q=80',
|
||||
'https://images.unsplash.com/photo-1527524330007-3ea4e06ed667?w=800&q=80',
|
||||
];
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<div>
|
||||
<h1>Welcome to Car Dealership</h1>
|
||||
<p>Browse our collection of vehicles</p>
|
||||
</div>
|
||||
<ThemeProvider
|
||||
defaultButtonVariant="text-stagger"
|
||||
defaultTextAnimation="entrance-slide"
|
||||
borderRadius="rounded"
|
||||
contentWidth="medium"
|
||||
sizing="medium"
|
||||
background="none"
|
||||
cardStyle="glass-elevated"
|
||||
primaryButtonStyle="gradient"
|
||||
secondaryButtonStyle="glass"
|
||||
headingFontWeight="normal"
|
||||
>
|
||||
<div id="nav" data-section="nav">
|
||||
<NavbarLayoutFloatingOverlay
|
||||
navItems={[
|
||||
{ name: "Home", id: "/" },
|
||||
{ name: "Browse", id: "browse" },
|
||||
{ name: "Compare", id: "compare" },
|
||||
]}
|
||||
brandName="Webild"
|
||||
button={{ text: "Search", href: "search" }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="hero" data-section="hero">
|
||||
<HeroSplitTestimonial
|
||||
title="Find Your Perfect Car"
|
||||
description="Explore our comprehensive database of vehicles with detailed specifications, pricing, and real owner testimonials."
|
||||
background={{ variant: "plain" }}
|
||||
testimonials={[
|
||||
{
|
||||
name: "Alex Johnson", handle: "@alexj", testimonial: "The database is incredibly comprehensive. Found exactly what I was looking for!", rating: 5,
|
||||
imageSrc: testCarImages[0],
|
||||
},
|
||||
{
|
||||
name: "Sarah Chen", handle: "@sarahchen", testimonial: "Best car comparison tool I've used. Made my purchase decision so much easier.", rating: 5,
|
||||
imageSrc: testCarImages[1],
|
||||
},
|
||||
{
|
||||
name: "Mike Rodriguez", handle: "@mikerod", testimonial: "The specifications are detailed and accurate. Highly recommended for car shoppers.", rating: 5,
|
||||
imageSrc: testCarImages[2],
|
||||
},
|
||||
]}
|
||||
avatars={[
|
||||
{ src: testCarImages[0], alt: "User 1" },
|
||||
{ src: testCarImages[1], alt: "User 2" },
|
||||
{ src: testCarImages[2], alt: "User 3" },
|
||||
]}
|
||||
avatarText="Trusted by 10,000+ car shoppers"
|
||||
buttons={[
|
||||
{ text: "Browse Cars", href: "browse" },
|
||||
{ text: "Compare Now", href: "compare" },
|
||||
]}
|
||||
mediaAnimation="slide-up"
|
||||
imageSrc={testCarImages[0]}
|
||||
imageAlt="Premium sedan showcase"
|
||||
imagePosition="right"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="features" data-section="features">
|
||||
<FeatureCardEight
|
||||
title="Why Choose Webild?"
|
||||
description="Comprehensive tools for car shopping and comparison"
|
||||
textboxLayout="default"
|
||||
useInvertedBackground={false}
|
||||
features={[
|
||||
{
|
||||
id: 1,
|
||||
title: "Detailed Specifications", description: "Complete technical specs for every vehicle in our database", imageSrc: testCarImages[0],
|
||||
imageAlt: "Specifications icon"},
|
||||
{
|
||||
id: 2,
|
||||
title: "Price Tracking", description: "Monitor price changes and find the best deals", imageSrc: testCarImages[1],
|
||||
imageAlt: "Price tracking icon"},
|
||||
{
|
||||
id: 3,
|
||||
title: "Side-by-Side Comparison", description: "Compare multiple vehicles with detailed analytics", imageSrc: testCarImages[2],
|
||||
imageAlt: "Comparison icon"},
|
||||
]}
|
||||
buttons={[
|
||||
{ text: "Explore More", href: "database" },
|
||||
]}
|
||||
buttonAnimation="slide-up"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="testimonials" data-section="testimonials">
|
||||
<TestimonialCardSixteen
|
||||
title="Customer Reviews"
|
||||
description="Real testimonials from car shoppers who found their perfect vehicle"
|
||||
textboxLayout="default"
|
||||
useInvertedBackground={false}
|
||||
animationType="slide-up"
|
||||
testimonials={[
|
||||
{
|
||||
id: "1", name: "Jessica Martinez", role: "First-time Buyer", company: "Tech Startup", rating: 5,
|
||||
imageSrc: testCarImages[0],
|
||||
imageAlt: "Jessica Martinez"},
|
||||
{
|
||||
id: "2", name: "David Wong", role: "Car Enthusiast", company: "Automotive Blog", rating: 5,
|
||||
imageSrc: testCarImages[1],
|
||||
imageAlt: "David Wong"},
|
||||
{
|
||||
id: "3", name: "Emma Thompson", role: "Fleet Manager", company: "Logistics Corp", rating: 5,
|
||||
imageSrc: testCarImages[2],
|
||||
imageAlt: "Emma Thompson"},
|
||||
]}
|
||||
kpiItems={[
|
||||
{ value: "10K+", label: "Active Users" },
|
||||
{ value: "50K+", label: "Vehicles Listed" },
|
||||
{ value: "100K+", label: "Comparisons Made" },
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
</ThemeProvider>
|
||||
);
|
||||
}
|
||||
|
||||
56
src/app/privacy/page.tsx
Normal file
56
src/app/privacy/page.tsx
Normal file
@@ -0,0 +1,56 @@
|
||||
"use client";
|
||||
|
||||
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
|
||||
import NavbarLayoutFloatingOverlay from '@/components/navbar/NavbarLayoutFloatingOverlay/NavbarLayoutFloatingOverlay';
|
||||
|
||||
const testCarImages = [
|
||||
'https://images.unsplash.com/photo-1552519507-da3a142c6e3d?w=800&q=80',
|
||||
'https://images.unsplash.com/photo-1494976866105-d32a481b81b4?w=800&q=80',
|
||||
'https://images.unsplash.com/photo-1527524330007-3ea4e06ed667?w=800&q=80',
|
||||
];
|
||||
|
||||
export default function PrivacyPage() {
|
||||
return (
|
||||
<ThemeProvider
|
||||
defaultButtonVariant="text-stagger"
|
||||
defaultTextAnimation="entrance-slide"
|
||||
borderRadius="rounded"
|
||||
contentWidth="medium"
|
||||
sizing="medium"
|
||||
background="circleGradient"
|
||||
cardStyle="glass-elevated"
|
||||
primaryButtonStyle="gradient"
|
||||
secondaryButtonStyle="glass"
|
||||
headingFontWeight="normal"
|
||||
>
|
||||
<div id="nav" data-section="nav">
|
||||
<NavbarLayoutFloatingOverlay
|
||||
navItems={[
|
||||
{ name: "Home", id: "/" },
|
||||
{ name: "Browse", id: "browse" },
|
||||
{ name: "Compare", id: "compare" },
|
||||
]}
|
||||
brandName="Webild"
|
||||
button={{ text: "Search", href: "search" }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="min-h-screen p-4">
|
||||
<div className="max-w-2xl mx-auto pt-24">
|
||||
<h1 className="text-4xl font-bold mb-4">Privacy Policy</h1>
|
||||
<p className="text-gray-600 mb-8">Last updated: January 2025</p>
|
||||
<div className="space-y-6">
|
||||
<section>
|
||||
<h2 className="text-2xl font-semibold mb-3">1. Information We Collect</h2>
|
||||
<p className="text-gray-700">We collect information you provide directly to us when using our car database and comparison tools.</p>
|
||||
</section>
|
||||
<section>
|
||||
<h2 className="text-2xl font-semibold mb-3">2. How We Use Your Information</h2>
|
||||
<p className="text-gray-700">We use the information we collect to provide, maintain, and improve our services.</p>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ThemeProvider>
|
||||
);
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
import { MetadataRoute } from "next";
|
||||
|
||||
export default function robots(): MetadataRoute.Robots {
|
||||
const baseUrl = "https://autoarchive.example.com";
|
||||
|
||||
return {
|
||||
rules: [
|
||||
{
|
||||
userAgent: "*", allow: "/", disallow: ["/admin", "/private", "/*.json$", "/*?*sort=", "/*?*order="],
|
||||
},
|
||||
{
|
||||
userAgent: "Googlebot", allow: "/", crawlDelay: 0.5,
|
||||
},
|
||||
],
|
||||
sitemap: `${baseUrl}/sitemap.xml`,
|
||||
host: baseUrl,
|
||||
};
|
||||
}
|
||||
@@ -1,11 +1,21 @@
|
||||
"use client";
|
||||
|
||||
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
|
||||
import NavbarLayoutFloatingOverlay from '@/components/navbar/NavbarLayoutFloatingOverlay/NavbarLayoutFloatingOverlay';
|
||||
import { useState } from 'react';
|
||||
|
||||
const testCarImages = [
|
||||
'https://images.unsplash.com/photo-1552519507-da3a142c6e3d?w=800&q=80',
|
||||
'https://images.unsplash.com/photo-1494976866105-d32a481b81b4?w=800&q=80',
|
||||
'https://images.unsplash.com/photo-1527524330007-3ea4e06ed667?w=800&q=80',
|
||||
];
|
||||
|
||||
export default function SearchPage() {
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
|
||||
const SearchPage = () => {
|
||||
return (
|
||||
<ThemeProvider
|
||||
defaultButtonVariant="hover-magnetic"
|
||||
defaultButtonVariant="text-stagger"
|
||||
defaultTextAnimation="entrance-slide"
|
||||
borderRadius="rounded"
|
||||
contentWidth="medium"
|
||||
@@ -16,10 +26,35 @@ const SearchPage = () => {
|
||||
secondaryButtonStyle="glass"
|
||||
headingFontWeight="normal"
|
||||
>
|
||||
<div id="nav" data-section="nav" />
|
||||
<div id="search" data-section="search" />
|
||||
<div id="nav" data-section="nav">
|
||||
<NavbarLayoutFloatingOverlay
|
||||
navItems={[
|
||||
{ name: "Home", id: "/" },
|
||||
{ name: "Browse", id: "browse" },
|
||||
{ name: "Compare", id: "compare" },
|
||||
]}
|
||||
brandName="Webild"
|
||||
button={{ text: "Search", href: "search" }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="min-h-screen flex items-center justify-center p-4">
|
||||
<div className="w-full max-w-2xl">
|
||||
<h1 className="text-4xl font-bold mb-8 text-center">Search Cars</h1>
|
||||
<div className="flex gap-4">
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Search by make, model, or year..."
|
||||
value={searchQuery}
|
||||
onChange={(e) => setSearchQuery(e.target.value)}
|
||||
className="flex-1 px-4 py-2 rounded border border-gray-300 focus:outline-none focus:border-blue-500"
|
||||
/>
|
||||
<button className="px-6 py-2 bg-blue-600 text-white rounded hover:bg-blue-700">
|
||||
Search
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ThemeProvider>
|
||||
);
|
||||
};
|
||||
|
||||
export default SearchPage;
|
||||
}
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
import { MetadataRoute } from "next";
|
||||
|
||||
export default function sitemap(): MetadataRoute.Sitemap {
|
||||
const baseUrl = "https://autoarchive.example.com";
|
||||
const lastModified = new Date();
|
||||
|
||||
return [
|
||||
{
|
||||
url: baseUrl,
|
||||
lastModified: lastModified,
|
||||
changeFrequency: "weekly", priority: 1.0,
|
||||
},
|
||||
{
|
||||
url: `${baseUrl}/search`,
|
||||
lastModified: lastModified,
|
||||
changeFrequency: "daily", priority: 0.9,
|
||||
},
|
||||
{
|
||||
url: `${baseUrl}/browse`,
|
||||
lastModified: lastModified,
|
||||
changeFrequency: "weekly", priority: 0.9,
|
||||
},
|
||||
{
|
||||
url: `${baseUrl}/compare`,
|
||||
lastModified: lastModified,
|
||||
changeFrequency: "weekly", priority: 0.8,
|
||||
},
|
||||
{
|
||||
url: `${baseUrl}/timeline`,
|
||||
lastModified: lastModified,
|
||||
changeFrequency: "monthly", priority: 0.8,
|
||||
},
|
||||
{
|
||||
url: `${baseUrl}/about`,
|
||||
lastModified: lastModified,
|
||||
changeFrequency: "monthly", priority: 0.7,
|
||||
},
|
||||
{
|
||||
url: `${baseUrl}/privacy`,
|
||||
lastModified: lastModified,
|
||||
changeFrequency: "yearly", priority: 0.5,
|
||||
},
|
||||
{
|
||||
url: `${baseUrl}/terms`,
|
||||
lastModified: lastModified,
|
||||
changeFrequency: "yearly", priority: 0.5,
|
||||
},
|
||||
{
|
||||
url: `${baseUrl}/help`,
|
||||
lastModified: lastModified,
|
||||
changeFrequency: "monthly", priority: 0.6,
|
||||
},
|
||||
{
|
||||
url: `${baseUrl}/contact`,
|
||||
lastModified: lastModified,
|
||||
changeFrequency: "monthly", priority: 0.6,
|
||||
},
|
||||
];
|
||||
}
|
||||
46
src/app/specifications/page.tsx
Normal file
46
src/app/specifications/page.tsx
Normal file
@@ -0,0 +1,46 @@
|
||||
"use client";
|
||||
|
||||
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
|
||||
import NavbarLayoutFloatingOverlay from '@/components/navbar/NavbarLayoutFloatingOverlay/NavbarLayoutFloatingOverlay';
|
||||
|
||||
const testCarImages = [
|
||||
'https://images.unsplash.com/photo-1552519507-da3a142c6e3d?w=800&q=80',
|
||||
'https://images.unsplash.com/photo-1494976866105-d32a481b81b4?w=800&q=80',
|
||||
'https://images.unsplash.com/photo-1527524330007-3ea4e06ed667?w=800&q=80',
|
||||
];
|
||||
|
||||
export default function SpecificationsPage() {
|
||||
return (
|
||||
<ThemeProvider
|
||||
defaultButtonVariant="text-stagger"
|
||||
defaultTextAnimation="entrance-slide"
|
||||
borderRadius="rounded"
|
||||
contentWidth="medium"
|
||||
sizing="medium"
|
||||
background="circleGradient"
|
||||
cardStyle="glass-elevated"
|
||||
primaryButtonStyle="gradient"
|
||||
secondaryButtonStyle="glass"
|
||||
headingFontWeight="normal"
|
||||
>
|
||||
<div id="nav" data-section="nav">
|
||||
<NavbarLayoutFloatingOverlay
|
||||
navItems={[
|
||||
{ name: "Home", id: "/" },
|
||||
{ name: "Browse", id: "browse" },
|
||||
{ name: "Compare", id: "compare" },
|
||||
]}
|
||||
brandName="Webild"
|
||||
button={{ text: "Search", href: "search" }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="min-h-screen flex items-center justify-center p-4">
|
||||
<div className="text-center">
|
||||
<h1 className="text-4xl font-bold mb-4">Car Specifications</h1>
|
||||
<p className="text-lg text-gray-600">Detailed technical specifications for vehicles</p>
|
||||
</div>
|
||||
</div>
|
||||
</ThemeProvider>
|
||||
);
|
||||
}
|
||||
@@ -10,15 +10,15 @@
|
||||
--accent: #ffffff;
|
||||
--background-accent: #ffffff; */
|
||||
|
||||
--background: #f5f5f5;
|
||||
--card: #ffffff;
|
||||
--foreground: #1c1c1c;
|
||||
--primary-cta: #511f1f;
|
||||
--background: #0f172a;
|
||||
--card: #1e293b;
|
||||
--foreground: #f1f5f9;
|
||||
--primary-cta: #3b82f6;
|
||||
--primary-cta-text: #f5f5f5;
|
||||
--secondary-cta: #ffffff;
|
||||
--secondary-cta: #64748b;
|
||||
--secondary-cta-text: #1c1c1c;
|
||||
--accent: #e63946;
|
||||
--background-accent: #e8a8b6;
|
||||
--accent: #06b6d4;
|
||||
--background-accent: #1e293b;
|
||||
|
||||
/* text sizing - set by ThemeProvider */
|
||||
/* --text-2xs: clamp(0.465rem, 0.62vw, 0.62rem);
|
||||
|
||||
56
src/app/terms/page.tsx
Normal file
56
src/app/terms/page.tsx
Normal file
@@ -0,0 +1,56 @@
|
||||
"use client";
|
||||
|
||||
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
|
||||
import NavbarLayoutFloatingOverlay from '@/components/navbar/NavbarLayoutFloatingOverlay/NavbarLayoutFloatingOverlay';
|
||||
|
||||
const testCarImages = [
|
||||
'https://images.unsplash.com/photo-1552519507-da3a142c6e3d?w=800&q=80',
|
||||
'https://images.unsplash.com/photo-1494976866105-d32a481b81b4?w=800&q=80',
|
||||
'https://images.unsplash.com/photo-1527524330007-3ea4e06ed667?w=800&q=80',
|
||||
];
|
||||
|
||||
export default function TermsPage() {
|
||||
return (
|
||||
<ThemeProvider
|
||||
defaultButtonVariant="text-stagger"
|
||||
defaultTextAnimation="entrance-slide"
|
||||
borderRadius="rounded"
|
||||
contentWidth="medium"
|
||||
sizing="medium"
|
||||
background="circleGradient"
|
||||
cardStyle="glass-elevated"
|
||||
primaryButtonStyle="gradient"
|
||||
secondaryButtonStyle="glass"
|
||||
headingFontWeight="normal"
|
||||
>
|
||||
<div id="nav" data-section="nav">
|
||||
<NavbarLayoutFloatingOverlay
|
||||
navItems={[
|
||||
{ name: "Home", id: "/" },
|
||||
{ name: "Browse", id: "browse" },
|
||||
{ name: "Compare", id: "compare" },
|
||||
]}
|
||||
brandName="Webild"
|
||||
button={{ text: "Search", href: "search" }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="min-h-screen p-4">
|
||||
<div className="max-w-2xl mx-auto pt-24">
|
||||
<h1 className="text-4xl font-bold mb-4">Terms of Service</h1>
|
||||
<p className="text-gray-600 mb-8">Last updated: January 2025</p>
|
||||
<div className="space-y-6">
|
||||
<section>
|
||||
<h2 className="text-2xl font-semibold mb-3">1. Acceptance of Terms</h2>
|
||||
<p className="text-gray-700">By accessing and using this website, you accept and agree to be bound by the terms and provision of this agreement.</p>
|
||||
</section>
|
||||
<section>
|
||||
<h2 className="text-2xl font-semibold mb-3">2. Use License</h2>
|
||||
<p className="text-gray-700">Permission is granted to temporarily download one copy of the materials for personal, non-commercial transitory viewing only.</p>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ThemeProvider>
|
||||
);
|
||||
}
|
||||
@@ -1,11 +1,18 @@
|
||||
"use client";
|
||||
|
||||
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
|
||||
import NavbarLayoutFloatingOverlay from '@/components/navbar/NavbarLayoutFloatingOverlay/NavbarLayoutFloatingOverlay';
|
||||
|
||||
const TimelinePage = () => {
|
||||
const testCarImages = [
|
||||
'https://images.unsplash.com/photo-1552519507-da3a142c6e3d?w=800&q=80',
|
||||
'https://images.unsplash.com/photo-1494976866105-d32a481b81b4?w=800&q=80',
|
||||
'https://images.unsplash.com/photo-1527524330007-3ea4e06ed667?w=800&q=80',
|
||||
];
|
||||
|
||||
export default function TimelinePage() {
|
||||
return (
|
||||
<ThemeProvider
|
||||
defaultButtonVariant="hover-magnetic"
|
||||
defaultButtonVariant="text-stagger"
|
||||
defaultTextAnimation="entrance-slide"
|
||||
borderRadius="rounded"
|
||||
contentWidth="medium"
|
||||
@@ -16,10 +23,24 @@ const TimelinePage = () => {
|
||||
secondaryButtonStyle="glass"
|
||||
headingFontWeight="normal"
|
||||
>
|
||||
<div id="nav" data-section="nav" />
|
||||
<div id="timeline" data-section="timeline" />
|
||||
<div id="nav" data-section="nav">
|
||||
<NavbarLayoutFloatingOverlay
|
||||
navItems={[
|
||||
{ name: "Home", id: "/" },
|
||||
{ name: "Browse", id: "browse" },
|
||||
{ name: "Compare", id: "compare" },
|
||||
]}
|
||||
brandName="Webild"
|
||||
button={{ text: "Search", href: "search" }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="min-h-screen flex items-center justify-center p-4">
|
||||
<div className="text-center">
|
||||
<h1 className="text-4xl font-bold mb-4">Vehicle Timeline</h1>
|
||||
<p className="text-lg text-gray-600">Historical vehicle data and model evolution</p>
|
||||
</div>
|
||||
</div>
|
||||
</ThemeProvider>
|
||||
);
|
||||
};
|
||||
|
||||
export default TimelinePage;
|
||||
}
|
||||
|
||||
333
src/lib/database/carDatabase.ts
Normal file
333
src/lib/database/carDatabase.ts
Normal file
@@ -0,0 +1,333 @@
|
||||
/**
|
||||
* Car Database Service
|
||||
* Handles all car data operations and queries
|
||||
*/
|
||||
|
||||
import { Car, CarFilter, CarComparison, CarInventory } from './carTypes';
|
||||
|
||||
export class CarDatabase {
|
||||
private cars: Car[] = [];
|
||||
|
||||
/**
|
||||
* Initialize database with sample data
|
||||
*/
|
||||
initialize(cars: Car[]): void {
|
||||
this.cars = cars;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all cars
|
||||
*/
|
||||
getAllCars(): Car[] {
|
||||
return this.cars;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get car by ID
|
||||
*/
|
||||
getCarById(id: string): Car | undefined {
|
||||
return this.cars.find((car) => car.id === id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Search cars by filter criteria
|
||||
*/
|
||||
filterCars(filter: CarFilter): Car[] {
|
||||
return this.cars.filter((car) => {
|
||||
// Make filter
|
||||
if (filter.make && !filter.make.includes(car.make)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Model filter
|
||||
if (filter.model && !filter.model.includes(car.model)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Year range filter
|
||||
if (filter.yearRange) {
|
||||
const [minYear, maxYear] = filter.yearRange;
|
||||
if (car.year < minYear || car.year > maxYear) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Price range filter
|
||||
if (filter.priceRange) {
|
||||
const [minPrice, maxPrice] = filter.priceRange;
|
||||
if (car.price < minPrice || car.price > maxPrice) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Transmission filter
|
||||
if (filter.transmission && !filter.transmission.includes(car.transmission)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Fuel filter
|
||||
if (filter.fuel && !filter.fuel.includes(car.fuel)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Body type filter
|
||||
if (filter.bodyType && !filter.bodyType.includes(car.bodyType || '')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Drive type filter
|
||||
if (filter.driveType && !filter.driveType.includes(car.driveType || '')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Seating filter
|
||||
if (filter.seatCount && car.seating) {
|
||||
const [minSeats, maxSeats] = filter.seatCount;
|
||||
if (car.seating < minSeats || car.seating > maxSeats) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Safety rating filter
|
||||
if (filter.safetyRating && car.safetyRating && car.safetyRating < filter.safetyRating) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Keyword search
|
||||
if (filter.keyword) {
|
||||
const keyword = filter.keyword.toLowerCase();
|
||||
const searchableFields = [
|
||||
car.make,
|
||||
car.model,
|
||||
car.bodyType,
|
||||
car.color,
|
||||
car.description,
|
||||
].filter(Boolean);
|
||||
|
||||
const matches = searchableFields.some(
|
||||
(field) => field && field.toString().toLowerCase().includes(keyword)
|
||||
);
|
||||
|
||||
if (!matches) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Search cars by keyword
|
||||
*/
|
||||
searchCars(keyword: string): Car[] {
|
||||
return this.filterCars({ keyword });
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cars by make
|
||||
*/
|
||||
getCarsByMake(make: string): Car[] {
|
||||
return this.cars.filter((car) => car.make.toLowerCase() === make.toLowerCase());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cars by fuel type
|
||||
*/
|
||||
getCarsByFuel(fuel: string): Car[] {
|
||||
return this.cars.filter((car) => car.fuel === fuel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cars by body type
|
||||
*/
|
||||
getCarsByBodyType(bodyType: string): Car[] {
|
||||
return this.cars.filter((car) => car.bodyType === bodyType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cars within price range
|
||||
*/
|
||||
getCarsByPriceRange(minPrice: number, maxPrice: number): Car[] {
|
||||
return this.cars.filter((car) => car.price >= minPrice && car.price <= maxPrice);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort cars by field
|
||||
*/
|
||||
sortCars(cars: Car[], sortBy: keyof Car, ascending: boolean = true): Car[] {
|
||||
const sorted = [...cars].sort((a, b) => {
|
||||
const aValue = a[sortBy];
|
||||
const bValue = b[sortBy];
|
||||
|
||||
if (typeof aValue === 'number' && typeof bValue === 'number') {
|
||||
return ascending ? aValue - bValue : bValue - aValue;
|
||||
}
|
||||
|
||||
if (typeof aValue === 'string' && typeof bValue === 'string') {
|
||||
return ascending ? aValue.localeCompare(bValue) : bValue.localeCompare(aValue);
|
||||
}
|
||||
|
||||
return 0;
|
||||
});
|
||||
|
||||
return sorted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get unique makes
|
||||
*/
|
||||
getUniqueMakes(): string[] {
|
||||
const makes = new Set(this.cars.map((car) => car.make));
|
||||
return Array.from(makes).sort();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get unique models for a make
|
||||
*/
|
||||
getUniqueModels(make: string): string[] {
|
||||
const models = new Set(
|
||||
this.cars.filter((car) => car.make === make).map((car) => car.model)
|
||||
);
|
||||
return Array.from(models).sort();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get unique fuel types
|
||||
*/
|
||||
getUniqueFuelTypes(): string[] {
|
||||
const fuels = new Set(this.cars.map((car) => car.fuel));
|
||||
return Array.from(fuels).sort();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get unique body types
|
||||
*/
|
||||
getUniqueBodyTypes(): string[] {
|
||||
const bodyTypes = new Set(this.cars.filter((car) => car.bodyType).map((car) => car.bodyType));
|
||||
return Array.from(bodyTypes).sort();
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare two or more cars
|
||||
*/
|
||||
compareCars(carIds: string[]): Car[] {
|
||||
return carIds
|
||||
.map((id) => this.getCarById(id))
|
||||
.filter((car) => car !== undefined) as Car[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get similar cars based on specifications
|
||||
*/
|
||||
getSimilarCars(carId: string, count: number = 3): Car[] {
|
||||
const car = this.getCarById(carId);
|
||||
if (!car) return [];
|
||||
|
||||
const similar = this.cars
|
||||
.filter((c) => c.id !== carId && c.make === car.make)
|
||||
.slice(0, count);
|
||||
|
||||
return similar.length >= count
|
||||
? similar
|
||||
: this.cars.filter((c) => c.id !== carId && c.bodyType === car.bodyType).slice(0, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get top rated cars
|
||||
*/
|
||||
getTopRatedCars(count: number = 5): Car[] {
|
||||
return [...this.cars]
|
||||
.sort((a, b) => (b.userRating || 0) - (a.userRating || 0))
|
||||
.slice(0, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get most viewed cars
|
||||
*/
|
||||
getMostViewedCars(count: number = 5): Car[] {
|
||||
return [...this.cars]
|
||||
.sort((a, b) => (b.viewCount || 0) - (a.viewCount || 0))
|
||||
.slice(0, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get featured cars
|
||||
*/
|
||||
getFeaturedCars(count: number = 5): Car[] {
|
||||
return this.cars.filter((car) => car.isFavorite).slice(0, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate average specifications for a make or body type
|
||||
*/
|
||||
calculateAverageSpecs(
|
||||
cars: Car[]
|
||||
): Partial<Car> {
|
||||
if (cars.length === 0) return {};
|
||||
|
||||
const specs: Partial<Car> = {
|
||||
price:
|
||||
cars.reduce((sum, car) => sum + car.price, 0) / cars.length,
|
||||
horsepower:
|
||||
cars.reduce((sum, car) => sum + (car.horsepower || 0), 0) / cars.length,
|
||||
mpg: cars.reduce((sum, car) => sum + (car.mpg || 0), 0) / cars.length,
|
||||
seating:
|
||||
Math.round(cars.reduce((sum, car) => sum + (car.seating || 0), 0) / cars.length),
|
||||
};
|
||||
|
||||
return specs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new car to database
|
||||
*/
|
||||
addCar(car: Car): void {
|
||||
this.cars.push(car);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a car
|
||||
*/
|
||||
updateCar(id: string, updates: Partial<Car>): Car | undefined {
|
||||
const index = this.cars.findIndex((car) => car.id === id);
|
||||
if (index !== -1) {
|
||||
this.cars[index] = { ...this.cars[index], ...updates, updatedAt: new Date() };
|
||||
return this.cars[index];
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a car
|
||||
*/
|
||||
deleteCar(id: string): boolean {
|
||||
const index = this.cars.findIndex((car) => car.id === id);
|
||||
if (index !== -1) {
|
||||
this.cars.splice(index, 1);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get database statistics
|
||||
*/
|
||||
getStatistics() {
|
||||
return {
|
||||
totalCars: this.cars.length,
|
||||
averagePrice: this.cars.reduce((sum, car) => sum + car.price, 0) / this.cars.length,
|
||||
makes: this.getUniqueMakes().length,
|
||||
models: this.cars.length,
|
||||
fuelTypes: this.getUniqueFuelTypes().length,
|
||||
bodyTypes: this.getUniqueBodyTypes().length,
|
||||
averageHorsepower:
|
||||
this.cars.reduce((sum, car) => sum + (car.horsepower || 0), 0) / this.cars.length,
|
||||
averageMpg:
|
||||
this.cars.reduce((sum, car) => sum + (car.mpg || 0), 0) / this.cars.length,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Export singleton instance
|
||||
export const carDatabase = new CarDatabase();
|
||||
249
src/lib/database/carTypes.ts
Normal file
249
src/lib/database/carTypes.ts
Normal file
@@ -0,0 +1,249 @@
|
||||
/**
|
||||
* Universal Car Database Types
|
||||
* Defines all fields and structures for car data management
|
||||
*/
|
||||
|
||||
export interface Car {
|
||||
// Basic Information
|
||||
id: string;
|
||||
make: string; // Manufacturer (e.g., Toyota, Honda, BMW)
|
||||
model: string; // Model name (e.g., Camry, Civic, 3 Series)
|
||||
year: number; // Model year
|
||||
vin?: string; // Vehicle Identification Number
|
||||
generation?: string; // Generation/body style
|
||||
|
||||
// Pricing
|
||||
price: number; // Base price in USD
|
||||
msrp?: number; // Manufacturer Suggested Retail Price
|
||||
depreciation?: number; // Annual depreciation percentage
|
||||
|
||||
// Transmission & Drivetrain
|
||||
transmission: 'Manual' | 'Automatic' | 'CVT' | 'Semi-Automatic';
|
||||
driveType?: 'FWD' | 'RWD' | 'AWD' | 'RWD/AWD';
|
||||
gears?: number; // Number of gears
|
||||
|
||||
// Fuel & Environmental
|
||||
fuel: 'Gasoline' | 'Diesel' | 'Hybrid' | 'Electric' | 'Plug-in Hybrid';
|
||||
mpg?: number; // Miles per gallon (combined)
|
||||
mpgCity?: number; // City MPG
|
||||
mpgHighway?: number; // Highway MPG
|
||||
fuelCapacity?: number; // In gallons
|
||||
co2Emissions?: number; // Grams per mile
|
||||
|
||||
// Engine Specifications
|
||||
engineSize?: number; // Engine displacement in liters
|
||||
cylinders?: number; // Number of cylinders
|
||||
horsepower?: number; // Power output in HP
|
||||
torque?: number; // Torque in lb-ft
|
||||
topSpeed?: number; // Maximum speed in mph
|
||||
acceleration?: number; // 0-60 time in seconds
|
||||
powerDelivery?: string; // Direct injection, turbocharged, etc.
|
||||
|
||||
// Dimensions & Weight
|
||||
length?: number; // In inches
|
||||
width?: number; // In inches
|
||||
height?: number; // In inches
|
||||
wheelbase?: number; // Distance between front and rear axles in inches
|
||||
weight?: number; // Curb weight in lbs
|
||||
groundClearance?: number; // In inches
|
||||
trackWidth?: number; // Front and rear track width
|
||||
overhang?: number; // Front and rear overhang
|
||||
|
||||
// Capacity
|
||||
seating?: number; // Number of passengers
|
||||
luggage?: number; // Cargo space in cubic feet
|
||||
maxLoad?: number; // Maximum payload in lbs
|
||||
towingCapacity?: number; // Towing capacity in lbs
|
||||
|
||||
// Exterior
|
||||
bodyType?: 'Sedan' | 'SUV' | 'Truck' | 'Coupe' | 'Hatchback' | 'Wagon' | 'Minivan' | 'Crossover';
|
||||
color?: string;
|
||||
doorsCount?: number; // Number of doors
|
||||
roofType?: 'Fixed' | 'Panoramic' | 'Sunroof' | 'Convertible';
|
||||
wheelSize?: string; // e.g., "18 inch"
|
||||
wheelStyle?: string; // Design description
|
||||
|
||||
// Interior
|
||||
upholstery?: string; // Material (Cloth, Leather, Suede, etc.)
|
||||
seatMaterial?: 'Cloth' | 'Leather' | 'Suede' | 'Synthetic';
|
||||
interiorColor?: string;
|
||||
interiorTrim?: string; // Premium, sport, luxury, etc.
|
||||
steeringWheelMaterial?: string;
|
||||
dashboardMaterial?: string;
|
||||
|
||||
// Safety Features
|
||||
safetyRating?: number; // NHTSA/IIHS rating (1-5)
|
||||
airbags?: number; // Number of airbags
|
||||
crashTestScore?: number;
|
||||
rolloverRating?: number;
|
||||
safetyFeatures?: string[]; // Array of safety features
|
||||
adas?: string[]; // Advanced Driver Assistance Systems
|
||||
|
||||
// Technology & Infotainment
|
||||
infotainmentSystem?: string; // System name (Apple CarPlay, Android Auto, etc.)
|
||||
displaySize?: number; // Screen size in inches
|
||||
displayType?: 'LCD' | 'OLED' | 'Touchscreen';
|
||||
navigationSystem?: boolean;
|
||||
soundSystem?: string; // Brand and configuration
|
||||
speakers?: number; // Number of speakers
|
||||
bluetooth?: boolean;
|
||||
wifi?: boolean;
|
||||
phoneIntegration?: string[]; // iOS CarPlay, Android Auto, etc.
|
||||
voiceControl?: boolean;
|
||||
|
||||
// Climate Control
|
||||
airConditioning?: 'Manual' | 'Automatic' | 'Dual-zone' | 'Multi-zone';
|
||||
heatedSeats?: boolean;
|
||||
ventilatedSeats?: boolean;
|
||||
heatedSteeringWheel?: boolean;
|
||||
heatedWindshield?: boolean;
|
||||
climateZones?: number;
|
||||
|
||||
// Lights & Visibility
|
||||
headlightType?: 'Halogen' | 'LED' | 'HID' | 'Adaptive LED';
|
||||
adapativeHeadlights?: boolean;
|
||||
ledDaytimeRunningLights?: boolean;
|
||||
rearLights?: 'LED' | 'Halogen';
|
||||
wiper?: 'Manual' | 'Rain-sensing automatic';
|
||||
wiperSpeed?: string;
|
||||
rearWiper?: boolean;
|
||||
washerFluid?: boolean;
|
||||
parkingLights?: boolean;
|
||||
automaticLights?: boolean;
|
||||
|
||||
// Suspension & Handling
|
||||
suspensionType?: string; // MacPherson, multi-link, etc.
|
||||
steeringType?: string; // Rack and pinion, etc.
|
||||
steeringRatio?: string; // e.g., "15.6:1"
|
||||
brakesType?: string; // Disc/drum configuration
|
||||
abs?: boolean; // Anti-lock braking system
|
||||
ebd?: boolean; // Electronic brakeforce distribution
|
||||
stabilityControl?: boolean;
|
||||
tractionControl?: boolean;
|
||||
hillStartAssist?: boolean;
|
||||
adaptiveSuspension?: boolean;
|
||||
|
||||
// Storage & Organization
|
||||
armrests?: number;
|
||||
cupholders?: number;
|
||||
storageCompartments?: number;
|
||||
doorPockets?: number;
|
||||
underfloorStorage?: boolean;
|
||||
ceilingStorage?: boolean;
|
||||
|
||||
// Convenience Features
|
||||
powerWindows?: boolean;
|
||||
powerDoors?: boolean;
|
||||
powerTrunk?: boolean;
|
||||
powerSteeringWheel?: boolean;
|
||||
powerSeats?: boolean;
|
||||
memorySeats?: boolean;
|
||||
keylessEntry?: boolean;
|
||||
pushButtonStart?: boolean;
|
||||
remoteStart?: boolean;
|
||||
automaticParking?: boolean;
|
||||
handsFreeParking?: boolean;
|
||||
|
||||
// Warranty
|
||||
warrantyBasic?: string; // e.g., "3 years/36,000 miles"
|
||||
warrantyPowertrain?: string;
|
||||
warrantyRust?: string;
|
||||
warrantyRoadsideAssistance?: string;
|
||||
|
||||
// Maintenance
|
||||
oilChangeInterval?: number; // In miles
|
||||
maintenanceCost?: number; // Estimated annual cost
|
||||
commonIssues?: string[];
|
||||
|
||||
// Performance
|
||||
fuelEconomy?: 'Poor' | 'Average' | 'Good' | 'Excellent';
|
||||
handling?: 'Soft' | 'Balanced' | 'Sporty' | 'Very Sporty';
|
||||
comfort?: 'Firm' | 'Balanced' | 'Soft' | 'Very Soft';
|
||||
noiseLevels?: 'High' | 'Medium' | 'Low' | 'Very Low';
|
||||
reliabilityRating?: number; // 1-10 scale
|
||||
resaleValue?: number; // Percentage after 3 years
|
||||
|
||||
// Availability & Production
|
||||
productionStart?: Date;
|
||||
productionEnd?: Date;
|
||||
productionCountries?: string[];
|
||||
availableMarkets?: string[];
|
||||
discontinuedYear?: number;
|
||||
|
||||
// Media & Marketing
|
||||
imageUrls?: string[];
|
||||
videoUrl?: string;
|
||||
brochureUrl?: string;
|
||||
description?: string; // Marketing description
|
||||
|
||||
// Additional Features
|
||||
features?: string[]; // Array of key features
|
||||
highlights?: string[];
|
||||
competitors?: string[]; // Competing models
|
||||
|
||||
// Metadata
|
||||
createdAt?: Date;
|
||||
updatedAt?: Date;
|
||||
lastViewed?: Date;
|
||||
viewCount?: number;
|
||||
isFavorite?: boolean;
|
||||
userRating?: number;
|
||||
reviews?: Review[];
|
||||
}
|
||||
|
||||
export interface Review {
|
||||
id: string;
|
||||
carId: string;
|
||||
userId: string;
|
||||
userName: string;
|
||||
rating: number; // 1-5
|
||||
title: string;
|
||||
comment: string;
|
||||
pros?: string[];
|
||||
cons?: string[];
|
||||
createdAt: Date;
|
||||
helpful?: number; // Number of helpful votes
|
||||
}
|
||||
|
||||
export interface CarFilter {
|
||||
make?: string[];
|
||||
model?: string[];
|
||||
yearRange?: [number, number];
|
||||
priceRange?: [number, number];
|
||||
transmission?: string[];
|
||||
fuel?: string[];
|
||||
bodyType?: string[];
|
||||
driveType?: string[];
|
||||
seatCount?: [number, number];
|
||||
fuelEconomy?: 'Poor' | 'Average' | 'Good' | 'Excellent';
|
||||
safetyRating?: number; // Minimum rating
|
||||
keyword?: string;
|
||||
}
|
||||
|
||||
export interface CarComparison {
|
||||
carIds: string[];
|
||||
compareFields: (keyof Car)[];
|
||||
}
|
||||
|
||||
export interface CarInventory {
|
||||
carId: string;
|
||||
dealershipId: string;
|
||||
stockNumber: string;
|
||||
condition: 'New' | 'Used' | 'Certified Pre-Owned';
|
||||
mileage: number;
|
||||
inStock: boolean;
|
||||
quantity?: number;
|
||||
dateAdded: Date;
|
||||
lastUpdated: Date;
|
||||
}
|
||||
|
||||
export interface DealershipListing {
|
||||
id: string;
|
||||
dealershipName: string;
|
||||
dealershipLocation: string;
|
||||
dealershipPhone: string;
|
||||
dealershipEmail: string;
|
||||
cars: CarInventory[];
|
||||
rating?: number;
|
||||
reviewCount?: number;
|
||||
}
|
||||
Reference in New Issue
Block a user