Restructure routes: / and /dash show a project overview dashboard, /activity hosts the existing timeline, /cv remains. Shared Layout component provides consistent nav header and footer across all routes. New /v1/projects endpoint aggregates per-repo activity stats (commits, issues, PRs, date range) from existing event data via SQL. Dashboard ranks projects by weighted recency + volume score and renders a card grid. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
43 lines
1.4 KiB
TypeScript
43 lines
1.4 KiB
TypeScript
import { NavLink, Outlet } from 'react-router-dom';
|
|
import Container from 'react-bootstrap/Container';
|
|
|
|
const externalLinks = [
|
|
{ url: 'https://linkedin.com/in/thijssen/', label: 'linkedin' },
|
|
{ url: 'https://stackoverflow.com/users/68115/grenade', label: 'stackoverflow' },
|
|
{ url: 'https://github.com/grenade', label: 'github' },
|
|
{ url: 'https://git.lair.cafe/grenade', label: 'gitea' },
|
|
];
|
|
|
|
export function Layout() {
|
|
return (
|
|
<>
|
|
<Container className="py-4">
|
|
<header className="site-header d-flex flex-wrap justify-content-between align-items-center mb-4">
|
|
<h1 className="mb-0">hi, i'm rob</h1>
|
|
<nav className="d-flex flex-wrap gap-3 align-items-center">
|
|
<NavLink to="/" end>dash</NavLink>
|
|
<NavLink to="/activity">activity</NavLink>
|
|
<NavLink to="/cv">cv</NavLink>
|
|
<span className="nav-divider">|</span>
|
|
{externalLinks.map((el) => (
|
|
<a
|
|
key={el.url}
|
|
href={el.url}
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
>
|
|
{el.label}
|
|
</a>
|
|
))}
|
|
</nav>
|
|
</header>
|
|
<Outlet />
|
|
</Container>
|
|
<footer className="site-footer">
|
|
no cookies are set or read by this site, which is why no consent banner
|
|
is shown.
|
|
</footer>
|
|
</>
|
|
);
|
|
}
|