Add premium configurator with split-screen layout

- Redesigned configurator page with split-screen interface
- Left: Large visual preview with sticky positioning
- Right: Premium white controls container with form steps
- Added complete configurator wizard (5 steps)
- Updated hero CTA to "Zelf ontwerpen"
- Configured Shadcn UI with Slate theme
- Added layout components (Navbar, Footer)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Ubuntu
2026-02-10 15:59:37 +00:00
parent c283d7193a
commit 9cf5cea3ba
55 changed files with 8411 additions and 99 deletions

View File

@@ -0,0 +1,88 @@
import Image from "next/image";
import Link from "next/link";
import { MousePointerClick, FileText } from "lucide-react";
export function AboutSection() {
return (
<section className="bg-[#F5F5F3] py-24">
<div className="mx-auto grid max-w-7xl grid-cols-1 items-stretch gap-8 px-4 sm:px-6 lg:grid-cols-12 lg:px-8">
{/* Left Column - Tall Image */}
<div className="relative min-h-[500px] overflow-hidden rounded-[2.5rem] lg:col-span-5 lg:min-h-[600px]">
<Image
src="/images/image-people1.png"
alt="Het team van Proinn aan het werk"
fill
className="object-cover"
sizes="(max-width: 1024px) 100vw, 42vw"
/>
</div>
{/* Right Column - Stacked Cards */}
<div className="flex flex-col gap-8 lg:col-span-7">
{/* Card 1 - Zelf aan de slag */}
<div className="flex flex-1 flex-col justify-center rounded-[2.5rem] bg-[#1A2E2E] p-10 lg:p-12">
{/* Label */}
<div className="mb-6 flex items-center gap-3">
<div className="h-5 w-1 rounded-full bg-[#C4D668]" />
<span className="text-sm font-medium tracking-wide text-[#C4D668]">
Zelf aan de slag
</span>
</div>
{/* Heading */}
<h2 className="mb-4 text-3xl font-bold leading-tight text-white lg:text-4xl">
Ontwerp jouw deur of wand
<br />
op maat en zie direct de prijs
</h2>
{/* Text */}
<p className="mb-8 max-w-lg text-sm leading-relaxed text-gray-300">
Wil je zelf bepalen hoe jouw deur of wand eruitziet? Met onze
configurator kan dat. Jij kiest, wij maken. Selecteer stap voor
stap jouw favoriete uitvoering en bekijk direct het resultaat in
beeld en prijs.
</p>
{/* Button */}
<div>
<Link
href="/offerte"
className="inline-flex items-center gap-2 rounded-md bg-[#C4D668] px-6 py-3 text-sm font-semibold text-black transition-colors hover:bg-[#b5c75a]"
>
Klik hier
<MousePointerClick className="size-4" />
</Link>
</div>
</div>
{/* Card 2 - Hulp nodig */}
<div className="flex flex-1 flex-col justify-center rounded-[2.5rem] bg-[#1A2E2E] p-10 lg:p-12">
{/* Heading */}
<h3 className="mb-4 text-2xl font-bold text-white lg:text-3xl">
Heb je meer hulp nodig?
</h3>
{/* Text */}
<p className="mb-8 max-w-lg text-sm leading-relaxed text-gray-300">
We kunnen ons voorstellen dat je graag geholpen wordt rondom het
samenstellen van je deur. Hieronder kan je eenvoudig een snelle
offerte aanvragen waarna we contact met jou opnemen.
</p>
{/* Button */}
<div>
<Link
href="/offerte"
className="inline-flex items-center gap-2 rounded-md border-2 border-white px-6 py-3 text-sm font-semibold text-white transition-colors hover:bg-white hover:text-[#1A2E2E]"
>
<FileText className="size-4" />
Snelle offerte aanvragen
</Link>
</div>
</div>
</div>
</div>
</section>
);
}

View File

