Skip to content

Commit

Permalink
Setup animated countdown on schedule page (#93)
Browse files Browse the repository at this point in the history
* setup: basic framer countdown

* fix: removed useRef, changed animation exit value

* update: temporarily disabled slide up animation

* fix: conditional day render

* fix: precompute time

* fix: margin for the countdown

* update: added loading bar

* fix: rename to Loader

* feat: time until hacking countdown timer

* fix: clipboard styling

---------

Co-authored-by: Tyler Yu <[email protected]>
Co-authored-by: Alexander Liu <[email protected]>
  • Loading branch information
3 people authored Nov 3, 2023
1 parent 7b9b9df commit 56117a2
Show file tree
Hide file tree
Showing 7 changed files with 105 additions and 4 deletions.
1 change: 1 addition & 0 deletions apps/site/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"@types/react": "18.2.20",
"@types/react-dom": "^18.2.0",
"bootstrap": "^5.3.1",
"clsx": "^2.0.0",
"date-fns-tz": "^2.0.0",
"eslint": "8.46.0",
"eslint-config-next": "^13.4.1",
Expand Down
4 changes: 2 additions & 2 deletions apps/site/src/app/schedule/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import { Schedule } from "@/views";
import { Maintenance } from "@/views";

export const revalidate = 60;

// When set to any value
const Component = process.env.MAINTENANCE_MODE_SCHEDULE
? Maintenance
: Schedule;

export default Component;
export default Component;
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
@use "bootstrap-utils" as bootstrap;

.countdown {
margin: 0;
padding: 96px 0 32px 0;
opacity: 0;
transition: opacity 225ms cubic-bezier(0.32, 0, 0.67, 0);

span {
text-align: center;
font-weight: 600;

&.time {
display: block;
@include bootstrap.font-size(6rem);
line-height: 100%;

.number {
display: inline-block;
text-align: center;
width: 2ch;
}

.colon {
opacity: 0.75;
}
}

&.caption {
display: block;
@include bootstrap.font-size(1.5rem);
}
}
}

.loaded {
opacity: 1;
}
53 changes: 53 additions & 0 deletions apps/site/src/views/Schedule/components/Countdown/Countdown.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
"use client";

import { useEffect, useState } from "react";

import clsx from "clsx";
import styles from "./Countdown.module.scss";

// 10/4/23 10AM in UTC
const hackingStarts = new Date(Date.UTC(2023, 10, 4, 17, 0, 0));

export default function Countdown() {
const [remainingSeconds, setRemainingSeconds] = useState<number>(NaN);

useEffect(() => {
setRemainingSeconds(
(hackingStarts.valueOf() - new Date().valueOf()) / 1000,
);
const interval = setInterval(() => {
setRemainingSeconds((r) => r - 1);
}, 1000);

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

return (
<div
className={clsx(
styles.countdown,
!isNaN(remainingSeconds) && styles.loaded,
)}
>
<span className={styles.time}>
<span className={styles.number}>
{Math.floor(remainingSeconds / (60 * 60))}
</span>
<span className={styles.colon}>:</span>
<span className={styles.number}>
{Math.floor((remainingSeconds / 60) % 60)
.toString()
.padStart(2, "0")}
</span>

<span className={styles.colon}>:</span>
<span className={styles.number}>
{Math.floor(remainingSeconds % 60)
.toString()
.padStart(2, "0")}
</span>
</span>
<span className={styles.caption}>Until Hacking Begins</span>
</div>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
@use "zothacks-theme" as theme;

.accordion {
padding-top: 50px;
padding-bottom: 120px;
--bs-accordion-btn-icon: url("~@/assets/icons/accordion-btn.svg");
--bs-accordion-btn-active-icon: url("~@/assets/icons/accordion-btn.svg");
Expand All @@ -26,6 +25,7 @@
}
}
.clipboard {
padding-top: 50px;
@include bootstrap.rfs(8.5rem, border-radius);
background-color: theme.$brown;
padding: 5px;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ import Accordion from "react-bootstrap/Accordion";
import Col from "react-bootstrap/Col";
import Container from "react-bootstrap/Container";
import Row from "react-bootstrap/Row";
import { utcToZonedTime } from "date-fns-tz";

import clip from "@/assets/images/clip.svg";

import styles from "./ClipboardSchedule.module.scss";
import Countdown from "../../components/Countdown/Countdown";

interface ClipboardScheduleProps {
schedule: {
Expand Down Expand Up @@ -69,6 +69,7 @@ function ClipboardSchedule({ schedule }: ClipboardScheduleProps) {
initial="initial"
animate="animate"
>
<Countdown />
<Accordion defaultActiveKey="0" className={styles.accordion}>
{schedule.map((day, i) => (
<div key={i}>
Expand Down
8 changes: 8 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 56117a2

Please sign in to comment.