skyflytravel.hu/components/pricing-table.tsx

328 lines
19 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, Fragment } 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)
const [activeInfo, setActiveInfo] = useState<string | null>(null)
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-4 px-6", idx % 2 === 0 ? "bg-white" : "bg-slate-50/30")}>
<div className="flex items-center gap-2 text-slate-900 font-bold mb-3">
<div className="w-1.5 h-1.5 rounded-full bg-primary" />
<span className="text-base">{row.persons}</span>
</div>
<div className="grid grid-cols-2 gap-2 text-sm items-start">
<div className="text-center space-y-1">
<div className="text-[9px] uppercase tracking-[0.2em] text-slate-400">{t.pricing.table.express}</div>
<div className="font-extrabold text-blue-950 flex flex-col items-center gap-1.5">
<span className="text-lg leading-tight">{row.express}</span>
{idx === 0 && expressInfo && (
<button
type="button"
onClick={() => setActiveInfo(expressInfo)}
className="inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-[9px] font-black uppercase tracking-wider bg-primary/5 text-primary border border-primary/20 hover:bg-primary/10 transition-all active:scale-95"
>
<Info className="w-2.5 h-2.5" />
Infó
</button>
)}
</div>
</div>
<div className="text-center space-y-1">
<div className="text-[9px] uppercase tracking-[0.2em] text-slate-400">{t.pricing.table.private}</div>
<div className="flex flex-col items-center">
<div className="font-extrabold text-white px-3 py-1 bg-secondary rounded-full text-[11px] tracking-wider shadow-sm">
{row.private}
</div>
</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-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={`row-${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-5 px-4 text-center">
<div className="flex flex-col items-center justify-center gap-1">
<span className="font-extrabold text-blue-950">{row.express}</span>
{idx === 0 && expressInfo && (
<div className="mt-1">
<button
type="button"
onClick={() => setActiveInfo(expressInfo)}
className="inline-flex items-center gap-1 px-2.5 py-0.5 rounded-full text-[10px] font-black uppercase tracking-wider bg-primary/5 text-primary border border-primary/20 hover:bg-primary/10 transition-colors"
>
<Info className="w-3 h-3" />
Infó
</button>
</div>
)}
</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>
)}
{/* Luxury Popover - Redesigned to be beautiful and dynamic */}
{
activeInfo && (
<div className="fixed inset-0 z-[100] flex items-center justify-center p-6 animate-in fade-in duration-300">
{/* Backdrop with premium silk blur */}
<div
className="absolute inset-0 bg-slate-950/60 backdrop-blur-md"
onClick={() => setActiveInfo(null)}
/>
{/* Popover Card */}
<div className="relative w-full max-w-md bg-white rounded-[2.5rem] shadow-[0_25px_70px_rgba(0,0,0,0.4)] border border-white/20 overflow-hidden animate-in zoom-in-95 slide-in-from-bottom-5 duration-300">
{/* Decorative Header */}
<div className="bg-slate-900 px-8 py-6 flex items-center justify-between">
<div className="flex items-center gap-3">
<div className="w-10 h-10 bg-primary/20 rounded-xl flex items-center justify-center">
<Info className="w-5 h-5 text-primary" />
</div>
<span className="font-black uppercase tracking-[0.2em] text-[11px] text-white">Információ</span>
</div>
<button
onClick={() => setActiveInfo(null)}
className="w-8 h-8 rounded-full bg-white/5 flex items-center justify-center text-white/40 hover:text-white hover:bg-white/10 transition-all"
>
<svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
</div>
{/* Content Area */}
<div className="px-10 py-12 text-center">
<p className="text-slate-600 text-lg leading-relaxed font-medium">
{activeInfo}
</p>
</div>
{/* Footer Button */}
<div className="px-8 pb-8">
<button
type="button"
onClick={() => setActiveInfo(null)}
className="w-full rounded-2xl bg-slate-900 py-5 text-sm font-black uppercase tracking-[0.2em] text-white shadow-xl shadow-slate-950/20 hover:bg-slate-800 transition-all active:scale-[0.98]"
>
Értem
</button>
</div>
</div>
</div>
)
}
</div>
)
}
export default PricingTable