@@ -0,0 +1,52 @@
import Link from "next/link";
import Image from "next/image";
import { Button } from "@/components/ui/button";
import { ArrowRight } from "lucide-react";
export function AboutTeaser() {
return (
<section className="border-t border-border bg-muted/40 py-24">
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
<div className="grid items-center gap-12 lg:grid-cols-2">
{/* Text */}
<div>
<p className="mb-2 text-sm font-semibold uppercase tracking-widest text-brand-blue">
Over Proinn
</p>
<h2 className="mb-6 text-3xl font-bold tracking-tight sm:text-4xl">
Vakmanschap sinds de eerste las
</h2>
<p className="mb-4 leading-relaxed text-muted-foreground">
Bij Proinn draait alles om staal. Onze werkplaats combineert
traditioneel vakmanschap met moderne technieken om producten te
leveren die niet alleen functioneel zijn, maar ook esthetisch
verantwoord.
</p>
<p className="mb-8 leading-relaxed text-muted-foreground">
Van industriële stalen deuren tot op maat gemaakte kozijnen wij
denken mee, ontwerpen en produceren alles in eigen huis.
</p>
<Button asChild variant="outline" size="lg">
<Link href="/contact">
Neem Contact Op
<ArrowRight className="size-4" />
</Link>
</Button>
</div>
{/* Image */}
<div className="relative aspect-[4/3] overflow-hidden rounded-lg">
<Image
src="/images/about.jpg"
alt="Proinn werkplaats — stalen deuren productie"
fill
className="object-cover"
/>
{/* Accent corner */}
<div className="absolute bottom-0 left-0 h-1.5 w-24 bg-brand-orange" />
</div>
</div>
</div>
</section>
);
}

View File

@@ -0,0 +1,63 @@
import Image from "next/image";
import Link from "next/link";
import { ArrowRight } from "lucide-react";
export function CraftsmanshipSection() {
return (
<section className="relative bg-white">
<div className="mx-auto grid max-w-7xl grid-cols-1 lg:grid-cols-2">
{/* Left Column - Image */}
<div className="relative z-10 min-h-[450px] overflow-hidden rounded-r-[2.5rem] lg:min-h-[560px]">
<Image
src="/images/proinn-spuiten.png"
alt="Vakmanschap bij Proinn - spuitwerk in de fabriek"
fill
className="object-cover"
sizes="(max-width: 1024px) 100vw, 50vw"
/>
</div>
{/* Right Column - Dark Content */}
<div className="flex flex-col justify-center bg-[#1A2E2E] px-8 py-16 lg:px-16 lg:py-20">
{/* Label */}
<div className="mb-6 flex items-center gap-3">
<div className="h-5 w-1 rounded-full bg-[#C4D668]" />
<span className="text-sm font-medium tracking-wide text-[#C4D668]">
Waarom Proinn
</span>
</div>
{/* Heading */}
<h2 className="mb-5 text-3xl font-bold leading-tight text-white lg:text-4xl">
Vakmanschap op
<br />
ieder niveau
</h2>
{/* Text */}
<p className="mb-10 max-w-md text-sm leading-relaxed text-gray-300">
Bij Proinn draait alles om kwaliteit en vakmanschap. Van het eerste
ontwerp tot de laatste afwerking elk detail wordt met zorg
behandeld in onze eigen fabriek. Wij combineren ambachtelijke
technieken met moderne technologie om stalen deuren en wanden te
maken die perfect passen bij jouw ruimte.
</p>
{/* Input Group */}
<div className="flex max-w-md items-center gap-3">
<div className="flex-1 rounded-md bg-[#263e3e] px-4 py-3 text-sm text-gray-400">
Meer weten?
</div>
<Link
href="/over-ons"
className="inline-flex items-center gap-2 rounded-md bg-[#C4D668] px-5 py-3 text-sm font-semibold text-black transition-colors hover:bg-[#b5c75a]"
>
Over ons
<ArrowRight className="size-4" />
</Link>
</div>
</div>
</div>
</section>
);
}

View File

