Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
674 changes: 456 additions & 218 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,6 @@
"tailwindcss": "^3.4.11",
"typescript": "^5.5.3",
"typescript-eslint": "^8.0.1",
"vite": "^5.4.21"
"vite": "^7.1.12"
}
}
20 changes: 10 additions & 10 deletions src/components/BecomeSponsor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const BecomeSponsor = () => {
className="py-20 bg-gradient-to-b from-white to-posadev-lightPink/20 mx-auto px-4 w-full">
{/* Section header */}
<div className="text-center mb-16">
<h2 className="text-4xl md:text-5xl font-bold text-posadev-black mb-6">
<h2 className="text-3xl md:text-5xl font-bold text-posadev-black mb-6">
Únete como Patrocinador
</h2>
<p className="text-xl text-gray-600 max-w-3xl mx-auto mb-8">
Expand All @@ -33,14 +33,15 @@ const BecomeSponsor = () => {
{/* Benefits section */}
<section aria-labelledby="benefits-title" className="space-y-8">
<header>
<h3 id="benefits-title" className="text-2xl font-bold text-posadev-black mb-6">
<h3 id="benefits-title"
className="text-xl text-center md:text-2xl font-bold text-posadev-black mb-6">
¿Por qué patrocinar Posadev?
</h3>
</header>

{/* Lista de beneficios */}
<ul className="space-y-4">
<li className="flex items-start space-x-4 p-4 bg-white rounded-xl shadow-sm hover-scale">
<li className="flex justify-center items-center md:items-start md:justify-center space-x-4 p-4 bg-white rounded-xl shadow-sm hover-scale">
<span
className="w-12 h-12 rounded-lg flex items-center justify-center flex-shrink-0">
<DuckIcon color="purple" className="w-8 h-8 text-white" aria-hidden="true"/>
Expand All @@ -52,20 +53,19 @@ const BecomeSponsor = () => {
</div>
</li>

<li className="flex items-start space-x-4 p-4 bg-white rounded-xl shadow-sm hover-scale">
<span className="w-12 h-12 rounded-lg flex items-center justify-center flex-shrink-0">
<li className="flex justify-center items-center md:items-start space-x-4 p-4 bg-white rounded-xl shadow-sm hover-scale">
<span className="w-12 h-12 rounded-lg self-center flex items-center justify-center flex-shrink-0">
<DuckIcon color="blue" className="w-8 h-8 text-white" aria-hidden="true"/>
</span>
<div>
<h4 className="font-semibold text-posadev-black mb-2">Networking</h4>
<p className="text-gray-600">Expande tus redes de comunidades de desarrolladores</p>
</div>
</li>
<li className="flex items-start space-x-4 p-4 bg-white rounded-xl shadow-sm hover-scale">
<span
className="w-12 h-12 rounded-lg flex items-center justify-center flex-shrink-0">
<DuckIcon color="yellow" className="w-8 h-8 text-white" aria-hidden="true"/>
</span>
<li className="flex items-center md:items-start space-x-4 p-4 bg-white rounded-xl shadow-sm hover-scale">
<span className="w-12 h-12 rounded-lg flex items-center justify-center flex-shrink-0">
<DuckIcon color="yellow" className="w-8 h-8 text-white" aria-hidden="true"/>
</span>
<div>
<h4 className="font-semibold text-posadev-black mb-2">Impacto social</h4>
<p className="text-gray-600">Contribuye al crecimiento de las comunidades de la
Expand Down
58 changes: 58 additions & 0 deletions src/components/CalendarCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import React from "react";
import { Calendar } from "lucide-react";

const CalendarCard = () => {
const handleAddToCalendar = () => {
const event = `
BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VEVENT
URL:https://maps.app.goo.gl/8ayZ57xJf9Uvod6o7
DTSTART:20251206T180000Z
DTEND:20251206T230000Z
SUMMARY:Posadev 2025 🎉
DESCRIPTION:Únete al evento Posadev 2025 en Guadalajara.
LOCATION:https://maps.app.goo.gl/8ayZ57xJf9Uvod6o7
END:VEVENT
END:VCALENDAR
`.trim();

const blob = new Blob([event], { type: "text/calendar;charset=utf-8" });
const link = document.createElement("a");
link.href = URL.createObjectURL(blob);
link.download = "posadev-2025.ics";
link.click();
};
const handleGoogleCalendar = () => {
// Hora UTC equivalente a 9:00 a.m. - 9:00 p.m. hora México (UTC−6)
const start = "20251206T150000Z";
const end = "20251207T030000Z";

const text = encodeURIComponent("Posadev 2025 🎉");
const details = encodeURIComponent("Únete al evento Posadev 2025 en Guadalajara.");
const location = encodeURIComponent("https://maps.app.goo.gl/8ayZ57xJf9Uvod6o7");

const url = `https://www.google.com/calendar/render?action=TEMPLATE&text=${text}&dates=${start}/${end}&details=${details}&location=${location}`;
window.open(url, "_blank");
};

return (
<div
onClick={handleGoogleCalendar}
className="bg-white/10 backdrop-blur-sm rounded-2xl p-6 hover-scale text-center cursor-pointer"
>
<Calendar className="w-8 h-8 text-posadev-brightPink mx-auto mb-3" aria-hidden="true" />
<h3 className="text-white font-semibold mb-2">Fecha</h3>
<time
className="text-posadev-lightPink"
dateTime="2025-12-06"
itemProp="startDate"
>
6 de diciembre 2025
</time>
<p className="text-xs text-posadev-lightPink/70 mt-2">(Haz clic para agregar al calendario)</p>
</div>
);
};

export default CalendarCard;
53 changes: 28 additions & 25 deletions src/components/Carousel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { useKeenSlider } from "keen-slider/react";
import "keen-slider/keen-slider.min.css";
import { Button } from "@/components/ui/button";
import { ChevronLeft, ChevronRight } from "lucide-react";
import {useIsMobile} from "@/hooks/use-mobile.tsx";

export interface GridConfig {
cols: number;
Expand All @@ -21,7 +20,7 @@ interface CarouselProps<T> {

autoplay?: boolean;
autoplayInterval?: number;

className?: string;
hideArrows?: boolean;
}

Expand All @@ -33,6 +32,7 @@ const Carousel = <T,>({
gridSm = { cols: 1, rows: 1, itemsPerSlide: 1 },
autoplay = false,
autoplayInterval = 3000,
className,
hideArrows = false,
}: CarouselProps<T>) => {
const [currentSlide, setCurrentSlide] = useState(0);
Expand All @@ -42,8 +42,8 @@ const Carousel = <T,>({
useEffect(() => {
const updateGrid = () => {
const width = window.innerWidth;
if (width < 640) setGridConfig(gridSm);
else if (width < 1024) setGridConfig(gridMd);
if (width <= 640) setGridConfig(gridSm);
else if (width <= 1024) setGridConfig(gridMd);
else setGridConfig(gridLg);
};
updateGrid();
Expand All @@ -56,6 +56,7 @@ const Carousel = <T,>({
for (let i = 0; i < items.length; i += itemsPerSlide) {
groupedItems.push(items.slice(i, i + itemsPerSlide));
}
const slideCount = groupedItems.length;

const [sliderRef, instanceRef] = useKeenSlider<HTMLDivElement>({
loop: true,
Expand Down Expand Up @@ -83,7 +84,7 @@ const Carousel = <T,>({

return (
<section className="w-full flex flex-col items-center overflow-x-hidden">
<div className="flex flex-row items-center gap-10 w-full">
<div className="flex flex-row justify-center items-center gap-14 w-full">
{/* Left Arrow */}
{!hideArrows && (
<Button
Expand All @@ -96,8 +97,7 @@ const Carousel = <T,>({
</Button>
)}

<Slides itemsPerSlide={itemsPerSlide} renderItem={renderItem} groupedItems={groupedItems} gridConfig={gridConfig} sliderRef={sliderRef} />

<Slides className={className} key={`${gridConfig.cols}-${gridConfig.rows}`} itemsPerSlide={itemsPerSlide} renderItem={renderItem} groupedItems={groupedItems} gridConfig={gridConfig} sliderRef={sliderRef} />

{/* Right Arrow */}
{!hideArrows && (
Expand All @@ -115,7 +115,7 @@ const Carousel = <T,>({
{/* Dots */}
{loaded && instanceRef.current && (
<div className="flex justify-center mt-20 gap-2.5 md:gap-4">
{[...Array(instanceRef.current.track.details.slides.length).keys()].map((index) => (
{[...Array(slideCount).keys()].map((index) => (
<button
key={index}
onClick={() => instanceRef.current?.moveToIdx(index)}
Expand All @@ -130,15 +130,15 @@ const Carousel = <T,>({
);
};

const Slides = ({sliderRef, renderItem, groupedItems, gridConfig, itemsPerSlide}) => {
const Slides = ({className, sliderRef, renderItem, groupedItems, gridConfig, itemsPerSlide}) => {
if (itemsPerSlide === 1) {
return (
<div ref={sliderRef} className={`keen-slider`}>
{
groupedItems.map((group, i) => {
return (
<div key={i} className="keen-slider__slide flex justify-center">
{group.map((item, j) => renderItem(item, i * itemsPerSlide + j))}
<div key={i} className={`keen-slider__slide flex justify-center ${className}`}>
{group.map((item, j) => renderItem(item, i))}
</div>
);
})}
Expand All @@ -148,21 +148,24 @@ const Slides = ({sliderRef, renderItem, groupedItems, gridConfig, itemsPerSlide}

{/* Slides */}
return (<div ref={sliderRef} className={`keen-slider`}>
{groupedItems.map((group, i) => {
return (
<div key={i} className="keen-slider__slide flex justify-center">
<div
className="grid gap-4 w-full justify-center content-center"
style={{
gridTemplateColumns: `repeat(${gridConfig.cols}, minmax(0, auto))`,
gridTemplateRows: `repeat(${gridConfig.rows}, auto)`,
}}
>
{group.map((item, j) => renderItem(item, i * itemsPerSlide + j))}
</div>
{groupedItems.map((group, i) => (
<div key={i} className="keen-slider__slide flex justify-center flex-grow">
<div
className={`flex flex-wrap gap-2 w-full justify-center items-center ${className}`}
>
{group.map((item, j) => (
<div
key={j}
style={{
flex: `0 0 calc(${100 / gridConfig.cols}% - 1rem)`, // -1rem para compensar el gap
}}
>
{renderItem(item, i * itemsPerSlide + j)}
</div>
))}
</div>
);
})}
</div>
))}
</div>)
}

Expand Down
10 changes: 5 additions & 5 deletions src/components/Footer.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { MapPin, Mail, CandyCane, CalendarHeart} from 'lucide-react';
import {MapPin, Mail, CandyCane, CalendarHeart, Map} from 'lucide-react';
import {useNavigate} from "react-router-dom";
import {scrollToTop} from "@/lib/utils.ts";
import DuckFace from "@/components/ui/duckFace.tsx";
Expand All @@ -9,7 +9,7 @@ const Footer = () => {
const navigate = useNavigate();

return (
<footer className="bg-grey-900 text-white py-12">
<footer className="bg-grey-900 text-white py-12 px-6 md:px-10">
<div className="container mx-auto px-4">
<div className="grid grid-cols-1 md:grid-cols-3 gap-8 mb-8">
{/* Logo and description */}
Expand All @@ -36,8 +36,8 @@ const Footer = () => {
focusable="false" className="w-5 h-5 text-posadev-brightPink"/>
<time dateTime="2025-12-06" className="text-posadev-lightPink">6 de Diciembre del 2025</time>
</li>
<li className="flex items-center space-x-3">
<MapPin className="w-5 h-5 text-posadev-brightPink" aria-hidden="true" focusable="false"/>
<li className="flex items-center justify-start space-x-3">
<Map className="min-w-5 min-h-5 text-posadev-brightPink" aria-hidden="true" focusable="false"/>
<a href="https://maps.app.goo.gl/8ayZ57xJf9Uvod6o7" target="_blank"
itemProp="location"
className="text-posadev-lightPink">Tecnológico de Monterrey Campus Guadalajara</a>
Expand Down Expand Up @@ -75,7 +75,7 @@ const Footer = () => {
</div>
</div>
{/* Bottom section */}
<div className="border-t border-posadev-darkPink/30 flex md:flex-row flex-col md:items-baseline justify-between items-center pt-8">
<div className="border-t border-posadev-darkPink/30 flex md:flex-row flex-col md:items-baseline justify-between items-start gap-2 pt-8">
<small role="contentinfo" className="text-posadev-lightPink text-sm">
© {currentYear} Posadev. Todos los derechos reservados.
</small>
Expand Down
2 changes: 1 addition & 1 deletion src/components/Gallery.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ const Gallery = () => {
className="flex flex-col justify-center items-center py-20 px-10 bg-gradient-to-b from-posadev-lightPink/10 to-white"
aria-labelledby="gallery-title">
{/* Section header */}
<h2 id="gallery-title" className="text-2xl md:text-5xl font-bold text-alternative-700 mb-4">
<h2 id="gallery-title" className="text-3xl md:text-5xl font-bold text-alternative-700 mb-4">
Galería de Momentos
</h2>
<p className="text-md text-gray-600 w-full flex-wrap flex gap-2 justify-center items-center">
Expand Down
8 changes: 4 additions & 4 deletions src/components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, {useEffect, useState} from 'react';
import {Image, Menu, UserStar, X} from 'lucide-react';
import posadevLogo from '@/img/posadev-logo.png';
import {useLocation, useNavigate} from "react-router-dom";
import {cn, scrollToTop} from "@/lib/utils.ts";
import {cn} from "@/lib/utils.ts";

const Header = () => {
const [isMenuOpen, setIsMenuOpen] = useState(false);
Expand Down Expand Up @@ -93,13 +93,13 @@ const Header = () => {
<nav className="flex flex-col gap-2 px-4 py-4 space-y-4">
<a
onClick={() => navigateMenu('/#organizadores')}
className={cn("w-full text-white hover:text-posadev-brightPink transition-colors duration-300 flex items-center space-x-2", isActive('/#comunidades') && "text-posadev-brightPink")}
className={cn("w-full text-white hover:text-posadev-brightPink transition-colors duration-300 flex items-center px-4 py-1 space-x-2", isActive('/#comunidades') && "text-posadev-brightPink")}
>
Organizadores
</a>
<a
onClick={() => navigateMenu('/#galeria')}
className={cn("w-full flex items-center gap-2 text-white hover:text-posadev-brightPink transition-colors duration-300 space-x-2", isActive('/#galeria') && "text-posadev-brightPink")}
className={cn("w-full flex items-center gap-2 text-white hover:text-posadev-brightPink transition-colors px-4 py-1 duration-300 space-x-2", isActive('/#galeria') && "text-posadev-brightPink")}
>
<Image className="w-4 h-4" aria-hidden="true"/>
Galería
Expand All @@ -115,7 +115,7 @@ const Header = () => {
onClick={() => {
navigateMenu('/code-of-conduct')
}}
className={cn("text-white hover:text-posadev-brightPink transition-colors duration-300 flex items-center space-x-1", isActive('/code-of-conduct') && "text-posadev-brightPink")}>
className={cn("text-white hover:text-posadev-brightPink transition-colors duration-300 flex items-center space-x-1 px-4 py-1", isActive('/code-of-conduct') && "text-posadev-brightPink")}>
Código de Conducta
</a>
</nav>
Expand Down
18 changes: 3 additions & 15 deletions src/components/Hero.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from 'react';
import {Calendar, MapPin} from 'lucide-react';
import posadevLogo from '@/img/posadev-logo.png';
import Tickets from "@/components/Tickets.tsx";
import CalendarCard from "@/components/CalendarCard.tsx";

const Hero = () => {
return (
Expand Down Expand Up @@ -43,21 +44,7 @@ const Hero = () => {
Detalles del evento
</title>
{/* Fecha */}
<div className="bg-white/10 backdrop-blur-sm rounded-2xl p-6 hover-scale text-center">
<Calendar
className="w-8 h-8 text-posadev-brightPink mx-auto mb-3"
aria-hidden="true"
/>
<h3 className="text-white font-semibold mb-2">Fecha</h3>
<time
className="text-posadev-lightPink"
dateTime="2025-12-06"
itemProp="startDate"
>
6 de diciembre 2025
</time>
</div>

<CalendarCard />
{/* Ubicación */}
<a
href="https://maps.app.goo.gl/8ayZ57xJf9Uvod6o7"
Expand All @@ -76,6 +63,7 @@ const Hero = () => {
>
Tec de Monterrey Campus Guadalajara
</p>
<p className="text-xs text-posadev-lightPink/70 mt-2">(Haz clic para ir al mapa)</p>
</a>
</section>
</div>
Expand Down
Loading