aboutsummaryrefslogtreecommitdiffstats
path: root/frontend/src/components/Settings.tsx
blob: def8ffeaa72e28b5eec96a1e5a2dff06d9e19536 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import React, { useEffect, useState } from 'react';
import type { Feed } from '../types';
import './Settings.css';

export default function Settings() {
    const [feeds, setFeeds] = useState<Feed[]>([]);
    const [newFeedUrl, setNewFeedUrl] = useState('');
    const [loading, setLoading] = useState(false);
    const [error, setError] = useState<string | null>(null);

    useEffect(() => {
        fetchFeeds();
    }, []);

    const fetchFeeds = () => {
        setLoading(true);
        fetch('/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);
            });
    };

    const handleAddFeed = (e: React.FormEvent) => {
        e.preventDefault();
        if (!newFeedUrl) return;

        setLoading(true);
        fetch('/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(); // Refresh list (or we could append if server returns full feed object)
            })
            .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);
        fetch(`/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);
            });
    };

    return (
        <div className="settings-page">
            <h2>Settings</h2>

            <div className="add-feed-section">
                <h3>Add New Feed</h3>
                <form onSubmit={handleAddFeed} className="add-feed-form">
                    <input
                        type="url"
                        value={newFeedUrl}
                        onChange={(e) => setNewFeedUrl(e.target.value)}
                        placeholder="https://example.com/feed.xml"
                        required
                        className="feed-input"
                        disabled={loading}
                    />
                    <button type="submit" disabled={loading}>
                        Add Feed
                    </button>
                </form>
                {error && <p className="error-message">{error}</p>}
            </div>

            <div className="feed-list-section">
                <h3>Manage Feeds</h3>
                {loading && <p>Loading...</p>}
                <ul className="settings-feed-list">
                    {feeds.map((feed) => (
                        <li key={feed._id} className="settings-feed-item">
                            <div className="feed-info">
                                <span className="feed-title">{feed.title || '(No Title)'}</span>
                                <span className="feed-url">{feed.url}</span>
                            </div>
                            <button
                                onClick={() => handleDeleteFeed(feed._id)}
                                className="delete-btn"
                                disabled={loading}
                                title="Delete Feed"
                            >
                                Delete
                            </button>
                        </li>
                    ))}
                </ul>
            </div>
        </div>
    );
}