From 823ca68119b80d078cb376903e4a1400d4b8f806 Mon Sep 17 00:00:00 2001 From: Ichitux Date: Tue, 14 Apr 2026 15:48:44 +0200 Subject: [PATCH] Newer section and modular view --- src/components/FloatingButton.tsx | 3 +- src/components/HeroSection.tsx | 4 +- src/components/MixedBookingSection.tsx | 145 +++++++++++++++++++++++++ src/data/event-data.ts | 62 +++++++++-- src/locales/en.json | 25 +++++ src/locales/es.json | 25 +++++ src/pages/Index.tsx | 21 ++-- 7 files changed, 264 insertions(+), 21 deletions(-) create mode 100644 src/components/MixedBookingSection.tsx diff --git a/src/components/FloatingButton.tsx b/src/components/FloatingButton.tsx index 82f3631..0dbdd8f 100644 --- a/src/components/FloatingButton.tsx +++ b/src/components/FloatingButton.tsx @@ -3,6 +3,7 @@ import { motion, AnimatePresence } from "framer-motion"; import { useState, useEffect } from "react"; import { ChevronUp } from "lucide-react"; import { useTranslation } from "react-i18next"; +import { SECTIONS } from "@/data/event-data"; /** Botón flotante de reserva + scroll to top */ const FloatingButton = () => { @@ -30,7 +31,7 @@ const FloatingButton = () => { className="animate-pulse-glow rounded-full px-6 shadow-elevated" asChild > - + {/* Inline SVG: dancing couple icon */} { transition={{ delay: 1 }} > diff --git a/src/components/MixedBookingSection.tsx b/src/components/MixedBookingSection.tsx new file mode 100644 index 0000000..afa6e1f --- /dev/null +++ b/src/components/MixedBookingSection.tsx @@ -0,0 +1,145 @@ +import { useState } from "react"; +import { motion } from "framer-motion"; +import { MIXED_BOOKING_PACKAGES, ROOM_TYPES } from "@/data/event-data"; +import type { RoomType } from "@/data/event-data"; +import { useTranslation } from "react-i18next"; +import { Check, Star } from "lucide-react"; +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; +import { Label } from "@/components/ui/label"; + +const FEATURED_PASS = "full"; + +const MixedBookingSection = () => { + const { t } = useTranslation(); + const [selectedRooms, setSelectedRooms] = useState>({ + full: "individual", + party: "individual", + single: "individual", + }); + + return ( +
+
+ +

+ {t("mixedBooking.title")} +

+

{t("mixedBooking.subtitle")}

+
+ +
+ {MIXED_BOOKING_PACKAGES.map((pkg, i) => { + const selectedRoom = selectedRooms[pkg.id] || "individual"; + const price = pkg.roomPrices[selectedRoom]; + const isFeatured = pkg.id === FEATURED_PASS; + const features = t(`mixedBooking.${pkg.id}Features`).split("|").map((f: string) => f.trim()); + + return ( + + {isFeatured && ( +
+ + + {t("mixedBooking.popular")} + +
+ )} + +
+
+

+ {t(`mixedBooking.passTypes.${pkg.id}`)} +

+

+ {t(`mixedBooking.${pkg.id}Description`)} +

+
+
+ +
+

+ {price > 0 ? `${price}€` : t("mixedBooking.priceTBD")} +

+

+ {t("mixedBooking.perPerson")} +

+
+ +
+ + +
+ +
+
    + {features.map((feature: string, idx: number) => ( +
  • + + {feature} +
  • + ))} +
+
+
+ ); + })} +
+
+ + ); +}; + +export default MixedBookingSection; diff --git a/src/data/event-data.ts b/src/data/event-data.ts index 4d91fb7..fed05da 100644 --- a/src/data/event-data.ts +++ b/src/data/event-data.ts @@ -274,13 +274,57 @@ export const GALLERY_IMAGES = [ { src: "", alt: "[Descripción foto 6]" }, ]; -// ---- NAVEGACIÓN ---- -export const NAV_LINKS = [ - { href: "#about" }, - { href: "#staff" }, - { href: "#schedule" }, - { href: "#booking" }, - { href: "#hotel" }, - { href: "#info" }, - { href: "#gallery" }, +// ---- PAQUETES MIXTOS (Room + Pass) ---- +export type RoomType = "individual" | "double" | "suite"; +export type PassType = "full" | "party" | "single"; + +export const ROOM_TYPES: { id: RoomType }[] = [ + { id: "individual" }, + { id: "double" }, + { id: "suite" }, ]; + +export const MIXED_BOOKING_PACKAGES = [ + { id: "full" as PassType, label: "full", roomPrices: { individual: 0, double: 0, suite: 0 } }, + { id: "party" as PassType, label: "party", roomPrices: { individual: 0, double: 0, suite: 0 } }, + { id: "single" as PassType, label: "single", roomPrices: { individual: 0, double: 0, suite: 0 } }, +]; + +// ---- SECCIONES VISIBLES ---- +export const SECTIONS = { + about: true, + org: true, + staff: true, + profesores: true, + schedule: true, + booking: false, + mixed_booking: true, + hotel: true, + practical: true, + gallery: true, +}; + +// ---- NAVEGACIÓN ---- +const HREF_TO_SECTION: Record = { + "#about": "about", + "#staff": "staff", + "#schedule": "schedule", + "#booking": "booking", + "#mixed-booking": "mixed_booking", + "#hotel": "hotel", + "#info": "practical", + "#gallery": "gallery", +}; + +export const NAV_LINKS = ( + [ + { href: "#about" }, + { href: "#staff" }, + { href: "#schedule" }, + { href: "#booking" }, + { href: "#mixed-booking" }, + { href: "#hotel" }, + { href: "#info" }, + { href: "#gallery" }, + ] as const +).filter((link) => SECTIONS[HREF_TO_SECTION[link.href]]); diff --git a/src/locales/en.json b/src/locales/en.json index fd0b78e..7f4c72c 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -4,6 +4,7 @@ "staff": "Staff", "schedule": "Schedule", "booking": "Book your pass", + "mixed-booking": "Packs", "hotel": "Hotel", "info": "Info", "gallery": "Gallery" @@ -123,6 +124,30 @@ "description": "[Brief room description]", "bookButton": "Book at hotel" }, + "mixedBooking": { + "title": "Room + Pass Bundles", + "subtitle": "Room + Pass bundles for your stay.", + "priceTBD": "Price TBA", + "selectRoom": "Choose room type", + "popular": "Popular", + "perPerson": "/ person", + "roomTypes": { + "individual": "Single Room", + "double": "Double Room", + "suite": "Triple Room" + }, + "passTypes": { + "full": "Full Pass", + "party": "Party Pass", + "single": "Single Day Pass" + }, + "fullDescription": "Full access to all workshops, socials, and festival activities", + "fullFeatures": "All workshops|All social dances|Live shows|DJ sets", + "partyDescription": "Access to all parties (Friday, Saturday, and Sunday)", + "partyFeatures": "Friday party|Saturday party|Sunday farewell party|DJ sets", + "singleDescription": "Access to a single day of the festival", + "singleFeatures": "One day access|Workshops|Social dance|DJ set" + }, "info": { "title": "Practical Information", "airports": "Nearby Airports", diff --git a/src/locales/es.json b/src/locales/es.json index 1298c52..e58d802 100644 --- a/src/locales/es.json +++ b/src/locales/es.json @@ -4,6 +4,7 @@ "staff": "Staff", "schedule": "Programa", "booking": "Reservar", + "mixed-booking": "Packs", "hotel": "Hotel", "info": "Info", "gallery": "Galería" @@ -123,6 +124,30 @@ "description": "[Descripción breve de la habitación]", "bookButton": "Reservar en el hotel" }, + "mixedBooking": { + "title": "Packs de Habitación + Pase", + "subtitle": "Combina habitación + pase para tu estancia.", + "priceTBD": "Precio por confirmar", + "selectRoom": "Elige tipo de habitación", + "popular": "Popular", + "perPerson": "/ persona", + "roomTypes": { + "individual": "Habitación Individual", + "double": "Habitación Doble", + "suite": "Habitación Triple" + }, + "passTypes": { + "full": "Full Pass", + "party": "Party Pass", + "single": "Single Day Pass" + }, + "fullDescription": "Acceso completo a todos los workshops, sociales y actividades del festival", + "fullFeatures": "Todos los workshops|Todas las social dances|Shows en vivo|DJ sets", + "partyDescription": "Acceso a todas las fiestas (Viernes, Sábado y Domingo)", + "partyFeatures": "Fiesta del viernes|Fiesta del sábado|Fiesta despedida del domingo|DJ sets", + "singleDescription": "Acceso a un solo día del festival", + "singleFeatures": "Acceso un día|Workshops|Social dance|DJ set" + }, "info": { "title": "Información Práctica", "airports": "Aeropuertos Cercanos", diff --git a/src/pages/Index.tsx b/src/pages/Index.tsx index 7b39ee0..8cc2110 100644 --- a/src/pages/Index.tsx +++ b/src/pages/Index.tsx @@ -6,11 +6,13 @@ import StaffSection from "@/components/StaffSection"; import ProfesoresSection from "@/components/ProfesoresSection"; import ScheduleSection from "@/components/ScheduleSection"; import BookingSection from "@/components/BookingSection"; +import MixedBookingSection from "@/components/MixedBookingSection"; import HotelSection from "@/components/HotelSection"; import PracticalSection from "@/components/PracticalSection"; import GallerySection from "@/components/GallerySection"; import FooterSection from "@/components/FooterSection"; import FloatingButton from "@/components/FloatingButton"; +import { SECTIONS } from "@/data/event-data"; /** * Landing page — Lambada Festival Barcelona @@ -23,15 +25,16 @@ const Index = () => {
- - - - - - - - - + {SECTIONS.about && } + {SECTIONS.org && } + {SECTIONS.staff && } + {SECTIONS.profesores && } + {SECTIONS.schedule && } + {SECTIONS.booking && } + {SECTIONS.mixed_booking && } + {SECTIONS.hotel && } + {SECTIONS.practical && } + {SECTIONS.gallery && }