Done
linter / quality (push) Has been cancelled
tests / ci (8.3) (push) Has been cancelled
tests / ci (8.4) (push) Has been cancelled
tests / ci (8.5) (push) Has been cancelled

This commit is contained in:
2026-07-04 23:09:00 +10:00
parent 0485b85a59
commit 439139a057
50 changed files with 2405 additions and 548 deletions
+14 -252
View File
@@ -1,5 +1,6 @@
<script setup lang="ts">
import MainLayout from '@/layouts/MainLayout.vue';
import CategorySection from '@/components/CategorySection.vue';
defineOptions({
layout: MainLayout,
@@ -7,9 +8,11 @@ defineOptions({
interface Story {
source: string;
time: string;
time: string | null;
headline: string;
deck?: string;
deck?: string | null;
image?: string | null;
link: string;
}
interface Category {
@@ -18,152 +21,19 @@ interface Category {
items: Story[];
}
const categories: Category[] = [
{
label: 'Headlines',
hero: true,
items: [
{ source: 'Reuters', time: '42 minutes ago', headline: 'Leaders gather in Brussels as ceasefire talks enter critical third day', deck: 'Negotiators signalled cautious progress overnight, with both delegations agreeing to extend the informal moratorium on strikes.' },
{ source: 'Financial Times', time: '1 hour ago', headline: 'Markets edge higher on softer-than-expected inflation print', deck: 'Central banks signal caution as core inflation falls for the second consecutive month across G7 economies.' },
{ source: 'BBC News', time: '30 minutes ago', headline: 'Record heat across southern Europe for third week running' },
{ source: 'AP News', time: '55 minutes ago', headline: 'Congress reaches last-minute deal to avert government shutdown' },
{ source: 'The Guardian', time: '1 hour ago', headline: 'Tech giants face fresh scrutiny over data sharing practices' },
],
},
{
label: 'Australia',
hero: false,
items: [
{ source: 'ABC News', time: '8 minutes ago', headline: 'Treasurer signals pre-election budget revision in August' },
{ source: 'Sydney Morning Herald', time: '1 hour ago', headline: 'East coast housing approvals fall for third consecutive quarter' },
{ source: 'The Australian', time: '3 hours ago', headline: 'Queensland floods ease but thousands remain displaced' },
],
},
{
label: 'UK',
hero: false,
items: [
{ source: 'The Guardian', time: '20 minutes ago', headline: 'Prime Minister faces backbench revolt over public sector pay offer' },
{ source: 'BBC News', time: '1 hour ago', headline: 'London rents rise for twelfth consecutive month as supply tightens' },
{ source: 'The Times', time: '2 hours ago', headline: 'NHS waiting lists fall slightly but remain at historic highs' },
],
},
{
label: 'USA',
hero: false,
items: [
{ source: 'AP News', time: '15 minutes ago', headline: 'Congress reaches last-minute deal to avert government shutdown' },
{ source: 'Washington Post', time: '50 minutes ago', headline: 'Federal Reserve signals caution on further rate adjustments' },
{ source: 'New York Times', time: '2 hours ago', headline: 'Midwest storms leave hundreds of thousands without power' },
],
},
{
label: 'Politics',
hero: false,
items: [
{ source: 'Politico', time: '18 minutes ago', headline: 'Senate committee advances sweeping electoral reform bill' },
{ source: 'The Hill', time: '55 minutes ago', headline: 'Opposition leader calls for early election amid polling slump' },
{ source: 'AP News', time: '2 hours ago', headline: 'Foreign ministers meet in Geneva over disputed border region' },
],
},
{
label: 'Climate',
hero: false,
items: [
{ source: 'BBC News', time: '30 minutes ago', headline: 'Record heat across southern Europe for third week running' },
{ source: 'The Guardian', time: '1 hour ago', headline: 'Arctic sea ice extent hits lowest July measurement on record' },
{ source: 'Nature', time: '4 hours ago', headline: 'New modelling suggests 2°C target may be breached by 2031' },
],
},
{
label: 'Health',
hero: false,
items: [
{ source: 'Reuters', time: '25 minutes ago', headline: 'WHO recommends updated booster schedule ahead of winter' },
{ source: 'New Scientist', time: '2 hours ago', headline: "Trial drug shows promise in slowing early-onset Alzheimer's" },
{ source: 'The Lancet', time: '5 hours ago', headline: 'Childhood obesity rates plateau in high-income countries for first time' },
],
},
{
label: 'Sport',
hero: false,
items: [
{ source: 'The Guardian', time: '10 minutes ago', headline: 'Australian side advances after dramatic penalty shootout' },
{ source: 'ESPN', time: '1 hour ago', headline: 'Transfer window: three clubs circle record-breaking midfielder' },
{ source: 'Reuters', time: '3 hours ago', headline: 'Athletics world championships draw record television audience' },
],
},
{
label: 'Arts',
hero: false,
items: [
{ source: 'The New Yorker', time: '40 minutes ago', headline: 'Booker Prize longlist announced, debut novelists dominate' },
{ source: 'Pitchfork', time: '2 hours ago', headline: 'Acclaimed composer releases first album in seven years' },
{ source: 'Artforum', time: '6 hours ago', headline: 'Venice Biennale attendance surpasses pre-pandemic figures' },
],
},
];
defineProps<{
categories: Category[];
}>();
</script>
<template>
<div class="feed">
<section v-for="category in categories" :key="category.label" class="category">
<div class="category-header">
<span class="category-label">{{ category.label }}</span>
<a href="#" class="category-more">More</a>
</div>
<!-- Hero layout for flagged categories -->
<template v-if="category.hero">
<div class="hero-grid">
<a v-for="item in category.items.slice(0, 2)"
:key="item.headline"
href="#"
class="hero-story"
>
<div class="story-img story-img--hero" />
<div class="story-body">
<div class="story-source">{{ item.source }}</div>
<div class="story-headline story-headline--hero">{{ item.headline }}</div>
<div v-if="item.deck" class="story-deck">{{ item.deck }}</div>
<div class="story-time">{{ item.time }}</div>
</div>
</a>
</div>
<div class="story-grid">
<a v-for="item in category.items.slice(2)"
:key="item.headline"
href="#"
class="story"
>
<div class="story-img" />
<div class="story-body">
<div class="story-source">{{ item.source }}</div>
<div class="story-headline">{{ item.headline }}</div>
<div class="story-time">{{ item.time }}</div>
</div>
</a>
</div>
</template>
<!-- Standard 3-column grid -->
<div v-else class="story-grid">
<a v-for="item in category.items"
:key="item.headline"
href="#"
class="story"
>
<div class="story-img" />
<div class="story-body">
<div class="story-source">{{ item.source }}</div>
<div class="story-headline">{{ item.headline }}</div>
<div class="story-time">{{ item.time }}</div>
</div>
</a>
</div>
</section>
<CategorySection
v-for="(category, index) in categories"
:key="category.label"
:category="category"
:index="index"
/>
</div>
</template>
@@ -171,112 +41,4 @@ const categories: Category[] = [
.feed
display: flex
flex-direction: column
.category
border-bottom: 1px solid #E8E8E8
padding: 1.5rem 0
&:last-child
border-bottom: none
.category-header
display: flex
align-items: baseline
justify-content: space-between
margin-bottom: 1rem
.category-label
font-size: 10px
font-weight: 600
letter-spacing: 2px
text-transform: uppercase
color: #111
.category-more
font-size: 12px
color: #C0392B
text-decoration: none
&:hover
text-decoration: underline
// Hero grid (2 columns)
.hero-grid
display: grid
grid-template-columns: 1fr 1fr
gap: 1em
background: #E8E8E8
margin-bottom: 1px
.hero-story
background: #F7F7F5
text-decoration: none
display: flex
flex-direction: column
&:hover
background: #fff
// Standard story grid (3 columns)
.story-grid
display: grid
grid-template-columns: repeat(3, 1fr)
gap: 1px
background: #E8E8E8
.story
background: #F7F7F5
text-decoration: none
display: flex
flex-direction: column
&:hover
background: #fff
// Image placeholders
.story-img
width: 100%
height: 110px
background: #DDDDD8
flex-shrink: 0
&--hero
height: 200px
// Story body
.story-body
padding: 0.85rem
display: flex
flex-direction: column
gap: 5px
flex: 1
.story-source
font-size: 10px
font-weight: 600
letter-spacing: 1px
text-transform: uppercase
color: #C0392B
.story-headline
font-family: Georgia, serif
font-size: 13px
font-weight: 700
color: #111
line-height: 1.35
&--hero
font-size: 18px
line-height: 1.25
.story-deck
font-size: 12px
color: #555
line-height: 1.5
.story-time
font-size: 10px
color: #999
margin-top: auto
padding-top: 4px
</style>