From d2a18d0121d726d32ad1cdb8ef8fb4de18327ffa Mon Sep 17 00:00:00 2001 From: jeremy-ufoyrwoth Date: Wed, 15 Jul 2026 10:40:12 +0300 Subject: [PATCH] Install @types/react & auto compute anniversary years --- package-lock.json | 18 +++ package.json | 1 + src/pages/HomePage.tsx | 308 +++++++++++++++++++++++++++++++---------- 3 files changed, 252 insertions(+), 75 deletions(-) diff --git a/package-lock.json b/package-lock.json index d6d56d5..e1fe1be 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,6 +26,7 @@ "@netlify/functions": "^5.2.0", "@types/express": "^4.17.21", "@types/node": "^22.14.0", + "@types/react": "^19.2.17", "autoprefixer": "^10.4.21", "tailwindcss": "^4.1.14", "tsx": "^4.21.0", @@ -1598,6 +1599,16 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/react": { + "version": "19.2.17", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.17.tgz", + "integrity": "sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==", + "dev": true, + "license": "MIT", + "dependencies": { + "csstype": "^3.2.2" + } + }, "node_modules/@types/retry": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", @@ -1951,6 +1962,13 @@ "integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==", "license": "MIT" }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "dev": true, + "license": "MIT" + }, "node_modules/data-uri-to-buffer": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", diff --git a/package.json b/package.json index 5f51add..8b429ac 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ "@netlify/functions": "^5.2.0", "@types/express": "^4.17.21", "@types/node": "^22.14.0", + "@types/react": "^19.2.17", "autoprefixer": "^10.4.21", "tailwindcss": "^4.1.14", "tsx": "^4.21.0", diff --git a/src/pages/HomePage.tsx b/src/pages/HomePage.tsx index 58dcc42..51d4441 100644 --- a/src/pages/HomePage.tsx +++ b/src/pages/HomePage.tsx @@ -35,14 +35,14 @@ const container = { show: { opacity: 1, transition: { - staggerChildren: 0.1 - } - } + staggerChildren: 0.1, + }, + }, }; const item = { hidden: { y: 20, opacity: 0 }, - show: { y: 0, opacity: 1 } + show: { y: 0, opacity: 1 }, }; const GALLERY_BASE_URL = "https://cdn.javascriptkampala.org"; @@ -166,17 +166,34 @@ function speakerAvatarUrl(username: string) { return `https://unavatar.io/x/${username}`; } +const anniversaryYear = new Date().getFullYear() - 2019; +const anniversaryYearLastDigit = + anniversaryYear.toString().length > 1 + ? +`${anniversaryYear}`.split("")[`${anniversaryYear}`.length - 1] + : anniversaryYear; +const anniversaryYearSymbol = + anniversaryYearLastDigit === 1 + ? "st" + : anniversaryYearLastDigit === 2 + ? "nd" + : anniversaryYearLastDigit === 3 + ? "rd" + : "th"; + export default function HomePage() { - const [selectedImageIndex, setSelectedImageIndex] = useState(null); + const [selectedImageIndex, setSelectedImageIndex] = useState( + null, + ); const triggerConfetti = () => { const duration = 3 * 1000; const animationEnd = Date.now() + duration; const defaults = { startVelocity: 30, spread: 360, ticks: 60, zIndex: 0 }; - const randomInRange = (min: number, max: number) => Math.random() * (max - min) + min; + const randomInRange = (min: number, max: number) => + Math.random() * (max - min) + min; - const interval: any = setInterval(function() { + const interval: any = setInterval(function () { const timeLeft = animationEnd - Date.now(); if (timeLeft <= 0) { @@ -184,8 +201,16 @@ export default function HomePage() { } const particleCount = 50 * (timeLeft / duration); - confetti({ ...defaults, particleCount, origin: { x: randomInRange(0.1, 0.3), y: Math.random() - 0.2 } }); - confetti({ ...defaults, particleCount, origin: { x: randomInRange(0.7, 0.9), y: Math.random() - 0.2 } }); + confetti({ + ...defaults, + particleCount, + origin: { x: randomInRange(0.1, 0.3), y: Math.random() - 0.2 }, + }); + confetti({ + ...defaults, + particleCount, + origin: { x: randomInRange(0.7, 0.9), y: Math.random() - 0.2 }, + }); }, 250); }; @@ -193,11 +218,20 @@ export default function HomePage() { triggerConfetti(); }, []); - const Lightbox = ({ images, index, onClose }: { images: string[], index: number, onClose: () => void }) => { + const Lightbox = ({ + images, + index, + onClose, + }: { + images: string[]; + index: number; + onClose: () => void; + }) => { const [currentIndex, setCurrentIndex] = useState(index); - + const next = () => setCurrentIndex((prev) => (prev + 1) % images.length); - const prev = () => setCurrentIndex((prev) => (prev - 1 + images.length) % images.length); + const prev = () => + setCurrentIndex((prev) => (prev - 1 + images.length) % images.length); useEffect(() => { const onKey = (e: KeyboardEvent) => { @@ -217,7 +251,7 @@ export default function HomePage() { > - +