Calendar & Assistants
CI/CD Deploy / test (push) Successful in 1m2s
CI/CD Deploy / build-push (push) Successful in 1m34s
CI/CD Deploy / deploy (push) Successful in 15s

This commit is contained in:
Antoni Nuñez Romeu
2026-08-25 14:23:05 +02:00
parent 6f2027610f
commit c799cdda00
5 changed files with 91 additions and 74 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 190 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 352 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 297 KiB

+36 -53
View File
@@ -1,8 +1,6 @@
import { motion } from "framer-motion";
import { useState, useEffect } from "react";
import { SCHEDULE, EVENT_INFO } from "@/data/event-data";
import { SCHEDULE } from "@/data/event-data";
import { Clock, Music, Coffee, Star } from "lucide-react";
import { getTimeLeft } from "@/components/HeroSection";
import { useTranslation } from "react-i18next";
const typeIcon: Record<string, typeof Clock> = {
@@ -19,60 +17,22 @@ const typeColor: Record<string, string> = {
show: "border-accent bg-accent/10 text-accent",
};
type ScheduleEvent = {
time: string;
title: string;
type: string;
parallel?: ScheduleEvent[];
};
const ScheduleSection = () => {
const { t } = useTranslation();
const [timeLeft, setTimeLeft] = useState(getTimeLeft(EVENT_INFO.date));
const isEventOngoing = timeLeft.days === 0 && timeLeft.hours === 0 && timeLeft.minutes === 0 && timeLeft.seconds === 0;
const dayKeys = ["friday", "saturday", "sunday"] as const;
const formatEventTitle = (event: { type: string; title: string }, dayIndex: number) => {
switch (event.type) {
case "workshop": {
const match = event.title.match(/Workshop\\s*(\\d+)/i);
return match?.[1] ? `${t("schedule.workshop")} ${match[1]}` : t("schedule.workshop");
}
case "break":
return t("schedule.break");
case "show":
return t("schedule.show");
case "social":
return dayIndex === 2 ? t("schedule.farewell") : t("schedule.social");
default:
return event.title;
}
};
useEffect(() => {
const timer = setInterval(() => {
setTimeLeft(getTimeLeft(EVENT_INFO.date));
}, 1000);
return () => clearInterval(timer);
}, []);
if (!isEventOngoing) {
return (
<section
id="schedule"
className="section-padding bg-card relative z-20 -mt-[40px] pt-[100px]"
style={{ borderRadius: "100% 0 0 0 / 120px 0 0 0" }}
>
<motion.div
initial={{ opacity: 0, scale: 0.9 }}
animate={{ opacity: 1, scale: 1 }}
className="max-w-lg mx-auto text-center bg-card rounded-2xl p-10 shadow-elevated"
>
<h3 className="font-display text-2xl md:text-3xl lg:text-4xl pt-3 pb-5 leading-[1.6] font-bold text-foreground mb-2">
{t("schedule.statusBriefTitle")}
</h3>
<p className="text-muted-foreground">
{t("schedule.statusBriefDescription")}
</p>
</motion.div>
</section>
);
}
return (
<section
id="schedule"
@@ -108,22 +68,45 @@ const ScheduleSection = () => {
</h3>
<div className="space-y-3">
{day.events.map((event, ei) => {
if (event.parallel) {
return (
<div key={ei} className="flex items-center gap-3 p-3 rounded-lg border-l-4 border-primary bg-primary/5">
<p className="text-xs font-medium opacity-70 whitespace-nowrap">{event.time}</p>
<div className="flex items-center gap-2 flex-1">
{event.parallel.map((pEvent, pi) => {
const PIcon = typeIcon[pEvent.type] || Clock;
return (
<div
key={pi}
className={`flex items-center gap-3 p-3 rounded-lg border-l-4 flex-1 ${
typeColor[pEvent.type] || ""
}`}
>
<PIcon className="w-4 h-4 shrink-0" />
<p className="text-sm font-semibold">
{pEvent.title}
</p>
</div>
);
})}
</div>
</div>
);
}
const Icon = typeIcon[event.type] || Clock;
return (
<div
key={ei}
className={`flex items-start gap-3 p-3 rounded-lg border-l-4 ${
className={`flex items-center gap-3 p-3 rounded-lg border-l-4 ${
typeColor[event.type] || ""
}`}
>
<Icon className="w-4 h-4 mt-0.5 shrink-0" />
<div>
<p className="text-xs font-medium opacity-70">{event.time}</p>
<Icon className="w-4 h-4 shrink-0" />
<p className="text-xs font-medium opacity-70 whitespace-nowrap">{event.time}</p>
<p className="text-sm font-semibold">
{formatEventTitle(event as { type: string; title: string }, di)}
</p>
</div>
</div>
);
})}
</div>
+51 -17
View File
@@ -38,6 +38,9 @@ import wellington from "@/assets/staff/wellington.jpg";
import xavilau from "@/assets/staff/xavilau.jpg";
import pamela from "@/assets/staff/pamela.jpg";
import papagaio from "@/assets/staff/papagaio.jpg";
import jade from "@/assets/staff/jade.jpg";
import juninho from "@/assets/staff/juninho.jpg";
import rafael from "@/assets/staff/rafael.jpg";
import gal1 from "@/assets/gallery/gal1.jpg";
import gal2 from "@/assets/gallery/gal2.jpg";
@@ -159,9 +162,9 @@ export const STAFF = [
},
{
id: "10",
name: "DJ Cathie",
role: "DJ" as const,
image: djcathie,
name: "Jade Rodrigues",
role: "Teacher" as const,
image: jade,
},
{
id: "11",
@@ -263,36 +266,67 @@ export const STAFF = [
name: "Papagaio",
role: "Specials" as const,
image: papagaio,
},
{
id: "28",
name: "Juninho",
role: "Specials" as const,
image: juninho,
},
{
id: "29",
name: "DJ Rafael",
role: "DJ" as const,
image: rafael,
}
];
// ---- PROGRAMA DEL EVENTO ----
export const SCHEDULE = [
{
day: "Viernes 20 Junio",
day: "Viernes 4 de Setiembre",
events: [
{ time: "18:00 – 19:30", title: "[Workshop 1]", type: "workshop" as const },
{ time: "19:30 – 20:00", title: "Pausa", type: "break" as const },
{ time: "20:00 – 21:30", title: "[Workshop 2]", type: "workshop" as const },
{ time: "17:00 – 18:30", title: "Followers & Style by Jade & Milu", type: "workshop" as const },
{ time: "20:00 – 21:30", title: "La Ciencia de los Giros by Rodrigo Delano", type: "workshop" as const },
{ time: "22:00 – 03:00", title: "Social Dance + DJ Set", type: "social" as const },
],
},
{
day: "Sábado 21 Junio",
day: "Sábado 5 de Setiembre",
events: [
{ time: "12:00 – 13:30", title: "[Workshop 3]", type: "workshop" as const },
{ time: "14:00 – 15:30", title: "[Workshop 4]", type: "workshop" as const },
{ time: "16:00 – 17:30", title: "[Workshop 5]", type: "workshop" as const },
{ time: "21:00 – 22:00", title: "Shows en Vivo", type: "show" as const },
{ time: "22:00 – 04:00", title: "Social Dance + DJ Sets", type: "social" as const },
{ time: "11:00 – 12:00", title: "", type: "workshop" as const, parallel: [
{ time: "11:00 – 12:00", title: "Matheus & Lydia", type: "workshop" as const },
{ time: "11:00 – 12:00", title: "Leticia & Alex", type: "workshop" as const },
]},
{ time: "12:00 – 13:00", title: "[Workshop 4]", type: "workshop" as const, parallel: [
{ time: "12:00 – 13:00", title: "Emanoel & Safira", type: "workshop" as const },
{ time: "12:00 – 13:00", title: "Ariel & Yasmin", type: "workshop" as const },
]
},
{ time: "14:00 – 15:00", title: "Comida / Lunch", type: "break" as const },
{ time: "15:00 – 16:00", title: "[Workshop 5]", type: "workshop" as const, parallel: [
{ time: "15:00 – 16:00", title: "Xavi & Laura", type: "workshop" as const },
{ time: "15:00 – 16:00", title: "Omer & Adva", type: "workshop" as const },
]
},
{ time: "16:00 – 17:00", title: "[Workshop 6]", type: "workshop" as const, parallel: [
{ time: "16:00 – 17:00", title: "Leo & Hila", type: "workshop" as const },
{ time: "16:00 – 17:00", title: "Pablo & Lena", type: "workshop" as const },
]
},
{ time: "17:00 – 18:00", title: "[Workshop 7]", type: "workshop" as const, parallel: [
{ time: "17:00 – 18:00", title: "Braz & Romina", type: "workshop" as const },
{ time: "17:00 – 18:00", title: "Didi & Patricia", type: "workshop" as const },
]
},
{ time: "22:00 – 03:00", title: "Social Dance + DJ Set", type: "social" as const },
],
},
{
day: "Domingo 22 Junio",
day: "Domingo 6 de Setiembre",
events: [
{ time: "12:00 – 13:30", title: "[Workshop 6]", type: "workshop" as const },
{ time: "14:00 – 15:30", title: "[Workshop 7]", type: "workshop" as const },
{ time: "17:00 – 22:00", title: "Farewell Party", type: "social" as const },
{ time: "11:30 – 12:30", title: "International Barcelona Flash Mob 2026. Choreo by: Lautaro & Ari. Teacher: Romina Hidalgo", type: "workshop" as const },
{ time: "12:00 – 14:00", title: "Pool Party", type: "social" as const },
],
},
];