CTAO portal demo (Astro + Sveltia)

This commit is contained in:
ctao
2026-07-24 18:09:00 +02:00
commit a1c85d73c7
16 changed files with 6118 additions and 0 deletions
+15
View File
@@ -0,0 +1,15 @@
---
import Base from '../layouts/Base.astro';
---
<Base title="CTAO Portal — Dashboard" description="Panel z danymi z innych serwisów">
<section class="container page">
<div class="placeholder">
<div>
<div class="big">📡</div>
<h1>Dashboard</h1>
<p>Tu trafią dane z innych serwisów (monitoring sieci teleskopów, statusy, wykresy).<br/>
To część <strong>dynamiczna</strong> — utrzymywana osobno od statycznych treści.</p>
</div>
</div>
</section>
</Base>
+29
View File
@@ -0,0 +1,29 @@
---
import { getCollection } from 'astro:content';
import Base from '../layouts/Base.astro';
const posts = (await getCollection('news', ({ data }) => !data.draft)).sort(
(a, b) => b.data.date.valueOf() - a.data.date.valueOf(),
);
const fmt = (d) => new Intl.DateTimeFormat('pl-PL', { dateStyle: 'long' }).format(d);
---
<Base title="CTAO Portal — Newsy" description="Aktualności obserwatorium CTAO">
<section class="container hero">
<div class="eyebrow">Cherenkov Telescope Array Observatory</div>
<h1>Aktualności i ogłoszenia</h1>
<p>Najnowsze informacje z sieci teleskopów CTAO. Treść zarządzana przez edytorów w graficznym CMS-ie, publikowana jako statyczna strona.</p>
</section>
<section class="container">
<div class="grid">
{posts.map((post) => (
<article class="card">
<span class="cat">{post.data.category}</span>
<h3><a href={`/news/${post.id}`}>{post.data.title}</a></h3>
<p>{post.data.description}</p>
<div class="meta">{post.data.author} · {fmt(post.data.date)}</div>
</article>
))}
</div>
</section>
</Base>
+23
View File
@@ -0,0 +1,23 @@
---
import { getCollection, render } from 'astro:content';
import Base from '../../layouts/Base.astro';
export async function getStaticPaths() {
const posts = await getCollection('news', ({ data }) => !data.draft);
return posts.map((post) => ({ params: { slug: post.id }, props: { post } }));
}
const { post } = Astro.props;
const { Content } = await render(post);
const fmt = (d) => new Intl.DateTimeFormat('pl-PL', { dateStyle: 'long' }).format(d);
---
<Base title={`${post.data.title} — CTAO`} description={post.data.description}>
<article class="container article">
<a class="back" href="/">← Wszystkie newsy</a>
<h1>{post.data.title}</h1>
<div class="meta">{post.data.category} · {post.data.author} · {fmt(post.data.date)}</div>
<div class="prose">
<Content />
</div>
</article>
</Base>
+45
View File
@@ -0,0 +1,45 @@
---
import Base from '../layouts/Base.astro';
---
<Base title="CTAO Portal — Teleskopy" description="Rejestracja i rezerwacja czasu obserwacyjnego">
<section class="container hero">
<div class="eyebrow">Rejestracja</div>
<h1>Zgłoszenie obserwacji</h1>
<p>Mockup formularza rejestracji/rezerwacji czasu na teleskopach CTAO. To makieta — bez logiki wysyłki.</p>
</section>
<section class="container page">
<div class="panel" style="max-width:640px">
<div class="form-row">
<label>Tytuł propozycji</label>
<input type="text" placeholder="np. Obserwacja rozbłysków AGN" />
</div>
<div class="form-row">
<label>Teleskop</label>
<select>
<option>LST-1 (Large Size Telescope)</option>
<option>MST (Medium Size Telescope)</option>
<option>SST (Small Size Telescope)</option>
</select>
</div>
<div class="form-row">
<label>Zakres energii</label>
<select>
<option>20 GeV – 3 TeV</option>
<option>80 GeV – 50 TeV</option>
<option>1 TeV – 300 TeV</option>
</select>
</div>
<div class="form-row">
<label>Wymagany czas (godziny)</label>
<input type="number" min="1" placeholder="np. 25" />
</div>
<div class="form-row">
<label>Uzasadnienie naukowe</label>
<textarea rows="4" placeholder="Krótki opis celu obserwacji..."></textarea>
</div>
<button class="btn" type="button">Wyślij zgłoszenie</button>
<p class="notice">Makieta demonstracyjna — formularz nie zapisuje danych.</p>
</div>
</section>
</Base>