Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 26 additions & 35 deletions src/components/Footer.astro
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
import SocialLinks from "@components/SocialLinks.astro";
import links from "@data/links.json";
import { FOOTER_COLUMNS, TERMS, SOCIALS } from "@data/nav";
import EPSLogo from "/public/theme/eps-logo.svg";

const buildTimestamp = __TIMESTAMP__;
Expand All @@ -18,33 +18,22 @@ const gitVersion = __GIT_VERSION__;
</div>
<div class="footer-grid">
{
links.footer.map((section) => (
FOOTER_COLUMNS.map((col) => (
<div>
<p class="footer-col-title">{section.name}</p>
{section.items ? (
<ul class="footer-links">
{section.items.map((item) => (
<li>
<a
href={item.path}
target={item.path.startsWith("http") ? "_blank" : undefined}
rel={item.path.startsWith("http") ? "noopener" : undefined}
>
{item.name}{item.path.startsWith("http") ? " ↗" : ""}
</a>
</li>
))}
</ul>
) : (
<a
href={section["path"]}
class="footer-links"
target={section["path"].startsWith("http") ? "_blank" : undefined}
rel={section["path"].startsWith("http") ? "noopener" : undefined}
>
{section.name}{section["path"].startsWith("http") ? " ↗" : ""}
</a>
)}
<p class="footer-col-title">{col.title}</p>
<ul class="footer-links">
{col.items.map((item) => (
<li>
<a
href={item.url}
target={item.external ? "_blank" : undefined}
rel={item.external ? "noopener" : undefined}
>
{item.label}{item.external ? " ↗" : ""}
</a>
</li>
))}
</ul>
</div>
))
}
Expand Down Expand Up @@ -90,28 +79,30 @@ const gitVersion = __GIT_VERSION__;
<div class="flex w-full lg:flex-row flex-col-reverse justify-between">
<div class="terms py-2 text-center ">
{
links.terms.map((item) => (
TERMS.map((item) => (
<a
href={item.path}
href={item.url}
class="text-[var(--color-text-secondary)] hover:text-[var(--color-primary-hover)] transition-colors duration-200 mx-2"
>
{item.name}
{item.path.startsWith("http") && (
<span class="inline-block"></span>
{item.label}
{item.external && (
<span class="inline-block">342206227</span>
)}
</a>
))
}
</div>

{
links && links["socials"] && (
SOCIALS && (
<SocialLinks
socials={links["socials"]}
socials={SOCIALS}
variant="white"
class="opacity-60 pb-4"
/>
)
}
/>
)
}
</div>
</div>
Expand Down
117 changes: 89 additions & 28 deletions src/components/Header.astro
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,7 @@ import HeaderLogo from "@components/header/header-logo.astro";
import Search from "@components/Search.astro";
import ThemeToggle from "@components/ThemeToggle.astro";

import links from "@data/links.json";

interface NavItem {
name: string;
path?: string;
items?: { name: string; path: string }[];
}
import { NAV_MENUS, type NavMenu } from "@data/nav";
---

<nav aria-label="Main navigation" id="navbar">
Expand All @@ -26,34 +20,56 @@ interface NavItem {
Search
</button>
</li>
{(links.header as NavItem[]).map((menu) => (
menu.items ? (
{NAV_MENUS.map((menu: NavMenu) => (
menu.sections ? (
<li class="nav-item has-dropdown">
<a href="#" aria-haspopup="true" aria-expanded="false">
{menu.name} <span class="nav-arrow">▾</span>
<a href={menu.url || "#"} aria-haspopup="true" aria-expanded="false">
{menu.label} <span class="nav-arrow">▾</span>
</a>
<div class="nav-dropdown">
<div class="nav-dropdown-inner">
<ul>
{menu.items.map((item) => (
<li>
<a
href={item.path}
target={item.path.startsWith("http") ? "_blank" : undefined}
rel={item.path.startsWith("http") ? "nofollow noopener" : undefined}
>
{item.name}
{item.path.startsWith("http") && <span class="nav-ext">&#8599;</span>}
</a>
</li>
))}
</ul>
<div class="nav-dropdown" class:list={menu.wide ? ["nav-dropdown-wide"] : []}>
<div class="nav-dropdown-inner" class:list={menu.wide ? ["nav-dropdown-grid"] : []}>
{menu.sections.length === 1 && !menu.sections[0].label ? (
<ul>
{menu.sections[0].items.map((item) => (
<li>
<a
href={item.url}
target={item.external ? "_blank" : undefined}
rel={item.external ? "nofollow noopener" : undefined}
>
{item.label}
{item.external && <span class="nav-ext">&#8599;</span>}
</a>
</li>
))}
</ul>
) : (
menu.sections.map((section) => (
<div class="nav-dropdown-col">
{section.label && <p class="nav-dropdown-label">{section.label}</p>}
<ul>
{section.items.map((item) => (
<li>
<a
href={item.url}
target={item.external ? "_blank" : undefined}
rel={item.external ? "nofollow noopener" : undefined}
>
{item.label}
{item.external && <span class="nav-ext">&#8599;</span>}
</a>
</li>
))}
</ul>
</div>
))
)}
</div>
</div>
</li>
) : (
<li class="nav-item">
<a href={menu.path || "#"}>{menu.name}</a>
<a href={menu.url || "#"}>{menu.label}</a>
</li>
)
))}
Expand Down Expand Up @@ -172,6 +188,31 @@ nav {
padding: 0;
}

.nav-dropdown-wide {
min-width: 540px;
}

.nav-dropdown-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 0.5rem;
}

.nav-dropdown-col {
break-inside: avoid;
}

.nav-dropdown-label {
font-size: 0.7rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.1em;
color: var(--color-text-muted);
padding: 0.65rem 1.2rem 0.3rem;
margin: 0;
opacity: 0.7;
}

.nav-dropdown li a {
display: block;
padding: 0.65rem 1.2rem;
Expand Down Expand Up @@ -356,6 +397,26 @@ nav {
font-size: 0.95rem;
}

/* Mobile: stack Programme sections vertically */
.nav-dropdown-grid {
display: block;
}

.nav-dropdown-col {
margin-bottom: 0.5rem;
}

.nav-dropdown-label {
font-size: 0.75rem;
padding: 0.6rem 0 0.2rem 0;
margin: 0;
color: var(--color-text-muted);
opacity: 0.7;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.1em;
}

.nav-item.open .nav-arrow {
transform: rotate(180deg);
}
Expand Down
56 changes: 38 additions & 18 deletions src/components/JobCard.astro
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
import { getEntry } from "astro:content";
import Markdown from "@ui/Markdown.astro";
const { job:jobId, sponsor:sponsorId } = Astro.props;
const { job:jobId, sponsor:sponsorId, compact = true } = Astro.props;

const job = await getEntry("jobs", jobId);
if (!job) {
Expand All @@ -17,22 +17,30 @@ if (!sponsor) {
// TODO: add tags
const { title, location, type, level, salary, description, responsibilities, min_requirements, requirements, preferred, benefits, apply_link, draft } = job.data;

const jobUrl = `/sponsor/${jobId}`;
const descLimit = 500;
const descFull = description || "";
const descDisplay = compact && descFull.length > descLimit
? descFull.slice(0, descLimit).replace(/\s+\S*$/, "") + "…"
: descFull;

---

<div class="mb-6 rounded-lg border border-white/10 bg-white/5">
<div class="mb-6 rounded-lg border border-[var(--color-border)] bg-[var(--color-surface-subtle)]">
<div class=`flex-1 p-6 ${draft ? "draft": ""}`>
<p class="text-xl pb-2 inline-block font-bold">
{sponsor.data.name}
</p>
<a href={`/sponsor/${jobId}`}>
<h2 class="text-3xl font-bold mb-2">{title}</h2>
<a href={`/sponsor/${jobId}`} class="group">
<h2 class="text-3xl font-bold mb-2 text-[var(--color-text)] group-hover:text-[var(--color-accent-themed)] transition-colors">{title}</h2>
</a>

<p class="text-[var(--color-text-muted)] mb-2">{([level, type, location].filter(Boolean)).join(" • ")}</p>
<p class="text-[var(--color-text-secondary)] mb-4">{salary}</p>
<Markdown content={description || ""} class="job-post" />
<Markdown content={descDisplay} class="job-post" />
{compact && <div class="mt-4"><a href={jobUrl} class="more-btn">Read more</a></div>}

{ responsibilities &&
{!compact && responsibilities &&
<h3 class="text-xl font-semibold mb-2">Responsibilities</h3>
<ul class="list-disc list-inside mb-4">
{responsibilities.map((item) => {
Expand All @@ -53,49 +61,61 @@ const { title, location, type, level, salary, description, responsibilities, min
</ul>
}

{ min_requirements &&
{!compact && min_requirements &&
<h3 class="text-xl font-semibold mb-2">Minimum requirements</h3>
<ul class="list-disc list-inside mb-4">
{min_requirements.map((item:string) => <li>{item}</li>)}
</ul>
}
{ requirements &&
{!compact && requirements &&
<h3 class="text-xl font-semibold mb-2">Requirements</h3>
<ul class="list-disc list-inside mb-4">
{requirements.map((item:string) => <li>{item}</li>)}
</ul>
}

{ preferred &&
{!compact && preferred &&
<h3 class="text-xl font-semibold mb-2">Nice-to-Haves</h3>
<ul class="list-disc list-inside mb-4">
{preferred.map((item:string) => <li>{item}</li>)}
</ul>
}

{ benefits &&
{!compact && benefits &&
<h3 class="text-xl font-semibold mb-2">Benefits</h3>
<ul class="list-disc list-inside mb-6">
{benefits.map((item:string) => <li>{item}</li>)}
</ul>
}

{ job.data.description2 &&
{!compact && job.data.description2 &&
<Markdown content={job.data.description2 || ""} class="job-post" />
}

<a
href={apply_link}
target="_blank"
class="apply-btn"
>
Apply Now
</a>
{!compact && apply_link && (
<a href={apply_link} target="_blank" class="apply-btn">Apply Now</a>
)}
</div>
</div>

<style>

.more-btn {
display: inline-block;
padding: 8px 24px;
color: white;
font-weight: 700;
border-radius: 9999px;
border: 1px solid transparent;
text-decoration: none;
transition: all 0.1s ease;
background: linear-gradient(to right, oklch(0.522 0.218 264.4), oklch(0.422 0.218 264.4));
}

.more-btn:hover {
color: white;
}

.apply-btn {
display: inline-block;
padding: 8px 24px;
Expand Down
4 changes: 2 additions & 2 deletions src/components/SponsorCard.astro
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ const logo = sponsorLogos[sponsor.id];
---

<div
class=`lg:max-w-[400px] flex flex-col gap-6 p-6 rounded-lg shadow-md bg-white/5 mb-6 ${draft ? "draft": "no-draft"}`
class=`lg:max-w-[400px] flex flex-col gap-6 p-6 rounded-lg shadow-md bg-[var(--color-surface-subtle)] mb-6 ${draft ? "draft": "no-draft"}`
>
<div class="w-full flex justify-center items-center md:items-center min-h-[140px] bg-white rounded-lg p-4">
{
Expand Down Expand Up @@ -74,7 +74,7 @@ const logo = sponsorLogos[sponsor.id];
<>{title}</>
}
</h2>
<p class="text-white/60 mb-4" style="color:oklch(54.6% 0.03 256.802);">
<p class="text-[var(--color-text-muted)] mb-4">
{industry} {industry && location && <>—</>} {location}
</p>

Expand Down
Loading
Loading