@@ -0,0 +1,56 @@
import { Hammer, Truck, ShieldCheck } from "lucide-react";
const features = [
{
icon: Hammer,
title: "Ambachtelijk Maatwerk",
description:
"Elk product wordt op maat gemaakt in onze eigen werkplaats. Geen standaardwerk, maar vakmanschap tot in detail.",
},
{
icon: Truck,
title: "Snelle Levering",
description:
"Korte doorlooptijden dankzij ons efficiënte productieproces. Van offerte tot montage, wij leveren op tijd.",
},
{
icon: ShieldCheck,
title: "Hoogste Kwaliteit",
description:
"Wij werken uitsluitend met hoogwaardig staal en duurzame coatings. Gebouwd om generaties mee te gaan.",
},
];
export function Features() {
return (
<section className="py-24">
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
<div className="mb-16 max-w-xl">
<p className="mb-2 text-sm font-semibold uppercase tracking-widest text-brand-orange">
Waarom Proinn
</p>
<h2 className="text-3xl font-bold tracking-tight sm:text-4xl">
Gebouwd op vakmanschap
</h2>
</div>
<div className="grid gap-8 md:grid-cols-3">
{features.map((feature) => (
<div
key={feature.title}
className="group rounded-lg border border-border bg-card p-8 transition-all hover:border-brand-orange/30 hover:shadow-lg"
>
<div className="mb-5 inline-flex rounded-md bg-brand-orange/10 p-3">
<feature.icon className="size-6 text-brand-orange" />
</div>
<h3 className="mb-3 text-lg font-semibold">{feature.title}</h3>
<p className="text-sm leading-relaxed text-muted-foreground">
{feature.description}
</p>
</div>
))}
</div>
</div>
</section>
);
}

62
components/home/hero.tsx Normal file
View File

@@ -0,0 +1,62 @@
import Link from "next/link";
import Image from "next/image";
import { ArrowRight } from "lucide-react";
export function Hero() {
return (
<section className="relative flex min-h-screen items-end overflow-hidden">
{/* Background image */}
<Image
src="/images/hero.jpg"
alt="Stalen deuren in modern interieur"
fill
className="object-cover"
priority
/>
{/* Gradient overlay */}
<div className="absolute inset-0 bg-gradient-to-t from-[#1A2E2E]/90 via-[#1A2E2E]/30 to-transparent" />
{/* Content pinned to bottom */}
<div className="relative w-full pb-20 pt-40">
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
{/* Label */}
<div className="mb-6 flex items-center gap-2">
<div className="h-5 w-1 rounded-full bg-[#C4D668]" />
<span className="text-sm font-medium tracking-wide text-[#C4D668]">
Staal &middot; Vakmanschap &middot; Maatwerk
</span>
</div>
<h1 className="max-w-3xl text-5xl font-light leading-[1.1] tracking-tight text-white md:text-7xl">
Innovatieve
<br />
<span className="font-semibold">Stalen</span> Oplossingen
</h1>
<p className="mt-6 max-w-md text-base font-light leading-relaxed text-white/60">
Maatwerk voor bedrijven en particulieren. Van stalen deuren tot
industriële kozijnen wij realiseren uw visie in staal.
</p>
<div className="mt-10 flex flex-col gap-4 sm:flex-row">
<Link
href="/offerte"
className="inline-flex items-center gap-2 rounded-md bg-[#C4D668] px-7 py-3 text-sm font-semibold text-black transition-colors hover:bg-[#b5c75a]"
>
Zelf ontwerpen
<ArrowRight className="size-4" />
</Link>
<Link
href="/producten"
className="inline-flex items-center gap-2 rounded-md border-2 border-white/30 px-7 py-3 text-sm font-semibold text-white transition-colors hover:bg-white/10"
>
Bekijk Producten
</Link>
</div>
</div>
</div>
</section>
);
}

View File

