const { useState, useEffect } = React; const { createRoot } = ReactDOM; // 検索入力のデバウンス時間(ミリ秒) const SEARCH_DEBOUNCE_MS = 300; // 市区町村の検索・一覧表示。選択すると議事録一覧へ遷移する const ShichosonList = ({ apiBase }) => { const [name, setName] = useState(''); const [shichosons, setShichosons] = useState([]); const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(''); // 入力からデバウンスして検索する。マウント時も空クエリで初期一覧を取得する useEffect(() => { let isCancelled = false; const timerId = setTimeout(async () => { setIsLoading(true); setError(''); try { const query = new URLSearchParams({ name: name }); const response = await fetch(`${apiBase}/shichosons?${query}`); if (isCancelled) return; if (response.ok) { const data = await response.json(); setShichosons(data.shichosons); } else { setError('検索に失敗しました'); } } catch (e) { if (isCancelled) return; console.error('Error:', e); setError('ネットワークエラーが発生しました'); } finally { if (!isCancelled) setIsLoading(false); } }, SEARCH_DEBOUNCE_MS); // 入力が続いた場合は前回のリクエスト結果を破棄する return () => { isCancelled = true; clearTimeout(timerId); }; }, [name, apiBase]); return (

議事録一覧

市区町村を選ぶと、その議会の議事録を閲覧できます。

setName(e.target.value)} autoFocus />
{error && (
{error}
)} {isLoading ? (
読み込み中...
) : shichosons.length === 0 ? (
該当する市区町村が見つかりません
) : (
{shichosons.map((shichoson) => ( {shichoson.name} 議事録 {shichoson.gijiroku_count}件 ))}
)}
); }; function initializeApp() { const container = document.getElementById('shichosons-root'); if (container) { try { const apiBase = container.dataset.apiBase; const root = createRoot(container); root.render(); } catch (error) { console.error('Error rendering ShichosonList component:', error); } } else { console.error('shichosons-root element not found!'); } } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', initializeApp); } else { initializeApp(); }