feat: confetti
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
import confetti from "canvas-confetti";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { useState } from "react";
|
||||
import { REGISTRATION_OPENS_AT } from "@/lib/opening";
|
||||
import { useRegistrationOpen } from "@/lib/useRegistrationOpen";
|
||||
import { client } from "@/utils/orpc";
|
||||
@@ -26,34 +25,6 @@ function UnitBox({ value, label }: UnitBoxProps) {
|
||||
);
|
||||
}
|
||||
|
||||
function fireConfetti() {
|
||||
const colors = ["#d82560", "#52979b", "#d09035", "#214e51", "#ffffff"];
|
||||
|
||||
// Three bursts from different origins
|
||||
confetti({
|
||||
particleCount: 120,
|
||||
spread: 80,
|
||||
origin: { x: 0.3, y: 0.6 },
|
||||
colors,
|
||||
});
|
||||
setTimeout(() => {
|
||||
confetti({
|
||||
particleCount: 120,
|
||||
spread: 80,
|
||||
origin: { x: 0.7, y: 0.6 },
|
||||
colors,
|
||||
});
|
||||
}, 200);
|
||||
setTimeout(() => {
|
||||
confetti({
|
||||
particleCount: 80,
|
||||
spread: 100,
|
||||
origin: { x: 0.5, y: 0.5 },
|
||||
colors,
|
||||
});
|
||||
}, 400);
|
||||
}
|
||||
|
||||
// Reminder opt-in form — sits at the very bottom of the banner
|
||||
function ReminderForm() {
|
||||
const [email, setEmail] = useState("");
|
||||
@@ -231,18 +202,9 @@ function ReminderForm() {
|
||||
|
||||
/**
|
||||
* Shown in place of the registration form while registration is not yet open.
|
||||
* Fires confetti the moment the gate opens (without a page reload).
|
||||
*/
|
||||
export function CountdownBanner() {
|
||||
const { isOpen, days, hours, minutes, seconds } = useRegistrationOpen();
|
||||
const confettiFired = useRef(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (isOpen && !confettiFired.current) {
|
||||
confettiFired.current = true;
|
||||
fireConfetti();
|
||||
}
|
||||
}, [isOpen]);
|
||||
|
||||
// Once open the parent component will unmount this — but render nothing just in case
|
||||
if (isOpen) return null;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Link } from "@tanstack/react-router";
|
||||
import { useState } from "react";
|
||||
import confetti from "canvas-confetti";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { CountdownBanner } from "@/components/homepage/CountdownBanner";
|
||||
import { PerformerForm } from "@/components/registration/PerformerForm";
|
||||
import { SuccessScreen } from "@/components/registration/SuccessScreen";
|
||||
@@ -8,6 +9,33 @@ import { WatcherForm } from "@/components/registration/WatcherForm";
|
||||
import { authClient } from "@/lib/auth-client";
|
||||
import { useRegistrationOpen } from "@/lib/useRegistrationOpen";
|
||||
|
||||
function fireConfetti() {
|
||||
const colors = ["#d82560", "#52979b", "#d09035", "#214e51", "#ffffff"];
|
||||
|
||||
confetti({
|
||||
particleCount: 120,
|
||||
spread: 80,
|
||||
origin: { x: 0.3, y: 0.6 },
|
||||
colors,
|
||||
});
|
||||
setTimeout(() => {
|
||||
confetti({
|
||||
particleCount: 120,
|
||||
spread: 80,
|
||||
origin: { x: 0.7, y: 0.6 },
|
||||
colors,
|
||||
});
|
||||
}, 200);
|
||||
setTimeout(() => {
|
||||
confetti({
|
||||
particleCount: 80,
|
||||
spread: 100,
|
||||
origin: { x: 0.5, y: 0.5 },
|
||||
colors,
|
||||
});
|
||||
}, 400);
|
||||
}
|
||||
|
||||
type RegistrationType = "performer" | "watcher";
|
||||
|
||||
interface SuccessState {
|
||||
@@ -19,6 +47,15 @@ interface SuccessState {
|
||||
export default function EventRegistrationForm() {
|
||||
const { data: session } = authClient.useSession();
|
||||
const { isOpen } = useRegistrationOpen();
|
||||
const confettiFired = useRef(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (isOpen && !confettiFired.current) {
|
||||
confettiFired.current = true;
|
||||
fireConfetti();
|
||||
}
|
||||
}, [isOpen]);
|
||||
|
||||
const [selectedType, setSelectedType] = useState<RegistrationType | null>(
|
||||
null,
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user