@@ -0,0 +1,149 @@
"use client";
import Image from "next/image";
import Link from "next/link";
import { ArrowRight, DoorOpen, Home, Grid2x2 } from "lucide-react";
import { useState } from "react";
import { cn } from "@/lib/utils";
const categories = [
{
id: "binnendeuren",
title: "Binnendeuren",
subtitle: "Stalen deuren voor binnen gebruik",
href: "/producten/binnendeuren",
icon: DoorOpen,
},
{
id: "buitendeuren",
title: "Buitendeuren",
subtitle: "Stalen deuren voor buiten gebruik",
href: "/producten/buitendeuren",
icon: Home,
},
{
id: "kantoorwanden",
title: "Kantoorwanden",
subtitle: "Glazen wanden voor kantoren",
href: "/producten/kantoorwanden",
icon: Grid2x2,
},
];
export function OfferSection() {
const [activeId, setActiveId] = useState("binnendeuren");
return (
<section className="bg-[#F5F5F3] py-20">
<div className="mx-auto grid max-w-7xl gap-12 px-4 sm:px-6 lg:grid-cols-2 lg:gap-16 lg:px-8">
{/* Left Column */}
<div className="flex flex-col justify-center">
{/* Label */}
<div className="mb-6 flex items-center gap-2">
<div className="h-5 w-1 rounded-full bg-[#C4D668]" />
<span className="text-sm font-medium tracking-wide text-gray-500">
Ons aanbod
</span>
</div>
{/* Heading */}
<h2 className="mb-5 text-4xl font-light leading-tight text-gray-900 lg:text-5xl">
Waar ben je
<br />
naar op zoek?
</h2>
{/* Description */}
<p className="mb-10 max-w-lg text-sm leading-relaxed text-gray-500">
Bij Proinn vind je deuren en wanden die passen bij iedere situatie.
Of je nu op zoek bent naar stijlvolle binnendeuren, sterke
buitendeuren of functionele kantoorwanden: wij verzorgen het
volledig op maat. Altijd met de kwaliteit, aandacht en service die
je van ons mag verwachten.
</p>
{/* Category Cards */}
<div className="space-y-3">
{categories.map((cat) => {
const isActive = activeId === cat.id;
const Icon = cat.icon;
return (
<Link
key={cat.id}
href={cat.href}
onMouseEnter={() => setActiveId(cat.id)}
className={cn(
"flex items-center gap-4 rounded-xl px-5 py-4 transition-all duration-200",
isActive
? "bg-[#1A2E2E] text-white shadow-lg"
: "bg-white text-gray-800 shadow-sm hover:shadow-md"
)}
>
{/* Icon */}
<div
className={cn(
"flex size-12 shrink-0 items-center justify-center rounded-lg",
isActive
? "bg-white/10"
: "bg-gray-50"
)}
>
<Icon
className={cn(
"size-6",
isActive ? "text-white" : "text-gray-600"
)}
strokeWidth={1.5}
/>
</div>
{/* Text */}
<div className="flex-1">
<p className="text-sm font-semibold">{cat.title}</p>
<p
className={cn(
"text-xs",
isActive ? "text-gray-300" : "text-gray-400"
)}
>
{cat.subtitle}
</p>
</div>
{/* Arrow */}
<div
className={cn(
"flex size-10 shrink-0 items-center justify-center rounded-lg transition-colors",
isActive
? "bg-white/10"
: "bg-gray-100"
)}
>
<ArrowRight
className={cn(
"size-4",
isActive ? "text-white" : "text-gray-500"
)}
/>
</div>
</Link>
);
})}
</div>
</div>
{/* Right Column - Image */}
<div className="relative min-h-[400px] overflow-hidden rounded-[2rem] lg:min-h-[560px]">
<Image
src="/images/aanbod.jpg"
alt="Stalen deur in modern interieur"
fill
className="object-cover"
sizes="(max-width: 1024px) 100vw, 50vw"
/>
</div>
</div>
</section>
);
}

View File

