aboutsummaryrefslogtreecommitdiffstats
path: root/frontend/src/components/Settings.tsx
blob: 3f508e970a7b6e09cd37f282aefd51142863dee2 (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
122
123
124
import React, { useEffect, useState } from 'react';
import type { Feed } from '../types';
import './Settings.css';
import { apiFetch } from '../utils';

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);

  const fetchFeeds = () => {
    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(() => {
    fetchFeeds();
  }, []);



  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(); // 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);
    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);
      });
  };

  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>
  );
}