import React, { useEffect, useState } from 'react'; import type { Feed } from '../types'; import './Settings.css'; import { apiFetch } from '../utils'; interface SettingsProps { fontTheme?: string; setFontTheme?: (t: string) => void; } export default function Settings({ fontTheme, setFontTheme }: SettingsProps) { const [feeds, setFeeds] = useState([]); /* ... existing state ... */ const [newFeedUrl, setNewFeedUrl] = useState(''); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const [importFile, setImportFile] = useState(null); /* ... existing fetchFeeds ... */ const fetchFeeds = React.useCallback(() => { setLoading(true); apiFetch('/api/feed/') .then((res) => { if (!res.ok) throw new Error('Failed to fetch feeds'); return res.json(); }) .then((data) => { setFeeds(data); setLoading(false); }) .catch((err) => { setError(err.message); setLoading(false); }); }, []); useEffect(() => { // eslint-disable-next-line fetchFeeds(); }, [fetchFeeds]); /* ... existing handlers ... */ const handleAddFeed = (e: React.FormEvent) => { e.preventDefault(); if (!newFeedUrl) return; setLoading(true); apiFetch('/api/feed/', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ url: newFeedUrl }), }) .then((res) => { if (!res.ok) throw new Error('Failed to add feed'); return res.json(); }) .then(() => { setNewFeedUrl(''); fetchFeeds(); }) .catch((err) => { setError(err.message); setLoading(false); }); }; const handleDeleteFeed = (id: number) => { if (!globalThis.confirm('Are you sure you want to delete this feed?')) return; setLoading(true); apiFetch(`/api/feed/${id}`, { method: 'DELETE', }) .then((res) => { if (!res.ok) throw new Error('Failed to delete feed'); setFeeds(feeds.filter((f) => f._id !== id)); setLoading(false); }) .catch((err) => { setError(err.message); setLoading(false); }); }; const handleImport = (e: React.FormEvent) => { e.preventDefault(); if (!importFile) return; setLoading(true); const formData = new FormData(); formData.append('file', importFile); formData.append('format', 'opml'); apiFetch('/api/import', { method: 'POST', body: formData, }) .then((res) => { if (!res.ok) throw new Error('Failed to import feeds'); return res.json(); }) .then(() => { setImportFile(null); fetchFeeds(); alert('Import successful!'); }) .catch((err) => { setError(err.message); setLoading(false); }); }; return (

Settings

{setFontTheme && (

Appearance

)}

Add New Feed

setNewFeedUrl(e.target.value)} placeholder="https://example.com/feed.xml" required className="feed-input" disabled={loading} />

Import Feeds (OPML)

setImportFile(e.target.files?.[0] || null)} className="file-input" disabled={loading} />

Export Feeds

{error &&

{error}

}

Manage Feeds

{loading &&

Loading...

}
    {feeds.map((feed) => (
  • {feed.title || '(No Title)'} {feed.url}
  • ))}
); }