@@ -0,0 +1,118 @@
import Link from "next/link";
import {
ArrowRight,
Check,
MapPin,
PenTool,
} from "lucide-react";
const steps = [
"Vrijblijvende offerte",
"Wensen bespreken",
"Meten is weten",
"Het definitieve plan",
"Jouw deur wordt gemaakt",
"Montage op locatie",
];
const checklistItems = [
"We luisteren goed naar jouw ideeën en denken mee in mogelijkheden.",
"Samen vertalen we jouw wensen naar een passend ontwerp.",
"In onze eigen fabriek maken we alles volledig op maat.",
"We gebruiken hoogwaardige materialen voor een duurzaam resultaat.",
"Tijdens het hele traject kun je rekenen op persoonlijk advies.",
"Ons team zorgt voor een zorgvuldige en nette montage op locatie.",
];
export function ProcessSection() {
return (
<section className="bg-[#F5F5F3] py-20">
<div className="mx-auto grid max-w-7xl gap-12 px-4 sm:px-6 lg:grid-cols-2 lg:gap-16 lg:px-8">
{/* Left Column */}
<div className="flex flex-col justify-center">
{/* Label */}
<div className="mb-6 flex items-center gap-2">
<div className="h-5 w-1 rounded-full bg-[#C4D668]" />
<span className="text-sm font-medium tracking-wide text-gray-500">
Onze werkwijze in 6 stappen
</span>
</div>
{/* Heading */}
<h2 className="mb-5 text-4xl font-light leading-tight text-gray-900 lg:text-5xl">
Van schets tot stalen
<br />
deur in je woonkamer
</h2>
{/* Description */}
<p className="mb-8 max-w-lg text-sm leading-relaxed text-gray-500">
Bij Proinn vinden we dat een deur of wand meer is dan alleen een
praktisch product. Het bepaalt de sfeer van een ruimte en moet
perfect aansluiten bij jouw wensen. Daarom begeleiden we je stap
voor stap in het proces:
</p>
{/* Checklist */}
<ul className="mb-8 space-y-3">
{checklistItems.map((item) => (
<li key={item} className="flex items-start gap-3">
<Check className="mt-0.5 size-4 shrink-0 text-gray-700" strokeWidth={2.5} />
<span className="text-sm leading-snug text-gray-600">
{item}
</span>
</li>
))}
</ul>
{/* Closing text */}
<p className="mb-8 max-w-lg text-sm leading-relaxed text-gray-500">
Zo zorgen we ervoor dat jij straks een deur of wand hebt die niet
alleen mooi oogt, maar ook praktisch en duurzaam is.
</p>
{/* Buttons */}
<div className="flex flex-wrap items-center gap-3">
<Link
href="/showrooms"
className="inline-flex items-center gap-2 rounded-md bg-[#1A2E2E] px-5 py-2.5 text-sm font-semibold text-white transition-colors hover:bg-[#263e3e]"
>
<MapPin className="size-4" />
Onze showrooms
</Link>
<Link
href="/offerte"
className="inline-flex items-center gap-2 rounded-md bg-[#C4D668] px-5 py-2.5 text-sm font-semibold text-black transition-colors hover:bg-[#b5c75a]"
>
<PenTool className="size-4" />
Zelf ontwerpen
</Link>
</div>
</div>
{/* Right Column - 6 Steps */}
<div className="flex flex-col justify-center space-y-3">
{steps.map((step, index) => (
<div
key={step}
className="flex items-center gap-4 rounded-xl bg-white px-5 py-4 shadow-sm"
>
{/* Number Circle */}
<div className="flex size-10 shrink-0 items-center justify-center rounded-full border border-gray-200 text-sm font-semibold text-gray-700">
{index + 1}
</div>
{/* Step Text */}
<span className="flex-1 text-sm font-semibold text-gray-800">
{step}
</span>
{/* Arrow */}
<ArrowRight className="size-4 shrink-0 text-gray-400" />
</div>
))}
</div>
</div>
</section>
);
}