@@ -0,0 +1,21 @@
|
||||
---
|
||||
import BaseLayout from '../layouts/BaseLayout.astro';
|
||||
import ContactList from '../components/ContactList.astro';
|
||||
import { getContacts } from '../lib/directus';
|
||||
import { site } from '../lib/site';
|
||||
|
||||
const contacts = await getContacts();
|
||||
---
|
||||
|
||||
<BaseLayout title="Contact" description="How to reach Swansea Airport and its public contacts.">
|
||||
<div class="container stack">
|
||||
<section class="prose">
|
||||
<p class="eyebrow">Contact</p>
|
||||
<h1 class="section-title">Reach the airport team</h1>
|
||||
<p>{site.address}</p>
|
||||
<p><a href={`tel:${site.phone.replace(/\s+/g, '')}`}>{site.phone}</a></p>
|
||||
</section>
|
||||
|
||||
<ContactList contacts={contacts} />
|
||||
</div>
|
||||
</BaseLayout>
|
||||
@@ -0,0 +1,13 @@
|
||||
---
|
||||
import BaseLayout from '../layouts/BaseLayout.astro';
|
||||
import DocumentList from '../components/DocumentList.astro';
|
||||
import { getDocuments } from '../lib/directus';
|
||||
|
||||
const documents = await getDocuments();
|
||||
---
|
||||
|
||||
<BaseLayout title="Documents" description="Airport documents and downloads for pilots, visitors, and staff.">
|
||||
<div class="container">
|
||||
<DocumentList documents={documents} />
|
||||
</div>
|
||||
</BaseLayout>
|
||||
@@ -0,0 +1,24 @@
|
||||
---
|
||||
import BaseLayout from '../../layouts/BaseLayout.astro';
|
||||
import { getEvents } from '../../lib/directus';
|
||||
import { formatDateTime } from '../../lib/format';
|
||||
|
||||
type EventItem = Awaited<ReturnType<typeof getEvents>>[number];
|
||||
|
||||
export async function getStaticPaths() {
|
||||
const events = await getEvents();
|
||||
return events.map((item) => ({ params: { slug: item.slug }, props: { item } }));
|
||||
}
|
||||
|
||||
const { item } = Astro.props as { item: EventItem };
|
||||
---
|
||||
|
||||
<BaseLayout title={item.title} description={item.description}>
|
||||
<article class="container prose">
|
||||
<p class="meta">{formatDateTime(item.start_datetime)}</p>
|
||||
<h1 class="section-title">{item.title}</h1>
|
||||
<p>{item.description}</p>
|
||||
{item.location_text && <p><strong>Location:</strong> {item.location_text}</p>}
|
||||
{item.registration_link && <p><a class="button primary" href={item.registration_link}>Register</a></p>}
|
||||
</article>
|
||||
</BaseLayout>
|
||||
@@ -0,0 +1,13 @@
|
||||
---
|
||||
import BaseLayout from '../../layouts/BaseLayout.astro';
|
||||
import EventsList from '../../components/EventsList.astro';
|
||||
import { getEvents } from '../../lib/directus';
|
||||
|
||||
const events = (await getEvents()).sort((left, right) => new Date(left.start_datetime).getTime() - new Date(right.start_datetime).getTime());
|
||||
---
|
||||
|
||||
<BaseLayout title="Events" description="Airport events and flying opportunities.">
|
||||
<div class="container">
|
||||
<EventsList events={events} title="Events listing" description="Scannable listings for public and operational events." />
|
||||
</div>
|
||||
</BaseLayout>
|
||||
@@ -0,0 +1,80 @@
|
||||
---
|
||||
import BaseLayout from '../layouts/BaseLayout.astro';
|
||||
import NoticeBanner from '../components/NoticeBanner.astro';
|
||||
import FuelPricesWidget from '../components/FuelPricesWidget.astro';
|
||||
import EventsList from '../components/EventsList.astro';
|
||||
import NewsFeed from '../components/NewsFeed.astro';
|
||||
import { homepageHighlights, site } from '../lib/site';
|
||||
import { getEvents, getFuelPrices, getNews, getNotices } from '../lib/directus';
|
||||
|
||||
const [notices, fuelPrices, events, news] = await Promise.all([
|
||||
getNotices(),
|
||||
getFuelPrices(),
|
||||
getEvents(),
|
||||
getNews(),
|
||||
]);
|
||||
|
||||
const featuredEvents = events.filter((event) => event.is_featured).slice(0, 3);
|
||||
const latestNews = news.slice(0, 3);
|
||||
---
|
||||
|
||||
<BaseLayout title="Home" description="Fast, clear airfield information for pilots and visitors.">
|
||||
<section class="hero">
|
||||
<div class="container hero-grid">
|
||||
<div class="hero-panel">
|
||||
<p class="eyebrow">Operational website</p>
|
||||
<h1 class="hero-title">Clear airfield information, built for speed.</h1>
|
||||
<p class="hero-copy">
|
||||
Visitor-critical information stays visible up front, while Directus supplies notices, news, events, and fuel pricing at build time.
|
||||
</p>
|
||||
<div class="cta-row">
|
||||
<a class="button primary" href="/visiting-pilots/">Visiting pilots</a>
|
||||
<a class="button secondary" href="/procedures-safety-noise-abatement/">Procedures and safety</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<aside class="hero-rail">
|
||||
<div class="surface">
|
||||
<p class="eyebrow">Today at the airfield</p>
|
||||
<div class="stats-grid">
|
||||
<div class="stat">
|
||||
<strong>{site.openingHours}</strong>
|
||||
<span class="muted">Opening hours</span>
|
||||
</div>
|
||||
<div class="stat">
|
||||
<strong>{site.licensedHours}</strong>
|
||||
<span class="muted">Licensed hours</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="surface">
|
||||
<p class="eyebrow">Runway overview</p>
|
||||
<ul class="compact-list">
|
||||
{site.runwayFacts.map((fact) => (
|
||||
<li>{fact}</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</aside>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="container stack">
|
||||
<NoticeBanner notices={notices} />
|
||||
<FuelPricesWidget fuelPrices={fuelPrices} />
|
||||
|
||||
<section>
|
||||
<div class="cards-grid">
|
||||
{homepageHighlights.map((item) => (
|
||||
<article class="card">
|
||||
<h3>{item.title}</h3>
|
||||
<p>{item.body}</p>
|
||||
</article>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<EventsList events={featuredEvents} title="Upcoming events" description="Featured events are surfaced here first for quick scanning." />
|
||||
<NewsFeed news={latestNews} />
|
||||
</div>
|
||||
</BaseLayout>
|
||||
@@ -0,0 +1,23 @@
|
||||
---
|
||||
import BaseLayout from '../../layouts/BaseLayout.astro';
|
||||
import { getNews } from '../../lib/directus';
|
||||
import { formatDate } from '../../lib/format';
|
||||
|
||||
type NewsItem = Awaited<ReturnType<typeof getNews>>[number];
|
||||
|
||||
export async function getStaticPaths() {
|
||||
const news = await getNews();
|
||||
return news.map((item) => ({ params: { slug: item.slug }, props: { item } }));
|
||||
}
|
||||
|
||||
const { item } = Astro.props as { item: NewsItem };
|
||||
---
|
||||
|
||||
<BaseLayout title={item.title} description={item.summary}>
|
||||
<article class="container prose">
|
||||
<p class="meta">Published {formatDate(item.publish_date)}</p>
|
||||
<h1 class="section-title">{item.title}</h1>
|
||||
<p>{item.summary}</p>
|
||||
<div set:html={item.body} />
|
||||
</article>
|
||||
</BaseLayout>
|
||||
@@ -0,0 +1,13 @@
|
||||
---
|
||||
import BaseLayout from '../../layouts/BaseLayout.astro';
|
||||
import NewsFeed from '../../components/NewsFeed.astro';
|
||||
import { getNews } from '../../lib/directus';
|
||||
|
||||
const news = (await getNews()).sort((left, right) => new Date(right.publish_date).getTime() - new Date(left.publish_date).getTime());
|
||||
---
|
||||
|
||||
<BaseLayout title="News" description="Latest airport news and operational updates.">
|
||||
<div class="container">
|
||||
<NewsFeed news={news} title="All news" description="Read the latest public updates and operational announcements." />
|
||||
</div>
|
||||
</BaseLayout>
|
||||
@@ -0,0 +1,29 @@
|
||||
---
|
||||
import BaseLayout from '../layouts/BaseLayout.astro';
|
||||
---
|
||||
|
||||
<BaseLayout title="Procedures, Safety and Noise Abatement" description="Operational procedures, safety notes, and noise-sensitive guidance.">
|
||||
<div class="container prose">
|
||||
<p class="eyebrow">Operations</p>
|
||||
<h1 class="section-title">Procedures, safety, and noise abatement</h1>
|
||||
<p>
|
||||
This page is intentionally text-led and easy to scan. It is controlled by Astro so the structure stays stable even as the content evolves.
|
||||
</p>
|
||||
|
||||
<h2>Safety priorities</h2>
|
||||
<div class="cards-grid">
|
||||
<article class="card">
|
||||
<h3>Brief before flight</h3>
|
||||
<p>Surface the checklist items pilots need most, without burying them under visual clutter.</p>
|
||||
</article>
|
||||
<article class="card">
|
||||
<h3>Check current notices</h3>
|
||||
<p>Operational notices should be reviewed before taxi, because the homepage is fed by the same notices collection.</p>
|
||||
</article>
|
||||
<article class="card">
|
||||
<h3>Respect local noise guidance</h3>
|
||||
<p>Noise abatement text can be expanded in Directus while the page structure stays fixed in code.</p>
|
||||
</article>
|
||||
</div>
|
||||
</div>
|
||||
</BaseLayout>
|
||||
@@ -0,0 +1,35 @@
|
||||
---
|
||||
import BaseLayout from '../layouts/BaseLayout.astro';
|
||||
import { site } from '../lib/site';
|
||||
---
|
||||
|
||||
<BaseLayout title="Visiting Pilots" description="Essential information for pilots planning a visit to Swansea Airport.">
|
||||
<div class="container prose">
|
||||
<p class="eyebrow">Visiting pilots</p>
|
||||
<h1 class="section-title">Essential information for arriving aircraft</h1>
|
||||
<p>
|
||||
This page is structured for quick pre-flight checks. It keeps operational details in fixed Astro components and leaves content updates to Directus.
|
||||
</p>
|
||||
|
||||
<h2>Airport facts</h2>
|
||||
<ul>
|
||||
{site.runwayFacts.map((fact) => <li>{fact}</li>)}
|
||||
</ul>
|
||||
|
||||
<h2>Arrival essentials</h2>
|
||||
<div class="cards-grid">
|
||||
<article class="card">
|
||||
<h3>PPR</h3>
|
||||
<p>Pre-landing fogging is presented prominently here and can be linked to the relevant Directus content or booking workflow.</p>
|
||||
</article>
|
||||
<article class="card">
|
||||
<h3>Book out</h3>
|
||||
<p>Departure procedures and any required outbound reporting remain in the same controlled page structure.</p>
|
||||
</article>
|
||||
<article class="card">
|
||||
<h3>Fuel and services</h3>
|
||||
<p>Fuel prices are shown on the homepage and can be reused here with the same data source.</p>
|
||||
</article>
|
||||
</div>
|
||||
</div>
|
||||
</BaseLayout>
|
||||
Reference in New Issue
Block a user