Skip to content

Commit 3b66c69

Browse files
committed
refactor(home): redesign hackathon top bar with aurora gradient style
1 parent fc0e541 commit 3b66c69

7 files changed

Lines changed: 970 additions & 124 deletions

File tree

pages/index.tsx

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { observer } from 'mobx-react';
2-
import { FC, useContext } from 'react';
2+
import { CSSProperties, FC, useContext, useEffect, useState } from 'react';
33
import { Card, Col, Row } from 'react-bootstrap';
44
import { renderToStaticMarkup } from 'react-dom/server';
55
import ReactTyped from 'react-typed-component';
@@ -8,13 +8,82 @@ import { PageHead } from '../components/Layout/PageHead';
88
import { I18nContext } from '../models/Translation';
99
import styles from '../styles/Home.module.less';
1010

11+
// Temporarily disable localStorage persistence so the bar returns after refresh.
12+
// const HackathonTopBarStorageKey = 'labor-ai-hackathon-2026-top-bar-dismissed';
13+
const HackathonTopBarLink = '/hackathon/Labor-AI-hackathon-2026';
14+
1115
const HomePage: FC = observer(() => {
1216
const { t } = useContext(I18nContext);
17+
const [isHackathonTopBarVisible, setIsHackathonTopBarVisible] = useState(true);
18+
const [hackathonTopBarStyle, setHackathonTopBarStyle] = useState<CSSProperties>();
19+
20+
// useEffect(() => {
21+
// setIsHackathonTopBarVisible(localStorage.getItem(HackathonTopBarStorageKey) !== 'true');
22+
// }, []);
23+
useEffect(() => {
24+
const navbar = document.querySelector('nav');
25+
const syncTopBarOffset = () => {
26+
const navbarHeight = navbar?.getBoundingClientRect().height || 56;
27+
28+
setHackathonTopBarStyle({
29+
'--hackathon-top-bar-gap': `${Math.max(navbarHeight - 56, 0)}px`,
30+
'--hackathon-top-bar-offset': `${navbarHeight}px`,
31+
} as CSSProperties);
32+
};
33+
const observer =
34+
typeof ResizeObserver === 'undefined' || !navbar
35+
? undefined
36+
: new ResizeObserver(syncTopBarOffset);
37+
38+
syncTopBarOffset();
39+
if (navbar) observer?.observe(navbar);
40+
window.addEventListener('resize', syncTopBarOffset);
41+
42+
return () => {
43+
observer?.disconnect();
44+
window.removeEventListener('resize', syncTopBarOffset);
45+
};
46+
}, []);
47+
48+
const closeHackathonTopBar = () => {
49+
setIsHackathonTopBarVisible(false);
50+
// localStorage.setItem(HackathonTopBarStorageKey, 'true');
51+
};
1352

1453
return (
1554
<>
1655
<PageHead />
1756

57+
{isHackathonTopBarVisible && (
58+
<aside
59+
className={styles.hackathonTopBar}
60+
aria-label={t('home_hackathon_top_bar_aria_label')}
61+
style={hackathonTopBarStyle}
62+
>
63+
<div className={styles.hackathonTopBarInner}>
64+
<a className={styles.hackathonTopBarContent} href={HackathonTopBarLink}>
65+
<span className={styles.hackathonTopBarText}>
66+
<strong>{t('home_hackathon_top_bar_title')}</strong>
67+
<span>{t('home_hackathon_top_bar_description')}</span>
68+
</span>
69+
<span className={styles.hackathonTopBarEventName}>Labor AI Hackathon 2026</span>
70+
<span className={styles.hackathonTopBarAction}>
71+
{t('home_hackathon_top_bar_action')}
72+
</span>
73+
</a>
74+
<button
75+
className={styles.hackathonTopBarClose}
76+
type="button"
77+
aria-label={t('home_hackathon_top_bar_close')}
78+
title={t('home_hackathon_top_bar_close')}
79+
onClick={closeHackathonTopBar}
80+
>
81+
×
82+
</button>
83+
</div>
84+
</aside>
85+
)}
86+
1887
<section
1988
className={`flex-fill d-flex flex-column justify-content-center align-items-center bg-secondary bg-gradient text-dark bg-opacity-10 ${styles.main}`}
2089
>

0 commit comments

Comments
 (0)