Some checks failed
Build + Deploy / build-backend-compliance (push) Successful in 2m43s
Build + Deploy / build-admin-compliance (push) Successful in 1m46s
Build + Deploy / build-ai-sdk (push) Successful in 47s
Build + Deploy / build-developer-portal (push) Successful in 1m0s
Build + Deploy / build-tts (push) Successful in 1m14s
Build + Deploy / build-document-crawler (push) Successful in 37s
Build + Deploy / build-dsms-gateway (push) Successful in 20s
CI / branch-name (push) Has been skipped
CI / guardrail-integrity (push) Has been skipped
CI / loc-budget (push) Failing after 19s
CI / secret-scan (push) Has been skipped
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / nodejs-build (push) Successful in 2m35s
CI / dep-audit (push) Has been skipped
CI / sbom-scan (push) Has been skipped
CI / test-go (push) Successful in 42s
CI / test-python-backend (push) Successful in 42s
CI / test-python-document-crawler (push) Successful in 24s
CI / test-python-dsms-gateway (push) Successful in 27s
CI / validate-canonical-controls (push) Successful in 23s
Build + Deploy / trigger-orca (push) Failing after 2h32m34s
Zeigt anstehende regulatorische Fristen im Dashboard an, abgeleitet aus den bestehenden Obligation v2 JSON-Dateien. Keine neue DB-Tabelle. Erster News-Eintrag: Widerrufsbutton-Pflicht ab 19.06.2026 (EU-RL 2023/2673, §356a BGB) — eigener Text, keine externe Quelle. Features: - Go Service: scannt Obligations nach Fristen, berechnet Urgency - API: GET /sdk/v1/regulatory-news mit Countdown + Farbcodierung - Dashboard: RegulatoryNewsFeed Sektion mit Countdown-Badges - Vorlage: news-Feld in v2 JSON fuer zukuenftige regulatorische Updates - 11 Tests (Sortierung, Urgency, Deadline-Parsing, Real-File-Test) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
55 lines
1.7 KiB
TypeScript
55 lines
1.7 KiB
TypeScript
'use client'
|
|
|
|
import React, { useState, useEffect } from 'react'
|
|
import { RegulatoryNewsCard, RegulatoryNewsItemData } from './RegulatoryNewsCard'
|
|
|
|
interface RegulatoryNewsFeedProps {
|
|
businessModel?: string
|
|
maxItems?: number
|
|
}
|
|
|
|
export function RegulatoryNewsFeed({ businessModel, maxItems = 3 }: RegulatoryNewsFeedProps) {
|
|
const [items, setItems] = useState<RegulatoryNewsItemData[]>([])
|
|
const [loading, setLoading] = useState(true)
|
|
const [showAll, setShowAll] = useState(false)
|
|
|
|
useEffect(() => {
|
|
const params = new URLSearchParams({ limit: '10', horizon_days: '365' })
|
|
if (businessModel) params.set('business_model', businessModel)
|
|
|
|
fetch(`/api/sdk/v1/regulatory-news?${params}`)
|
|
.then(r => r.ok ? r.json() : { items: [] })
|
|
.then(data => setItems(data.items || []))
|
|
.catch(() => setItems([]))
|
|
.finally(() => setLoading(false))
|
|
}, [businessModel])
|
|
|
|
if (loading) return null
|
|
if (items.length === 0) return null
|
|
|
|
const visible = showAll ? items : items.slice(0, maxItems)
|
|
|
|
return (
|
|
<div className="space-y-3">
|
|
<div className="flex items-center justify-between">
|
|
<h2 className="text-lg font-semibold text-gray-900 flex items-center gap-2">
|
|
<span>📢</span> Regulatorische Neuigkeiten
|
|
</h2>
|
|
{items.length > maxItems && (
|
|
<button
|
|
onClick={() => setShowAll(!showAll)}
|
|
className="text-sm text-blue-600 hover:underline"
|
|
>
|
|
{showAll ? 'Weniger' : `Alle ${items.length} anzeigen`}
|
|
</button>
|
|
)}
|
|
</div>
|
|
<div className="space-y-2">
|
|
{visible.map(item => (
|
|
<RegulatoryNewsCard key={item.id} item={item} />
|
|
))}
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|