From 1c73c999ac78d2e6d3a8c68b4e17058046326f55 Mon Sep 17 00:00:00 2001 From: nsfisis Date: Sat, 12 Jul 2025 14:55:19 +0900 Subject: feat(frontend): create pages and components --- frontend/src/pages/Settings.tsx | 155 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 frontend/src/pages/Settings.tsx (limited to 'frontend/src/pages/Settings.tsx') diff --git a/frontend/src/pages/Settings.tsx b/frontend/src/pages/Settings.tsx new file mode 100644 index 0000000..78fc306 --- /dev/null +++ b/frontend/src/pages/Settings.tsx @@ -0,0 +1,155 @@ +import { useState } from "react"; +import { useMutation, useQuery } from "urql"; +import { AddFeedForm, FeedList } from "../components"; +import { + GetFeedsDocument, + MarkFeedReadDocument, + MarkFeedUnreadDocument, + RemoveFeedDocument, +} from "../graphql/generated/graphql"; + +export function Settings() { + const [{ data: feedsData }, refetchFeeds] = useQuery({ + query: GetFeedsDocument, + }); + const [, markFeedRead] = useMutation(MarkFeedReadDocument); + const [, markFeedUnread] = useMutation(MarkFeedUnreadDocument); + const [, removeFeed] = useMutation(RemoveFeedDocument); + + const [selectedFeeds, setSelectedFeeds] = useState>(new Set()); + + const handleFeedAdded = () => { + refetchFeeds(); + }; + + const handleFeedDeleted = () => { + refetchFeeds(); + setSelectedFeeds(new Set()); + }; + + const handleSelectFeed = (feedId: string, selected: boolean) => { + const newSelection = new Set(selectedFeeds); + if (selected) { + newSelection.add(feedId); + } else { + newSelection.delete(feedId); + } + setSelectedFeeds(newSelection); + }; + + const handleSelectAll = () => { + if (!feedsData?.feeds) return; + if (selectedFeeds.size === feedsData.feeds.length) { + setSelectedFeeds(new Set()); + } else { + setSelectedFeeds(new Set(feedsData.feeds.map((feed) => feed.id))); + } + }; + + const handleBulkMarkRead = async () => { + const promises = Array.from(selectedFeeds).map((feedId) => + markFeedRead({ id: feedId }), + ); + await Promise.all(promises); + refetchFeeds(); + }; + + const handleBulkMarkUnread = async () => { + const promises = Array.from(selectedFeeds).map((feedId) => + markFeedUnread({ id: feedId }), + ); + await Promise.all(promises); + refetchFeeds(); + }; + + const handleBulkDelete = async () => { + const confirmed = window.confirm( + `Are you sure you want to delete ${selectedFeeds.size} selected feeds?`, + ); + if (!confirmed) return; + + const promises = Array.from(selectedFeeds).map((feedId) => + removeFeed({ id: feedId }), + ); + await Promise.all(promises); + handleFeedDeleted(); + }; + + const hasFeeds = feedsData?.feeds && feedsData.feeds.length > 0; + const hasSelectedFeeds = selectedFeeds.size > 0; + + return ( +
+

Feed Settings

+ + {/* Add New Feed Section */} +
+

+ Add New Feed +

+ +
+ + {/* Manage Feeds Section */} +
+
+

Manage Feeds

+ {hasFeeds && ( +
+ +
+ )} +
+ + {/* Bulk Operations */} + {hasSelectedFeeds && ( +
+
+ + {selectedFeeds.size} feed{selectedFeeds.size > 1 ? "s" : ""}{" "} + selected + +
+ + + +
+
+
+ )} + + +
+
+ ); +} -- cgit v1.2.3-70-g09d2