feat(privat/CV): sync to latest upstream (cv-upstream/main, 30f9608b)
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
import React, { useState } from 'react'
|
||||
import { Link } from 'react-router-dom'
|
||||
import { useContent, useContentTags } from '../hooks/useContent'
|
||||
import { formatDate } from '../utils/formatDate'
|
||||
|
||||
export default function Kniepunkt() {
|
||||
const [tag, setTag] = useState(null)
|
||||
const [page, setPage] = useState(1)
|
||||
const { items, totalPages, hasNext, hasPrev } = useContent('kniepunkt', { tag, page })
|
||||
const tags = useContentTags('kniepunkt')
|
||||
|
||||
return (
|
||||
<main style={{ paddingTop: '120px', minHeight: '100vh' }}>
|
||||
<div className="app-container">
|
||||
<div className="section-header">
|
||||
<h1 className="section-title"><span className="text-gradient">Kniepunkt</span></h1>
|
||||
<p className="section-subtitle">Wöchentliche KI-Kolumne. Nachrichten und Absurditäten rund um KI.</p>
|
||||
</div>
|
||||
|
||||
{tags.length > 0 && (
|
||||
<div style={{ display: 'flex', gap: '8px', flexWrap: 'wrap', justifyContent: 'center', marginBottom: '40px' }}>
|
||||
<button onClick={() => setTag(null)} className={`secondary-button ${!tag ? 'active' : ''}`} style={{ padding: '8px 16px', fontSize: '0.85rem' }}>Alle</button>
|
||||
{tags.map(t => (
|
||||
<button key={t} onClick={() => { setTag(t); setPage(1) }} className={`secondary-button ${tag === t ? 'active' : ''}`} style={{ padding: '8px 16px', fontSize: '0.85rem' }}>{t}</button>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: '16px', maxWidth: '700px', margin: '0 auto' }}>
|
||||
{items.map(issue => (
|
||||
<Link to={`/kniepunkt/${issue.slug}`} key={issue.slug} className="glass-panel" style={{ padding: '24px', display: 'block', transition: 'transform 0.3s ease' }}>
|
||||
<h3 style={{ marginBottom: '8px' }}>{issue.title}</h3>
|
||||
<p style={{ color: 'var(--text-secondary)', margin: 0, fontSize: '0.9rem' }}>{formatDate(issue.date)}</p>
|
||||
{issue.summary && <p style={{ color: 'var(--text-secondary)', margin: '8px 0 0', fontSize: '0.95rem' }}>{issue.summary}</p>}
|
||||
</Link>
|
||||
))}
|
||||
{items.length === 0 && <p style={{ textAlign: 'center', color: 'var(--text-secondary)' }}>Noch keine Ausgaben vorhanden.</p>}
|
||||
</div>
|
||||
|
||||
{totalPages > 1 && (
|
||||
<div style={{ display: 'flex', justifyContent: 'center', gap: '16px', marginTop: '40px' }}>
|
||||
{hasPrev && <button onClick={() => setPage(p => p - 1)} className="secondary-button">Zurück</button>}
|
||||
<span style={{ color: 'var(--text-secondary)', alignSelf: 'center' }}>Seite {page} / {totalPages}</span>
|
||||
{hasNext && <button onClick={() => setPage(p => p + 1)} className="secondary-button">Weiter</button>}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</main>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user