import { useCallback, useEffect, useState } from 'react'; import { ActivityIndicator, KeyboardAvoidingView, Modal, Platform, Pressable, StyleSheet, Text, TextInput, View, } from 'react-native'; import { createResourceHistoryItem, fetchResourceHistory, HistoryItem, } from '@/src/lib/api'; import { useAuth } from '@/src/providers/auth-provider'; const PRIMARY = '#69c350'; type HistorySectionProps = { resource: string; resourceId: number | string; }; function formatDateTime(value: unknown): string { if (!value) return '-'; const date = new Date(String(value)); if (Number.isNaN(date.getTime())) return String(value); return date.toLocaleString('de-DE', { day: '2-digit', month: '2-digit', year: '2-digit', hour: '2-digit', minute: '2-digit', }); } function getAuthor(item: HistoryItem): string { if (!item.created_by && !item.createdBy) return 'FEDEO Bot'; return String( item.created_by_profile?.full_name || item.created_by_profile?.fullName || item.created_by_profile?.email || 'Benutzer' ); } export function HistorySection({ resource, resourceId }: HistorySectionProps) { const { token } = useAuth(); const [items, setItems] = useState([]); const [loading, setLoading] = useState(true); const [loadError, setLoadError] = useState(null); const [formError, setFormError] = useState(null); const [modalOpen, setModalOpen] = useState(false); const [text, setText] = useState(''); const [saving, setSaving] = useState(false); const load = useCallback(async () => { if (!token || !resource || !resourceId) return; setLoading(true); setLoadError(null); try { const rows = await fetchResourceHistory(token, resource, resourceId); setItems((rows || []).slice().reverse()); } catch (err) { setLoadError(err instanceof Error ? err.message : 'Das Logbuch konnte nicht geladen werden.'); } finally { setLoading(false); } }, [resource, resourceId, token]); useEffect(() => { void load(); }, [load]); function closeModal() { if (saving) return; setModalOpen(false); setText(''); setFormError(null); } async function addItem() { if (!token || saving) return; const value = text.trim(); if (!value) { setFormError('Bitte einen Text für den Logbucheintrag eingeben.'); return; } setSaving(true); setFormError(null); try { await createResourceHistoryItem(token, resource, resourceId, value); setModalOpen(false); setText(''); await load(); } catch (err) { setFormError(err instanceof Error ? err.message : 'Der Logbucheintrag konnte nicht gespeichert werden.'); } finally { setSaving(false); } } return ( Logbuch ({items.length}) setModalOpen(true)}> + Eintrag {loading ? : null} {!loading && loadError ? {loadError} : null} {!loading && !loadError && items.length === 0 ? ( Noch keine Logbucheinträge vorhanden. ) : null} {!loading && !loadError ? items.map((item) => ( {getAuthor(item)} {item.text} {formatDateTime(item.created_at || item.createdAt)} )) : null} Logbucheintrag hinzufügen {formError ? {formError} : null} Abbrechen {saving ? 'Speichere...' : 'Speichern'} ); } const styles = StyleSheet.create({ card: { backgroundColor: '#ffffff', borderRadius: 12, borderWidth: 1, borderColor: '#e5e7eb', padding: 12, gap: 8, }, header: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', gap: 10, }, title: { color: '#111827', fontSize: 16, fontWeight: '700' }, addButton: { minHeight: 36, borderRadius: 8, backgroundColor: PRIMARY, paddingHorizontal: 12, alignItems: 'center', justifyContent: 'center', }, addButtonText: { color: '#ffffff', fontSize: 13, fontWeight: '700' }, item: { borderTopWidth: 1, borderTopColor: '#e5e7eb', paddingTop: 9, gap: 2, }, itemAuthor: { color: '#111827', fontSize: 13, fontWeight: '700' }, itemText: { color: '#374151', fontSize: 14, lineHeight: 20 }, itemDate: { color: '#6b7280', fontSize: 12 }, empty: { color: '#6b7280', fontSize: 13, paddingVertical: 4 }, error: { color: '#dc2626', fontSize: 13 }, modalOverlay: { flex: 1, backgroundColor: 'rgba(17, 24, 39, 0.45)', justifyContent: 'center', padding: 20, }, modalKeyboardWrap: { width: '100%' }, modalCard: { backgroundColor: '#ffffff', borderRadius: 14, padding: 16, gap: 12 }, modalTitle: { color: '#111827', fontSize: 18, fontWeight: '700' }, input: { minHeight: 120, borderWidth: 1, borderColor: '#d1d5db', borderRadius: 10, paddingHorizontal: 12, paddingVertical: 10, color: '#111827', fontSize: 15, textAlignVertical: 'top', }, modalActions: { flexDirection: 'row', justifyContent: 'flex-end', gap: 8 }, secondaryButton: { minHeight: 40, borderWidth: 1, borderColor: '#d1d5db', borderRadius: 10, paddingHorizontal: 14, alignItems: 'center', justifyContent: 'center', }, secondaryButtonText: { color: '#374151', fontWeight: '600' }, primaryButton: { minHeight: 40, borderRadius: 10, backgroundColor: PRIMARY, paddingHorizontal: 14, alignItems: 'center', justifyContent: 'center', }, primaryButtonText: { color: '#ffffff', fontWeight: '700' }, disabled: { opacity: 0.6 }, });