skyflytravel.hu/components/pricing-table.tsx

277 lines
16 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client"
import { cn } from "@/lib/utils"
import { Info, Tag, Check, Shield, CircleHelp } from "lucide-react"
import { useLanguage } from "@/lib/language-context"
import { useState } from "react"
interface PricingRow {
persons: string
express: string
private: string
classic?: string
}
interface SpecialPackage {
name: string
price: string
description: string
}
interface PricingTableProps {
route: string
rows: PricingRow[]
specials?: SpecialPackage[]
vipInfo?: string[]
effectiveFrom?: string
expressInfo?: string
districtSurcharge?: {
label: string
title: string
description: string
items: string[]
closeLabel: string
}
}
const PricingTable = ({
route,
rows,
specials,
vipInfo,
effectiveFrom,
expressInfo,
districtSurcharge
}: PricingTableProps) => {
const { t } = useLanguage()
const [isSurchargeOpen, setIsSurchargeOpen] = useState(false)
return (
<div className="w-full space-y-8 mb-24">
{/* Route Header matching FeatureSection style */}
<div className="space-y-2 mb-8">
<h3 className="text-5xl md:text-7xl font-black uppercase tracking-tighter opacity-10 text-primary">
{route.includes("POZSONY") || route.includes("BRATISLAVA")
? "BRATISLAVA"
: (route.includes("BÉCS") || route.includes("VIENNA"))
? "VIENNA"
: "BUDAPEST"}
</h3>
<h2 className="text-2xl md:text-3xl font-black tracking-tight -mt-8 md:-mt-10 ml-1 text-slate-900 max-w-2xl uppercase">
{route}
</h2>
{districtSurcharge && (
<button
type="button"
onClick={() => setIsSurchargeOpen(true)}
className="inline-flex items-center gap-2 rounded-full border border-secondary/40 bg-secondary/10 px-4 py-2 text-[11px] font-black uppercase tracking-[0.25em] text-secondary transition-colors hover:border-secondary hover:bg-secondary/20"
>
<CircleHelp className="h-4 w-4" />
{districtSurcharge.label}
</button>
)}
</div>
<div className="bg-white rounded-[2.5rem] shadow-xl border border-slate-100 overflow-hidden">
{/* Mobile cards */}
<div className="block md:hidden divide-y divide-slate-100">
{rows.map((row, idx) => (
<div key={idx} className={cn("p-5", idx % 2 === 0 ? "bg-white" : "bg-slate-50/30")}>
<div className="flex items-center gap-3 text-slate-900 font-bold mb-4">
<div className="w-1.5 h-1.5 rounded-full bg-primary" />
<span>{row.persons}</span>
</div>
<div className="grid grid-cols-2 gap-4 text-sm">
<div className="text-center">
<div className="text-[10px] uppercase tracking-[0.2em] text-slate-400 mb-2">{t.pricing.table.express}</div>
<div className="font-extrabold text-blue-950 flex items-center justify-center gap-2">
<span>{row.express}</span>
{idx === 0 && expressInfo && (
<span className="relative inline-flex items-center group">
<Info className="w-3 h-3 text-slate-300 hover:text-primary cursor-help transition-colors" />
<span className="pointer-events-none absolute bottom-full left-1/2 z-10 mb-2 w-64 -translate-x-1/2 rounded-lg bg-slate-900 px-3 py-2 text-[11px] font-medium text-white opacity-0 shadow-lg transition-opacity duration-150 group-hover:opacity-100">
{expressInfo}
</span>
</span>
)}
</div>
</div>
<div className="text-center">
<div className="text-[10px] uppercase tracking-[0.2em] text-slate-400 mb-2">{t.pricing.table.private}</div>
<div className="font-extrabold text-white px-4 py-1.5 bg-secondary rounded-full text-xs tracking-wider shadow-sm inline-block">
{row.private}
</div>
</div>
</div>
</div>
))}
</div>
{/* Desktop table */}
<div className="hidden md:block overflow-x-auto">
<table className="w-full text-left border-collapse">
<thead>
<tr className="bg-slate-50/50 text-slate-500 text-[10px] uppercase tracking-[0.2em] border-b border-slate-100">
<th className="py-6 px-4 md:py-8 md:px-10 font-bold whitespace-nowrap">{t.pricing.table.passengers}</th>
<th className="py-6 px-2 md:py-8 md:px-4 font-bold text-center">
<div className="flex flex-col items-center gap-1 opacity-40">
<span className="text-slate-400">{t.pricing.table.classic}</span>
<span className="text-[10px] lowercase normal-case tracking-normal">{t.pricing.table.classicNote}</span>
</div>
</th>
<th className="py-8 px-4 font-bold text-center">
<div className="flex items-center justify-center gap-2">
<span className="text-primary font-black">{t.pricing.table.express}</span>
<div className="bg-primary/10 p-1 rounded-md">
<Tag className="w-3 h-3 text-primary" />
</div>
</div>
</th>
<th className="py-8 px-10 font-bold text-center">
<div className="flex items-center justify-center gap-2">
<span className="text-secondary font-black">{t.pricing.table.private}</span>
<div className="bg-secondary/10 p-1 rounded-md">
<Shield className="w-3 h-3 text-secondary" />
</div>
</div>
</th>
</tr>
</thead>
<tbody className="text-slate-700">
{rows.map((row, idx) => (
<tr
key={idx}
className={cn(
"border-b border-slate-50 transition-colors hover:bg-slate-50/80",
idx % 2 === 0 ? "bg-white" : "bg-slate-50/20"
)}
>
<td className="py-4 px-4 md:py-5 md:px-10 font-bold text-slate-900 whitespace-nowrap">
<div className="flex items-center gap-3">
<div className="w-1.5 h-1.5 rounded-full bg-primary" />
{row.persons}
</div>
</td>
<td className="py-4 px-2 md:py-5 md:px-4 text-center text-slate-300">
<span className="text-xs"></span>
</td>
<td className="py-5 px-4 text-center">
<div className="flex items-center justify-center gap-2">
<span className="font-extrabold text-blue-950">{row.express}</span>
{idx === 0 && expressInfo && (
<span className="relative inline-flex items-center group">
<Info className="w-3 h-3 text-slate-300 hover:text-primary cursor-help transition-colors" />
<span className="pointer-events-none absolute bottom-full left-1/2 z-10 mb-2 w-64 -translate-x-1/2 rounded-lg bg-slate-900 px-3 py-2 text-[11px] font-medium text-white opacity-0 shadow-lg transition-opacity duration-150 group-hover:opacity-100">
{expressInfo}
</span>
</span>
)}
</div>
</td>
<td className="py-5 px-10 text-center">
<span className="font-extrabold text-white px-5 py-1.5 bg-secondary rounded-full text-xs tracking-wider shadow-sm">
{row.private}
</span>
</td>
</tr>
))}
</tbody>
</table>
</div>
{specials && specials.length > 0 && (
<div className="bg-gradient-to-r from-slate-950 to-slate-900 text-white p-10 space-y-8">
<div className="grid grid-cols-1 lg:grid-cols-2 gap-10">
{specials.map((special, idx) => (
<div key={idx} className="space-y-3 group">
<div className="flex items-center gap-4">
<div className="bg-primary p-2 rounded-xl group-hover:scale-110 transition-transform duration-300 shadow-lg shadow-primary/20">
<Check className="w-4 h-4 text-white" />
</div>
<span className="font-black text-xl text-white group-hover:text-primary transition-colors tracking-tight">
{special.name} {special.price}
</span>
</div>
<p className="text-slate-400 text-sm leading-relaxed pl-12 font-medium">
{special.description}
</p>
</div>
))}
</div>
{(vipInfo && vipInfo.length > 0) && (
<div className="pt-8 border-t border-white/5">
<h4 className="text-[10px] uppercase tracking-[0.3em] text-primary font-black mb-6">{t.pricing.table.premium}</h4>
<div className="flex flex-wrap gap-x-12 gap-y-4">
{vipInfo.map((info, idx) => (
<div key={idx} className="flex items-center gap-3 text-sm text-slate-300 font-bold italic">
<div className="w-2 h-2 rounded-full bg-primary shadow-[0_0_10px_rgba(217,163,33,0.5)]" />
{info}
</div>
))}
</div>
</div>
)}
</div>
)}
</div>
{effectiveFrom && (
<div className="text-right text-slate-400 text-[10px] uppercase tracking-[0.2em] font-black">
{effectiveFrom}
</div>
)}
{districtSurcharge && isSurchargeOpen && (
<div className="fixed inset-0 z-50 flex items-center justify-center bg-slate-950/70 px-4">
<div className="w-full max-w-2xl overflow-hidden rounded-[2rem] border border-slate-800/80 bg-slate-900 text-white shadow-[0_30px_80px_rgba(15,23,42,0.6)]">
<div className="relative px-8 py-6">
<div className="absolute inset-0 bg-gradient-to-br from-slate-900 via-slate-900 to-slate-800 opacity-90" />
<div className="relative flex items-center justify-between">
<div>
<p className="text-[10px] uppercase tracking-[0.35em] text-secondary/80">
{districtSurcharge.label}
</p>
<h4 className="text-lg font-black uppercase tracking-tight text-white">
{districtSurcharge.title}
</h4>
</div>
<button
type="button"
onClick={() => setIsSurchargeOpen(false)}
className="h-9 w-9 rounded-full border border-white/10 bg-white/5 text-white/70 transition-colors hover:bg-white/10 hover:text-white"
aria-label={districtSurcharge.closeLabel}
>
×
</button>
</div>
</div>
<div className="space-y-5 px-8 pb-8 pt-2 text-sm text-white/85">
<p className="leading-relaxed">{districtSurcharge.description}</p>
<div className="space-y-3">
{districtSurcharge.items.map((item, idx) => (
<div key={idx} className="flex items-start gap-3 rounded-xl border border-white/5 bg-white/5 px-4 py-3">
<span className="mt-0.5 h-2 w-2 flex-shrink-0 rounded-full bg-secondary shadow-[0_0_10px_rgba(217,163,33,0.6)]" />
<span className="font-semibold text-white/90">{item}</span>
</div>
))}
</div>
<div className="flex justify-end pt-2">
<button
type="button"
onClick={() => setIsSurchargeOpen(false)}
className="rounded-full bg-secondary px-6 py-2 text-[11px] font-black uppercase tracking-[0.25em] text-white hover:bg-secondary/90"
>
{districtSurcharge.closeLabel}
</button>
</div>
</div>
</div>
</div>
)}
</div>
)
}
export default PricingTable