Files
Orchestrator/privat/CV/andreknie.de/src/pages/Kniepunkt.jsx
T

78 lines
3.8 KiB
React

import React, { useState } from 'react'
import { Link } from 'react-router-dom'
import { Search } from 'lucide-react'
import { useContent } from '../hooks/useContent'
import { formatDate } from '../utils/formatDate'
import { decodeHtml } from '../utils/decodeHtml'
import SEOHead from '../components/SEOHead'
export default function Kniepunkt() {
const [searchQuery, setSearchQuery] = useState('')
const { items } = useContent('kniepunkt', { pageSize: 1000 })
const filteredItems = items.filter(item => {
if (!searchQuery) return true
const query = searchQuery.toLowerCase()
return (
(item.title && item.title.toLowerCase().includes(query)) ||
(item.summary && item.summary.toLowerCase().includes(query)) ||
(item.body && item.body.toLowerCase().includes(query))
)
})
return (
<main style={{ paddingTop: '120px', minHeight: '100vh' }}>
<SEOHead title="Kniepunkt" description="Die Kniepunkt-Kolumne von Dr. André Knie über KI, Technologie und die Absurditäten des digitalen Wandels." url="/kniepunkt" />
<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>
<div style={{ maxWidth: '700px', margin: '0 auto 40px auto', position: 'relative' }}>
<div style={{ position: 'absolute', left: '16px', top: '50%', transform: 'translateY(-50%)', color: 'var(--text-secondary)' }}>
<Search size={20} />
</div>
<input
type="text"
placeholder="Kniepunkte durchsuchen..."
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
style={{
width: '100%',
padding: '16px 80px 16px 48px',
borderRadius: '12px',
border: '1px solid rgba(255,255,255,0.1)',
background: 'var(--glass-bg)',
color: 'var(--text-primary)',
fontSize: '1rem',
outline: 'none'
}}
/>
<div style={{ position: 'absolute', right: '16px', top: '50%', transform: 'translateY(-50%)', color: 'var(--text-secondary)', fontSize: '0.9rem' }}>
{filteredItems?.length || 0} / {items?.length || 0}
</div>
</div>
<div style={{ display: 'flex', flexDirection: 'column', gap: '16px', maxWidth: '700px', margin: '0 auto' }}>
{filteredItems.map(issue => (
<Link to={`/kniepunkt/${issue.slug}`} key={issue.slug} className="glass-panel" style={{ padding: '0', display: 'flex', flexDirection: 'column', transition: 'transform 0.3s ease', overflow: 'hidden' }}>
{issue.image && (
<div style={{ width: '100%', height: '240px', overflow: 'hidden' }}>
<img src={issue.image.replace('.webp', '-thumb.webp')} alt={decodeHtml(issue.title)} loading="lazy" style={{ width: '100%', height: '100%', objectFit: 'cover', borderBottom: '1px solid rgba(255,255,255,0.1)' }} />
</div>
)}
<div style={{ padding: '24px' }}>
<h3 style={{ marginBottom: '8px' }}>{decodeHtml(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' }}>{decodeHtml(issue.summary)}</p>}
</div>
</Link>
))}
{filteredItems.length === 0 && <p style={{ textAlign: 'center', color: 'var(--text-secondary)' }}>Keine Kniepunkte für diese Suche gefunden.</p>}
</div>
</div>
</main>
)
}