Files
Voyager/src/components/tour-booking.tsx
2026-09-21 16:18:49 +03:30

156 lines
7.6 KiB
TypeScript

import type { ReactNode } from "react";
import { ButtonLink } from "@/components/button";
import { Reveal } from "@/components/reveal";
type Feature = { title: string; description: string; icon: ReactNode; full?: boolean };
// Lucide-style 24px stroke icons, ported from the Figma export
const features: Feature[] = [
{
title: "Tour Builder",
description: "Create tours, routes, stops, schedules, departures and products.",
icon: (
<>
<path d="M4 10C4 6.229 4 4.343 5.172 3.172 6.343 2 8.229 2 12 2s5.657 0 6.828 1.172C20 4.343 20 6.229 20 10v2c0 3.771 0 5.657-1.172 6.828C17.657 20 15.771 20 12 20s-5.657 0-6.828-1.172C4 17.657 4 15.771 4 12z" />
<path d="M4 13h16M15.5 16H17M7 16h1.5" />
<path d="M6 19.5V21a1 1 0 0 0 1 1h1.5a1 1 0 0 0 1-1v-1M18 19.5V21a1 1 0 0 1-1 1h-1.5a1 1 0 0 1-1-1v-1" />
<path d="M20 9h1a1 1 0 0 1 1 1v1a1 1 0 0 1-.4.8L20 13M4 9H3a1 1 0 0 0-1 1v1a1 1 0 0 0 .4.8L4 13M19.5 5h-15" />
</>
),
},
{
title: "Real-Time Availability",
description: "Manage capacity, inventory and availability in real time.",
icon: (
<>
<path d="M22 10.5V12c0 4.714 0 7.071-1.464 8.536C19.071 22 16.714 22 12 22s-7.071 0-8.536-1.464C2 19.071 2 16.714 2 12s0-7.071 1.464-8.536C4.929 2 7.286 2 12 2h1.5" />
<circle cx="19" cy="5" r="3" />
<path d="M7 14h9M7 17.5h6" />
</>
),
},
{
title: "Flexible Pricing",
description: "Create fixed, dynamic, seasonal, group and channel-specific pricing.",
icon: (
<>
<path d="M4.73 16.14 2.57 13.98c-.7-.7-1.05-1.06-1.19-1.48s0-.87.14-1.75l.28-1.72c.28-1.79.42-2.68.9-3.16.49-.49 1.38-.62 3.17-.9l1.72-.28c.88-.14 1.32-.21 1.75-.14s.78.49 1.48 1.19l1.83 1.83c2.13 2.13 3.2 3.2 3.2 4.53s-1.07 2.4-3.2 4.54c-2.14 2.13-3.2 3.2-4.54 3.2s-2.4-1.07-4.53-3.2Z" />
<path d="m15.39 15.39.35.35M15.39 15.39c-.4.4-.94.57-1.39.47m1.39-.47c.59-.59.67-1.46.18-1.94-.49-.49-1.36-.4-1.94.18-.59.59-1.46.67-1.94.18s-.4-1.36.18-1.94M15.39 15.39c.35.4.44.86.31 1.28m-3.87-4.53.35.35" />
<circle cx="8.61" cy="8.88" r="2" transform="rotate(-45 8.61 8.88)" />
</>
),
},
{
title: "Preservation",
description: "Manage individual, group, private, corporate and wholesale bookings.",
icon: (
<>
<path d="m18.18 8.04.46-.46a1.75 1.75 0 0 1 2.47 2.47l-.46.46m-2.47-2.47c0 1 .87 1.86 1.75 1.86m.72-1.86-4.26 4.26c-.6.6-.9.9-1.11 1.24-.19.32-.33.66-.42 1.02l-.7 2.61-.2.33m0 0-.4.13c-.19.06-.4.02-.55-.16-.14-.14-.19-.35-.13-.55l.53-1.5" />
<path d="M8 13h2.5M8 9h6.5M8 17h1.5" />
<path d="M19.83 3.17C18.66 2 16.77 2 13 2h-2C7.23 2 5.34 2 4.17 3.17 3 4.34 3 6.23 3 10v4c0 3.77 0 5.66 1.17 6.83C5.34 22 7.23 22 11 22h2c3.77 0 5.66 0 6.83-1.17.94-.94 1.13-2.35 1.16-4.83" />
</>
),
},
{
title: "Digital Tickets",
description: "Issue digital tickets, confirmations, vouchers and booking information.",
icon: (
<>
<path d="M20.31 12.65 20.83 10.72c.6-2.26.91-3.38.68-4.36a4.5 4.5 0 0 0-1.16-2.02c-.73-.68-1.86-1-4.12-1.6-2.25-.6-3.38-.9-4.35-.68-.77.18-1.47.58-2.01 1.16-.59.62-.9 1.54-1.35 3.2l-.52 1.93c-.6 2.25-.91 3.38-.68 4.35.18.77.58 1.47 1.16 2.02.73.68 1.86.98 4.12 1.59 2.03.55 3.15.85 4.06.73.1-.01.2-.03.29-.05.77-.18 1.47-.58 2.01-1.16.68-.73.98-1.86 1.59-4.11Z" />
<path d="M16.42 17.97c-.21.64-.58 1.22-1.07 1.68-.73.68-1.86.98-4.12 1.59-2.25.6-3.38.9-4.35.67a4.5 4.5 0 0 1-2.01-1.16c-.68-.73-.98-1.86-1.59-4.11l-.52-1.93c-.6-2.25-.9-3.38-.68-4.35.18-.77.58-1.47 1.16-2.02.73-.68 1.86-.98 4.12-1.59.43-.11.81-.22 1.16-.31" />
<path d="m11.78 10 4.83 1.29M11 12.9l2.9.78" />
</>
),
},
{
title: "Changes & Cancellation",
description: "Manage amendments, extensions, cancellations and customer changes efficiently.",
icon: (
<>
<path d="M16 4c2.17.01 3.35.11 4.12.88.88.88.88 2.29.88 5.12v6c0 2.83 0 4.24-.88 5.12-.88.88-2.29.88-5.12.88H9c-2.83 0-4.24 0-5.12-.88C3 20.24 3 18.83 3 16v-6c0-2.83 0-4.24.88-5.12C4.65 4.11 5.82 4.01 8 4" />
<path d="M8 3.5A1.5 1.5 0 0 1 9.5 2h5A1.5 1.5 0 0 1 16 3.5v1A1.5 1.5 0 0 1 14.5 6h-5A1.5 1.5 0 0 1 8 4.5Z" />
<path d="M14.5 11 9.5 16M9.5 11l5 5" />
</>
),
},
];
const platform: Feature = {
title: "Enterprise Ticketing Platform",
description: "Manage high-volume ticketing, reservations, inventory and customer transactions from one centralized platform.",
icon: (
<>
<path d="M21.61 13.56 21.84 11.13c.18-1.91.27-2.87-.06-3.27a1.05 1.05 0 0 0-.68-.36c-.48-.04-1.07.63-2.27 1.99-.62.7-.93 1.06-1.28 1.11a.9.9 0 0 1-.57-.09c-.32-.16-.53-.6-.95-1.46L13.81 4.46C13.01 2.82 12.61 2 12 2s-1.01.82-1.81 2.46l-2.24 4.58c-.42.87-.63 1.3-.95 1.46-.18.09-.38.12-.57.09-.34-.05-.65-.41-1.27-1.11C3.97 8.13 3.37 7.45 2.9 7.5c-.26.02-.5.15-.68.36-.33.4-.23 1.36-.06 3.27l.23 2.43c.38 4.01.57 6.02 1.74 7.23S7.1 22 10.64 22h2.72c3.54 0 5.32 0 6.5-1.21s1.36-3.22 1.74-7.23Z" />
<path d="M9 18h6" />
</>
),
full: true,
};
function FeatureIcon({ children }: { children: ReactNode }) {
return (
<svg viewBox="0 0 24 24" fill="none" stroke="#0160d4" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" aria-hidden className="size-6 shrink-0">
{children}
</svg>
);
}
function FeatureCard({ f }: { f: Feature }) {
return (
<div
className={`group flex items-center gap-4 rounded-3xl bg-[#0160d4]/3 px-6 py-8 transition-all duration-300 hover:-translate-y-1 hover:bg-[#0160d4]/6 hover:shadow-lg ${f.full ? "sm:col-span-2" : ""}`}
>
<span className="transition-transform duration-300 group-hover:scale-110">
<FeatureIcon>{f.icon}</FeatureIcon>
</span>
<div>
<h3 className="text-xl font-bold text-foreground sm:text-2xl">{f.title}</h3>
<p className="mt-2 text-sm leading-relaxed text-foreground/70 sm:text-base">{f.description}</p>
</div>
</div>
);
}
export function TourBooking() {
return (
<section className="relative overflow-hidden py-20 lg:py-28">
<div className="mx-auto max-w-6xl px-4 sm:px-6">
<Reveal className="flex max-w-md flex-col gap-4">
<h2 className="text-4xl font-medium tracking-tight text-foreground sm:text-5xl">
Tour Booking &amp; Management Software
</h2>
<p className="max-w-md text-sm text-muted sm:text-base">
Voyager gives tour operators and activity businesses the tools to create, sell and manage virtually any
tourism product from one platform.
</p>
</Reveal>
<Reveal delay={100} className="mt-10 flex items-center justify-center rounded-2xl bg-accent/10 px-4 py-3 lg:mt-14">
<p className="text-center text-3xl font-medium text-foreground sm:text-4xl lg:text-5xl">
Sell <em className="font-normal text-accent italic">More</em>. Manage{" "}
<em className="font-normal text-accent italic">Less</em>.
</p>
</Reveal>
<div className="mt-6 grid gap-4 sm:grid-cols-2">
{features.map((f, i) => (
<Reveal key={f.title} delay={i * 90}>
<FeatureCard f={f} />
</Reveal>
))}
<Reveal delay={features.length * 90} className="sm:col-span-2">
<FeatureCard f={platform} />
</Reveal>
</div>
<Reveal delay={100} className="mt-10 flex flex-wrap items-center justify-center gap-4 lg:mt-14">
<p className="text-xl font-medium text-foreground sm:text-2xl">Now lets see</p>
<ButtonLink href="#tour-booking" size="lg">
Tour Booking Software
</ButtonLink>
</Reveal>
</div>
</section>
);
}