/** * TitleSheet — suggère 3 titres IA dans un bottom sheet propre */ import { useState, useEffect } from 'react' import { View, Text, TouchableOpacity, ActivityIndicator, StyleSheet, } from 'react-native' import { Sparkles } from 'lucide-react-native' import { BottomSheet } from '@/components/BottomSheet' import { apiFetch } from '@/lib/api' import { ENDPOINTS } from '@/lib/config' import { C } from '@/lib/theme' interface Props { visible: boolean onClose: () => void content: string onSelect: (title: string) => void } export function TitleSheet({ visible, onClose, content, onSelect }: Props) { const [loading, setLoading] = useState(false) const [suggestions, setSuggestions] = useState([]) const [error, setError] = useState(null) useEffect(() => { if (visible && content.trim()) { fetchTitles() } }, [visible]) const fetchTitles = async () => { setLoading(true) setError(null) setSuggestions([]) try { const res = await apiFetch(ENDPOINTS.aiTitle, { method: 'POST', body: JSON.stringify({ content }), }) const d = await res.json().catch(() => ({})) if (!res.ok) { setError(d.error === 'quota_exceeded' ? 'Quota dépassé' : 'Erreur serveur') return } const raw: unknown[] = d.suggestions ?? [] setSuggestions(raw.map((s) => (typeof s === 'string' ? s : (s as any).title ?? '')).filter(Boolean)) } catch { setError('Erreur réseau') } finally { setLoading(false) } } const handleSelect = (t: string) => { onSelect(t) onClose() } return ( {loading && ( Génération des titres… )} {error && !loading && ( {error} Réessayer )} {!loading && !error && suggestions.length > 0 && ( {suggestions.map((t, i) => ( handleSelect(t)} style={s.row} activeOpacity={0.7}> {i + 1} {t} ))} )} {!loading && !error && suggestions.length === 0 && ( Aucune suggestion disponible )} ) } const s = StyleSheet.create({ center: { alignItems: 'center', paddingVertical: 32, gap: 12 }, hint: { fontSize: 14, color: C.concrete }, errorText: { fontSize: 14, color: '#e11d48' }, retryBtn: { paddingHorizontal: 20, paddingVertical: 10, borderRadius: 10, backgroundColor: C.border }, retryText: { fontSize: 13, color: C.ink, fontWeight: '600' }, list: { paddingHorizontal: 12, paddingTop: 8, paddingBottom: 8 }, row: { flexDirection: 'row', alignItems: 'center', gap: 12, paddingHorizontal: 12, paddingVertical: 14, borderRadius: 14, marginBottom: 8, backgroundColor: C.white, borderWidth: 1, borderColor: C.border, marginHorizontal: 8, }, numBadge: { width: 26, height: 26, borderRadius: 13, backgroundColor: '#f3ece4', alignItems: 'center', justifyContent: 'center' }, numText: { fontSize: 12, fontWeight: '700', color: C.brand }, titleText: { flex: 1, fontSize: 14, fontWeight: '500', color: C.ink }, })