Skip to content

Commit 9fdff03

Browse files
committed
show more news
1 parent 247a926 commit 9fdff03

File tree

5 files changed

+125
-7
lines changed

5 files changed

+125
-7
lines changed

src/components/NavBar.astro

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,14 @@ const p = useLocalePages(Astro.currentLocale);
110110
{t('data.title')}
111111
</a>
112112

113+
<a
114+
class="flex items-center p-2 text-sm text-white/80 hover:text-white focus:text-white focus:outline-hidden"
115+
href={p('news')}
116+
>
117+
<Icon name="mdi:newspaper-variant-outline" class="me-3 block size-4 shrink-0 md:me-2 md:hidden" />
118+
{t('news.nav')}
119+
</a>
120+
113121
<a
114122
class="flex items-center p-2 text-sm text-white/80 hover:text-white focus:text-white focus:outline-hidden"
115123
href={p('references')}

src/components/News.astro

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
---
22
import {getCollection} from 'astro:content';
3-
import {asLocale, slugToPostLink, useTranslations} from '../i18n/utils';
3+
import {asLocale, slugToPostLink, useTranslations, useLocalePages} from '../i18n/utils';
44
import {Image} from 'astro:assets';
55
import {mdExcerpt, pictureWidths} from './utils';
66
77
const pageLang = Astro.currentLocale;
88
const t = useTranslations(pageLang);
9+
const p = useLocalePages(pageLang);
910
1011
const pages = await getCollection('posts', (entry) => {
1112
const [lang, ...slug] = entry.slug.split('/');
@@ -149,13 +150,13 @@ const newsItems: Array<{
149150
</div>
150151
<!-- End Grid -->
151152

152-
<!-- Card -->
153-
<!-- <div class="mt-12 text-center">
153+
<!-- View All Posts Link -->
154+
<div class="mt-12 text-center">
154155
<a
155156
class="text-main-green dark:text-main-green inline-flex items-center gap-x-1 rounded-full border border-gray-200 bg-white px-4 py-3 text-sm font-medium shadow-2xs hover:bg-gray-50 focus:bg-gray-50 focus:outline-hidden disabled:pointer-events-none disabled:opacity-50 dark:border-neutral-700 dark:bg-neutral-900 dark:hover:bg-neutral-800 dark:focus:bg-neutral-800"
156-
href="#"
157+
href={p('news')}
157158
>
158-
Read more
159+
{t('news.viewAll')}
159160
<svg
160161
class="size-4 shrink-0"
161162
xmlns="http://www.w3.org/2000/svg"
@@ -169,7 +170,7 @@ const newsItems: Array<{
169170
stroke-linejoin="round"><path d="m9 18 6-6-6-6"></path></svg
170171
>
171172
</a>
172-
</div> -->
173-
<!-- End Card -->
173+
</div>
174+
<!-- End View All Posts Link -->
174175
</div>
175176
<!-- End Card Blog -->

src/i18n/translations.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,11 @@ export const translations = {
6363
'references.title': 'Referenzen & Beispiele',
6464
'references.intro':
6565
'Hier finden Sie einige Beispiele für unsere Arbeit. Diese Projekte zeigen, wie wir Geodaten und Zeitreihenverarbeitung in verschiedenen Anwendungsfällen einsetzen.',
66+
'news.nav': 'Neuigkeiten',
6667
'news.title': 'Neueste Beiträge',
6768
'news.subtitle': 'Bleiben Sie auf dem Laufenden mit unseren neuesten Nachrichten und Updates.',
69+
'news.allPosts': 'Alle Beiträge',
70+
'news.viewAll': 'Alle Beiträge anzeigen',
6871
'footer.info': 'Informationen',
6972
'footer.documentation': 'Dokumentation',
7073
'footer.privacyPolicy': 'Datenschutzerklärung',
@@ -146,8 +149,11 @@ export const translations = {
146149
'references.title': 'References & Examples',
147150
'references.intro':
148151
'Here you will find some examples of our work. These projects show how we use geodata and time series processing in various applications.',
152+
'news.nav': 'News',
149153
'news.title': 'Latest Posts',
150154
'news.subtitle': 'Stay up to date with our latest news and updates.',
155+
'news.allPosts': 'All Posts',
156+
'news.viewAll': 'View all posts',
151157
'footer.info': 'Information',
152158
'footer.documentation': 'Documentation',
153159
'footer.privacyPolicy': 'Privacy Policy',
@@ -185,6 +191,7 @@ export const pages = {
185191
privacyPolicy: '/datenschutzerklaerung/',
186192
references: '/beispiele-referenzen/',
187193
services: '/services/',
194+
news: '/neuigkeiten/',
188195
404: '/404/',
189196
},
190197
en: {
@@ -197,6 +204,7 @@ export const pages = {
197204
privacyPolicy: '/en/privacy-policy/',
198205
references: '/en/examples-references/',
199206
services: '/en/services/',
207+
news: '/en/news/',
200208
404: '/en/404/',
201209
},
202210
} as const;

src/pages/en/news.astro

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
import Page from '../neuigkeiten.astro';
3+
---
4+
5+
<Page />

src/pages/neuigkeiten.astro

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
---
2+
import {getCollection} from 'astro:content';
3+
import {asLocale, slugToPostLink, useTranslations} from '../i18n/utils';
4+
import {Image} from 'astro:assets';
5+
import {mdExcerpt, pictureWidths} from '../components/utils';
6+
import Section from '../components/Section.astro';
7+
import Layout from '../layouts/Layout.astro';
8+
9+
const t = useTranslations(Astro.currentLocale);
10+
11+
const pageLang = Astro.currentLocale;
12+
13+
const pages = await getCollection('posts', (entry) => {
14+
const [lang, ...slug] = entry.slug.split('/');
15+
if (lang !== pageLang) {
16+
return undefined;
17+
}
18+
return entry;
19+
});
20+
21+
pages.sort((a, b) => b.data.date.getTime() - a.data.date.getTime());
22+
23+
const paths = pages.map((page) => {
24+
const [lang, ...slug] = page.slug.split('/');
25+
if (slug.length === 0) {
26+
throw new Error(`Empty slug: ${page.slug}`);
27+
}
28+
return {params: {lang: asLocale(lang), slug: slug.join('/')}, props: page};
29+
});
30+
31+
const newsItems: Array<{
32+
title: string;
33+
date: string;
34+
image: ImageMetadata;
35+
abstract: string;
36+
link: string;
37+
}> = paths.map((page) => {
38+
return {
39+
title: page.props.data.title,
40+
date: page.props.data.date.toLocaleDateString(pageLang, {
41+
year: 'numeric',
42+
month: 'long',
43+
day: 'numeric',
44+
}),
45+
image: page.props.data.image,
46+
abstract: mdExcerpt(page.props.body, 200),
47+
link: slugToPostLink(page.params.lang, page.params.slug),
48+
};
49+
});
50+
---
51+
52+
<Layout title={t('news.allPosts')} description={t('news.subtitle')}>
53+
<Section>
54+
<!-- Title -->
55+
<div class="mx-auto mb-10 max-w-2xl text-center lg:mb-14">
56+
<h1 class="text-3xl font-bold md:text-4xl md:leading-tight dark:text-white">{t('news.allPosts')}</h1>
57+
<p class="mt-1 text-gray-600 dark:text-neutral-400">
58+
{t('news.subtitle')}
59+
</p>
60+
</div>
61+
<!-- End Title -->
62+
63+
<!-- Grid -->
64+
<div class="grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
65+
<!-- Cards -->
66+
{
67+
newsItems.map((news) => (
68+
<a
69+
class="group flex h-full flex-col rounded-xl border border-gray-200 p-5 transition duration-300 hover:border-transparent hover:shadow-lg focus:border-transparent focus:shadow-lg focus:outline-hidden dark:border-neutral-700 dark:hover:border-transparent dark:hover:shadow-black/40 dark:focus:border-transparent dark:focus:shadow-black/40"
70+
href={news.link}
71+
>
72+
<Image
73+
class="aspect-video w-full rounded-xl object-cover"
74+
src={news.image}
75+
alt={news.title}
76+
widths={pictureWidths()}
77+
/>
78+
<div class="my-6">
79+
<h3 class="text-xl font-semibold text-gray-800 dark:text-neutral-300 dark:group-hover:text-white">
80+
{news.title}
81+
</h3>
82+
<p class="mt-5 text-gray-600 dark:text-neutral-400">{news.abstract}</p>
83+
</div>
84+
<div class="mt-auto flex items-center gap-x-3">
85+
<div>
86+
<h5 class="text-sm text-gray-800 dark:text-neutral-200">{news.date}</h5>
87+
</div>
88+
</div>
89+
</a>
90+
))
91+
}
92+
<!-- End Cards -->
93+
</div>
94+
<!-- End Grid -->
95+
</Section>
96+
</Layout>

0 commit comments

Comments
 (0)