galery fix and translation

This commit is contained in:
Bognar 2026-03-13 20:45:05 +01:00
parent bcbd06292f
commit 6ab460931c
4 changed files with 75 additions and 51 deletions

View File

@ -88,10 +88,10 @@ export default function OtherTransportPage() {
<div className="space-y-6"> <div className="space-y-6">
<div className="inline-flex items-center gap-2 px-4 py-2 rounded-full bg-primary/10 text-primary"> <div className="inline-flex items-center gap-2 px-4 py-2 rounded-full bg-primary/10 text-primary">
<Sparkles className="w-4 h-4" /> <Sparkles className="w-4 h-4" />
<span className="text-[10px] font-black uppercase tracking-[0.2em]">Egyedi Megoldások</span> <span className="text-[10px] font-black uppercase tracking-[0.2em]">{t.otherTransportPage.badge}</span>
</div> </div>
<h2 className="text-3xl md:text-4xl font-black uppercase tracking-tighter text-slate-900 leading-tight"> <h2 className="text-3xl md:text-4xl font-black uppercase tracking-tighter text-slate-900 leading-tight">
Minden igényre <span className="text-primary">van megoldásunk</span> {t.otherTransportPage.titlePart1} <span className="text-primary">{t.otherTransportPage.titleAccentPart}</span>
</h2> </h2>
<p className="text-slate-600 text-lg leading-relaxed font-medium"> <p className="text-slate-600 text-lg leading-relaxed font-medium">
{t.otherTransportPage.mainContent} {t.otherTransportPage.mainContent}
@ -148,18 +148,12 @@ export default function OtherTransportPage() {
{t.otherTransportPage.capacityDesc} {t.otherTransportPage.capacityDesc}
</p> </p>
<div className="space-y-4"> <div className="space-y-4">
<div className="flex items-start gap-3"> {t.otherTransportPage.capacityList.map((item: string, idx: number) => (
<CheckCircle2 className="w-4 h-4 text-primary mt-1" /> <div key={idx} className="flex items-start gap-3">
<span className="text-slate-200 text-sm font-medium">Több kisbusz egyszerre</span> <CheckCircle2 className="w-4 h-4 text-primary mt-1" />
</div> <span className="text-slate-200 text-sm font-medium">{item}</span>
<div className="flex items-start gap-3"> </div>
<CheckCircle2 className="w-4 h-4 text-primary mt-1" /> ))}
<span className="text-slate-200 text-sm font-medium">Buszpartner szoros együttműködésben</span>
</div>
<div className="flex items-start gap-3">
<CheckCircle2 className="w-4 h-4 text-primary mt-1" />
<span className="text-slate-200 text-sm font-medium">Logisztikai tervezés nagy létszámhoz</span>
</div>
</div> </div>
</div> </div>
</Card> </Card>
@ -167,9 +161,9 @@ export default function OtherTransportPage() {
{/* Contact Card */} {/* Contact Card */}
<Card className="rounded-[3rem] border-none shadow-2xl bg-white overflow-hidden p-8 space-y-8"> <Card className="rounded-[3rem] border-none shadow-2xl bg-white overflow-hidden p-8 space-y-8">
<div className="space-y-2"> <div className="space-y-2">
<p className="text-[10px] font-black uppercase tracking-[0.3em] text-primary">Kapcsolatfelvétel</p> <p className="text-[10px] font-black uppercase tracking-[0.3em] text-primary">{t.otherTransportPage.contactSubtitle}</p>
<h3 className="text-2xl font-black uppercase tracking-tight text-slate-900"> <h3 className="text-2xl font-black uppercase tracking-tight text-slate-900">
Kérjen egyedi ajánlatot {t.otherTransportPage.cta}
</h3> </h3>
</div> </div>
<div className="space-y-4"> <div className="space-y-4">
@ -180,7 +174,7 @@ export default function OtherTransportPage() {
</Button> </Button>
<div className="flex items-center justify-center gap-4 py-4"> <div className="flex items-center justify-center gap-4 py-4">
<div className="h-px bg-slate-100 flex-grow" /> <div className="h-px bg-slate-100 flex-grow" />
<span className="text-[10px] font-black text-slate-300 uppercase tracking-widest">vagy hívjon minket</span> <span className="text-[10px] font-black text-slate-300 uppercase tracking-widest">{t.otherTransportPage.phoneAlt}</span>
<div className="h-px bg-slate-100 flex-grow" /> <div className="h-px bg-slate-100 flex-grow" />
</div> </div>
<a href={`tel:${t.common.phoneHref}`} className="flex items-center gap-4 p-5 rounded-[2rem] bg-slate-50 hover:bg-slate-100 transition-colors border border-slate-100 group"> <a href={`tel:${t.common.phoneHref}`} className="flex items-center gap-4 p-5 rounded-[2rem] bg-slate-50 hover:bg-slate-100 transition-colors border border-slate-100 group">
@ -199,9 +193,9 @@ export default function OtherTransportPage() {
<div className="rounded-[3rem] bg-gradient-to-br from-primary to-secondary p-[1px]"> <div className="rounded-[3rem] bg-gradient-to-br from-primary to-secondary p-[1px]">
<div className="bg-white rounded-[2.9rem] p-8 space-y-4"> <div className="bg-white rounded-[2.9rem] p-8 space-y-4">
<Shield className="w-10 h-10 text-primary" /> <Shield className="w-10 h-10 text-primary" />
<h4 className="text-xl font-black uppercase tracking-tight text-slate-900">Garantált minőség</h4> <h4 className="text-xl font-black uppercase tracking-tight text-slate-900">{t.otherTransportPage.qualityTitle}</h4>
<p className="text-slate-500 text-sm font-medium leading-relaxed"> <p className="text-slate-500 text-sm font-medium leading-relaxed">
Több mint 10 év tapasztalatával garantáljuk a pontosságot és a prémium szolgáltatást minden egyedi megrendelés esetén is. {t.otherTransportPage.qualityDesc}
</p> </p>
</div> </div>
</div> </div>

View File

@ -18,6 +18,7 @@ export default function FleetPage() {
const [isGalleryOpen, setIsGalleryOpen] = useState(false) const [isGalleryOpen, setIsGalleryOpen] = useState(false)
const [selectedGallery, setSelectedGallery] = useState<string[]>([]) const [selectedGallery, setSelectedGallery] = useState<string[]>([])
const [selectedVehicleName, setSelectedVehicleName] = useState("") const [selectedVehicleName, setSelectedVehicleName] = useState("")
const [selectedCategoryName, setSelectedCategoryName] = useState("")
useEffect(() => { useEffect(() => {
fetch('/gallery.json') fetch('/gallery.json')
@ -26,11 +27,12 @@ export default function FleetPage() {
.catch(err => console.error('Error fetching gallery:', err)) .catch(err => console.error('Error fetching gallery:', err))
}, []) }, [])
const openGallery = (categoryId: string, vehicleName: string) => { const openGallery = (categoryId: string, vehicleName: string, categoryName: string) => {
const images = galleryData[categoryId] || [] const images = galleryData[categoryId] || []
if (images.length > 0) { if (images.length > 0) {
setSelectedGallery(images) setSelectedGallery(images)
setSelectedVehicleName(vehicleName) setSelectedVehicleName(vehicleName)
setSelectedCategoryName(categoryName)
setIsGalleryOpen(true) setIsGalleryOpen(true)
} }
} }
@ -141,38 +143,39 @@ export default function FleetPage() {
variants={itemVariants} variants={itemVariants}
className={vehicle.large ? "md:col-span-2" : "md:col-span-1"} className={vehicle.large ? "md:col-span-2" : "md:col-span-1"}
> >
<Card className="group relative overflow-hidden rounded-[3.5rem] border-none bg-white shadow-[0_32px_64px_-16px_rgba(0,0,0,0.08)] transition-all duration-700 hover:shadow-[0_48px_80px_-20px_rgba(0,0,0,0.12)] aspect-[16/9] md:aspect-auto md:h-[700px]"> <Card className="group relative overflow-hidden rounded-[2.5rem] md:rounded-[3.5rem] border-none bg-white shadow-[0_32px_64px_-16px_rgba(0,0,0,0.08)] transition-all duration-700 hover:shadow-[0_48px_80px_-20px_rgba(0,0,0,0.12)] flex flex-col md:block md:h-[700px]">
{/* Image with refined hover scaling */} {/* Image container */}
<Image <div className="relative h-[280px] md:absolute md:inset-0 md:h-full overflow-hidden">
src={vehicle.image} <Image
alt={vehicle.data.name} src={vehicle.image}
fill alt={vehicle.data.name}
className="object-cover transition-transform duration-[1.5s] ease-out group-hover:scale-110" fill
/> className="object-cover transition-transform duration-[1.5s] ease-out md:group-hover:scale-110"
/>
{/* Desktop-only gradient */}
<div className="hidden md:block absolute inset-0 bg-gradient-to-t from-black/80 via-black/20 to-transparent opacity-80" />
</div>
{/* Darker bottom gradient for text readability */} {/* Content - Overlay on desktop, below on mobile */}
<div className="absolute inset-0 bg-gradient-to-t from-black/80 via-black/20 to-transparent opacity-80 transition-opacity duration-700 group-hover:opacity-90" /> <div className="relative md:absolute md:inset-0 p-8 md:p-16 flex flex-col justify-end bg-white md:bg-transparent">
<div className="space-y-6 transform transition-all duration-700 md:group-hover:-translate-y-2">
{/* Content Details - Overlay style without box */}
<div className="absolute inset-0 p-10 md:p-16 flex flex-col justify-end">
<div className="space-y-6 transform transition-all duration-700 group-hover:-translate-y-2">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<span className="px-5 py-2 rounded-full bg-primary text-white text-[9px] font-black uppercase tracking-[0.2em] shadow-xl"> <span className="px-5 py-2 rounded-full bg-primary text-white text-[9px] font-black uppercase tracking-[0.2em] shadow-xl">
{vehicle.data.category} {vehicle.data.category}
</span> </span>
</div> </div>
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<div className="w-2 h-2 rounded-full bg-green-500 animate-pulse" /> <div className="w-2 h-2 rounded-full bg-green-500 animate-pulse" />
<span className="text-[9px] font-black text-white/60 uppercase tracking-[0.3em]">{t.fleetPage.availabilityLabel}</span> <span className="text-[9px] font-black text-slate-400 md:text-white/60 uppercase tracking-[0.3em]">{t.fleetPage.availabilityLabel}</span>
</div> </div>
</div> </div>
<div className="space-y-4"> <div className="space-y-4">
<h3 className="text-4xl md:text-7xl font-black uppercase tracking-tighter text-white leading-tight"> <h3 className="text-3xl md:text-7xl font-black uppercase tracking-tighter text-slate-900 md:text-white leading-tight">
{vehicle.data.name} {vehicle.data.name}
</h3> </h3>
<p className="text-white/70 max-w-2xl text-base md:text-lg font-medium leading-relaxed"> <p className="text-slate-500 md:text-white/70 max-w-2xl text-base md:text-lg font-medium leading-relaxed">
{vehicle.data.description} {vehicle.data.description}
</p> </p>
</div> </div>
@ -180,7 +183,7 @@ export default function FleetPage() {
{vehicle.data.features && vehicle.data.features.length > 0 && ( {vehicle.data.features && vehicle.data.features.length > 0 && (
<div className="flex flex-wrap gap-x-8 gap-y-4 pt-4"> <div className="flex flex-wrap gap-x-8 gap-y-4 pt-4">
{vehicle.data.features.map((feature: string, fIdx: number) => ( {vehicle.data.features.map((feature: string, fIdx: number) => (
<div key={fIdx} className="flex items-center gap-3 text-white/80"> <div key={fIdx} className="flex items-center gap-3 text-slate-500 md:text-white/80">
<div className="w-1.5 h-1.5 rounded-full bg-primary" /> <div className="w-1.5 h-1.5 rounded-full bg-primary" />
<span className="text-[10px] md:text-xs font-black uppercase tracking-widest">{feature}</span> <span className="text-[10px] md:text-xs font-black uppercase tracking-widest">{feature}</span>
</div> </div>
@ -188,10 +191,10 @@ export default function FleetPage() {
</div> </div>
)} )}
<div className="pt-8 border-t border-white/10 flex items-center justify-between"> <div className="pt-8 border-t border-slate-100 md:border-white/10 flex items-center justify-between">
<div className="flex flex-wrap gap-6 items-center"> <div className="flex flex-wrap gap-6 items-center">
<button <button
onClick={() => openGallery(vehicle.categoryId, vehicle.data.name)} onClick={() => openGallery(vehicle.categoryId, vehicle.data.name, t.fleetPage.categories[vehicle.categoryId as keyof typeof t.fleetPage.categories])}
className="inline-flex items-center gap-4 text-primary font-black uppercase tracking-[0.2em] text-[10px] hover:gap-6 transition-all cursor-pointer group/btn" className="inline-flex items-center gap-4 text-primary font-black uppercase tracking-[0.2em] text-[10px] hover:gap-6 transition-all cursor-pointer group/btn"
> >
{t.common.moreImages} {t.common.moreImages}
@ -251,6 +254,7 @@ export default function FleetPage() {
onClose={() => setIsGalleryOpen(false)} onClose={() => setIsGalleryOpen(false)}
images={selectedGallery} images={selectedGallery}
vehicleName={selectedVehicleName} vehicleName={selectedVehicleName}
categoryName={selectedCategoryName}
/> />
<Footer /> <Footer />

View File

@ -11,9 +11,10 @@ interface GalleryDialogProps {
onClose: () => void; onClose: () => void;
images: string[]; images: string[];
vehicleName: string; vehicleName: string;
categoryName: string;
} }
export function GalleryDialog({ isOpen, onClose, images, vehicleName }: GalleryDialogProps) { export function GalleryDialog({ isOpen, onClose, images, vehicleName, categoryName }: GalleryDialogProps) {
const [currentIndex, setCurrentIndex] = useState(0); const [currentIndex, setCurrentIndex] = useState(0);
const [direction, setDirection] = useState(0); const [direction, setDirection] = useState(0);
@ -79,9 +80,10 @@ export function GalleryDialog({ isOpen, onClose, images, vehicleName }: GalleryD
</button> </button>
{/* Header Info */} {/* Header Info */}
<div className="absolute top-8 left-8 z-[110] flex flex-col gap-2"> <div className="absolute top-8 left-8 z-[110] flex flex-col gap-2 pr-20">
<h3 className="text-2xl font-black uppercase tracking-[0.3em] text-white"> <h3 className="text-lg lg:text-2xl font-black uppercase tracking-[0.15em] lg:tracking-[0.3em] text-white leading-tight">
{vehicleName} <span className="lg:hidden block">{categoryName}</span>
<span className="hidden lg:block">{vehicleName}</span>
</h3> </h3>
<div className="flex items-center gap-4 text-primary text-[10px] font-black tracking-widest uppercase"> <div className="flex items-center gap-4 text-primary text-[10px] font-black tracking-widest uppercase">
<ImageIcon className="w-4 h-4" /> <ImageIcon className="w-4 h-4" />

View File

@ -1,4 +1,4 @@
export const translations = { export const translations = {
hu: { hu: {
common: { common: {
brand: "SkyFly Travel", brand: "SkyFly Travel",
@ -601,10 +601,13 @@
description: "Egyéni és csoportos személyszállítás: kirándulások, esküvők, céges rendezvények, munkásjáratok. Rugalmas megoldások, modern flotta." description: "Egyéni és csoportos személyszállítás: kirándulások, esküvők, céges rendezvények, munkásjáratok. Rugalmas megoldások, modern flotta."
}, },
back: "Vissza a kezdőlapra", back: "Vissza a kezdőlapra",
badge: "Egyedi Megoldások",
title: "Egyéb", title: "Egyéb",
titleAccent: "személyszállítás", titleAccent: "személyszállítás",
titlePart1: "Minden igényre",
titleAccentPart: "van megoldásunk",
heroDescription: "Egyedi igényekhez szabott, rugalmas személyszállítási megoldások. Legyen szó családi eseményről, céges rendezvényről vagy rendszeres munkásjáratról, ránk számíthat.", heroDescription: "Egyedi igényekhez szabott, rugalmas személyszállítási megoldások. Legyen szó családi eseményről, céges rendezvényről vagy rendszeres munkásjáratról, ránk számíthat.",
mainContent: "Egyéb személyszállítás alatt értjük azokat az utaztatásokat, melyek során a megrendelő egyedi igényeinek megfelelően teljesítjük a személyszállítást. Például: kirándulások (akár több napos külföldi kirándulás), esküvők (esküvői autó és vendégek szállítása kisbuszokkal), céges rendezvények, konferenciák, munkásjáratok. Nagyobb létszám esetén több kisbusz rendelhető egyidőre vagy nagy buszos partnerünk szolgáltatása is választható.", mainContent: "Egyéb személyszállítás alatt értjük azokat az utaztatásokat, melyek során a megrendelő egyedi igényeinek megfelelően teljesítjük a személyszallítást. Például: kirándulások (akár több napos külföldi kirándulás), esküvők (esküvői autó és vendégek szállítása kisbuszokkal), céges rendezvények, konferenciák, munkásjáratok. Nagyobb létszám esetén több kisbusz rendelhető egyidőre vagy nagy buszos partnerünk szolgáltatása is választható.",
services: [ services: [
{ {
title: "Kirándulások", title: "Kirándulások",
@ -625,7 +628,16 @@
], ],
capacityTitle: "Rugalmas létszám", capacityTitle: "Rugalmas létszám",
capacityDesc: "Flottánk és partnerhálózatunk lehetővé teszi, hogy a kisebb csoportoktól a több száz fős rendezvényekig mindenre megoldást nyújtsunk. Több kisbusz vagy akár nagy buszos partnerünk bevonásával garantáljuk a zökkenőmentes szállítást.", capacityDesc: "Flottánk és partnerhálózatunk lehetővé teszi, hogy a kisebb csoportoktól a több száz fős rendezvényekig mindenre megoldást nyújtsunk. Több kisbusz vagy akár nagy buszos partnerünk bevonásával garantáljuk a zökkenőmentes szállítást.",
cta: "Kérjen egyedi ajánlatot" capacityList: [
"Több kisbusz egyszerre",
"Buszpartner szoros együttműködésben",
"Logisztikai tervezés nagy létszámhoz"
],
contactSubtitle: "Kapcsolatfelvétel",
cta: "Kérjen egyedi ajánlatot",
phoneAlt: "vagy hívjon minket",
qualityTitle: "Garantált minőség",
qualityDesc: "Több mint 10 év tapasztalatával garantáljuk a pontosságot és a prémium szolgáltatást minden egyedi megrendelés esetén is."
}, },
footer: { footer: {
ready: "Készen áll az indulásra?", ready: "Készen áll az indulásra?",
@ -1243,8 +1255,11 @@
description: "Individual and group passenger transport: trips, weddings, corporate events, work shuttles. Flexible solutions, modern fleet." description: "Individual and group passenger transport: trips, weddings, corporate events, work shuttles. Flexible solutions, modern fleet."
}, },
back: "Back to home", back: "Back to home",
badge: "Unique Solutions",
title: "Other", title: "Other",
titleAccent: "transport", titleAccent: "transport",
titlePart1: "We have a solution",
titleAccentPart: "for every need",
heroDescription: "Flexible transport solutions tailored to your unique needs. Whether it's a family event, corporate gathering, or regular staff commute, you can count on us.", heroDescription: "Flexible transport solutions tailored to your unique needs. Whether it's a family event, corporate gathering, or regular staff commute, you can count on us.",
mainContent: "By other personal transport, we mean trips where we fulfill the transport according to the customer's unique needs. For example: excursions (even multi-day trips abroad), weddings (wedding car and guest transport by minibuses), corporate events, conferences, work shuttles. For larger groups, several minibuses can be ordered at once, or our large bus partner's service can also be chosen.", mainContent: "By other personal transport, we mean trips where we fulfill the transport according to the customer's unique needs. For example: excursions (even multi-day trips abroad), weddings (wedding car and guest transport by minibuses), corporate events, conferences, work shuttles. For larger groups, several minibuses can be ordered at once, or our large bus partner's service can also be chosen.",
services: [ services: [
@ -1267,7 +1282,16 @@
], ],
capacityTitle: "Flexible Capacity", capacityTitle: "Flexible Capacity",
capacityDesc: "Our fleet and partner network allow us to provide solutions for everything from small groups to events with hundreds of people. With multiple minibuses or by involving our large bus partner, we guarantee smooth transport.", capacityDesc: "Our fleet and partner network allow us to provide solutions for everything from small groups to events with hundreds of people. With multiple minibuses or by involving our large bus partner, we guarantee smooth transport.",
cta: "Request a unique quote" capacityList: [
"Multiple minibuses at once",
"Bus partner in close cooperation",
"Logistics planning for large groups"
],
contactSubtitle: "Get in Touch",
cta: "Request a unique quote",
phoneAlt: "or call us",
qualityTitle: "Guaranteed Quality",
qualityDesc: "With more than 10 years of experience, we guarantee punctuality and premium service even for every unique order."
}, },
footer: { footer: {
ready: "Ready to go?", ready: "Ready to go?",