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
12 changes: 4 additions & 8 deletions src/components/Meetups/2025/Hero/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { FaTicket } from "react-icons/fa6";

import TicketHome from "components/Meetups/2025/TicketHome";
import { addUtmParams } from "app/lib/utils";
import { useTicketRelease } from "hooks/useTicketRelease";
import classNames from "classnames";

type HeroProps = {
Expand All @@ -23,9 +24,8 @@ export default function Hero({ sponsors }: HeroProps) {
const now = new Date();
const deadline = new Date("2025-07-31T23:59:59"); // TODO: Move to a constant

// Check if tickets are released (October 13, 2025 at 13:10 Uruguay time)
const ticketReleaseDate = new Date("2025-10-13T13:10:00-03:00");
const areTicketsReleased = now >= ticketReleaseDate;
// Check if tickets are released using centralized hook
const { isReleased: areTicketsReleased, ticketUrl } = useTicketRelease();

return (
<section
Expand Down Expand Up @@ -69,11 +69,7 @@ export default function Hero({ sponsors }: HeroProps) {
"cursor-not-allowed border-gray-500 bg-gray-800 text-gray-500 opacity-50": !areTicketsReleased,
}
)}
href={
areTicketsReleased
? addUtmParams("https://www.eventbrite.com/e/la-meetup-iii-tickets-1735441254509")
: "#"
}
href={areTicketsReleased ? addUtmParams(ticketUrl) : "#"}
target={areTicketsReleased ? "_blank" : undefined}
rel={areTicketsReleased ? "noopener noreferrer" : undefined}
aria-disabled={!areTicketsReleased}
Expand Down
23 changes: 3 additions & 20 deletions src/components/Meetups/2025/TicketHome/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
"use client";

import { useState, useEffect } from "react";
import Link from "next/link";
import { Container3D } from "components/Meetups/2024/Container3D";
import Ticket from "components/Meetups/2024/Ticket";
import { addUtmParams } from "app/lib/utils";
import { useTicketRelease } from "hooks/useTicketRelease";

type TicketHomeProps = {
sponsors?: readonly {
Expand All @@ -15,25 +15,8 @@ type TicketHomeProps = {
};

export default function TicketHome({ sponsors }: TicketHomeProps) {
// Uruguay timezone is UTC-3, so 13:10 Uruguay time = 16:10 UTC
// Using ISO 8601 format with timezone offset for clarity
const uruguayReleaseDate = "2025-10-13T13:10:00-03:00"; // 13/10/2025 at 13:10 Uruguay time
const ticketUrl = "https://www.eventbrite.com/e/la-meetup-iii-tickets-1735441254509";

const [isReleased, setIsReleased] = useState(false);

useEffect(() => {
const checkReleaseStatus = () => {
const now = new Date();
const releaseDate = new Date(uruguayReleaseDate);
setIsReleased(now >= releaseDate);
};

checkReleaseStatus();
const interval = setInterval(checkReleaseStatus, 1000);

return () => clearInterval(interval);
}, [uruguayReleaseDate]);
// Use centralized ticket release logic
const { isReleased, releaseDate: uruguayReleaseDate, ticketUrl } = useTicketRelease();

const desktopTicket = (
<div className="flex-0 mx-auto flex max-w-[550px] items-center justify-center">
Expand Down
32 changes: 32 additions & 0 deletions src/hooks/useTicketRelease.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { useState, useEffect } from "react";

// Uruguay timezone is UTC-3
// Using ISO 8601 format with timezone offset ensures this works globally
const URUGUAY_TICKET_RELEASE_DATE = "2025-10-13T13:10:00-03:00"; // 13/10/2025 at 13:10 Uruguay time
const EVENTBRITE_TICKET_URL = "https://www.eventbrite.com/e/la-meetup-iii-tickets-1735441254509";

export function useTicketRelease() {
const [isReleased, setIsReleased] = useState(false);

useEffect(() => {
const checkReleaseStatus = () => {
const now = new Date();
const releaseDate = new Date(URUGUAY_TICKET_RELEASE_DATE);
setIsReleased(now >= releaseDate);
};

// Check immediately
checkReleaseStatus();

// Then check every second to ensure real-time updates
const interval = setInterval(checkReleaseStatus, 1000);

return () => clearInterval(interval);
}, []);

return {
isReleased,
releaseDate: URUGUAY_TICKET_RELEASE_DATE,
ticketUrl: EVENTBRITE_TICKET_URL,
};
}