diff options
Diffstat (limited to 'apps/web/app/reader/_components/add-feed-dialog.tsx')
| -rw-r--r-- | apps/web/app/reader/_components/add-feed-dialog.tsx | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/apps/web/app/reader/_components/add-feed-dialog.tsx b/apps/web/app/reader/_components/add-feed-dialog.tsx new file mode 100644 index 0000000..4eb119c --- /dev/null +++ b/apps/web/app/reader/_components/add-feed-dialog.tsx @@ -0,0 +1,123 @@ +"use client" + +import { useState } from "react" +import { useSubscribeToFeed } from "@/lib/queries/use-subscribe-to-feed" +import { useSubscriptions } from "@/lib/queries/use-subscriptions" +import { useUserInterfaceStore } from "@/lib/stores/user-interface-store" + +export function AddFeedDialog() { + const isOpen = useUserInterfaceStore((state) => state.isAddFeedDialogOpen) + const setOpen = useUserInterfaceStore((state) => state.setAddFeedDialogOpen) + const [feedUrl, setFeedUrl] = useState("") + const [customTitle, setCustomTitle] = useState("") + const [selectedFolderIdentifier, setSelectedFolderIdentifier] = useState< + string | null + >(null) + const subscribeToFeed = useSubscribeToFeed() + const { data: subscriptionsData } = useSubscriptions() + + function handleClose() { + setFeedUrl("") + setCustomTitle("") + setSelectedFolderIdentifier(null) + setOpen(false) + } + + async function handleSubmit(event: React.FormEvent) { + event.preventDefault() + + subscribeToFeed.mutate( + { + feedUrl, + folderIdentifier: selectedFolderIdentifier, + customTitle: customTitle || null, + }, + { + onSuccess: () => { + handleClose() + }, + } + ) + } + + if (!isOpen) return null + + return ( + <div className="fixed inset-0 z-50 flex items-center justify-center"> + <div + className="fixed inset-0 bg-background-primary/80" + onClick={handleClose} + /> + <div className="relative w-full max-w-md border border-border bg-background-secondary p-6"> + <h2 className="mb-4 text-text-primary">add feed</h2> + <form onSubmit={handleSubmit} className="space-y-4"> + <div className="space-y-2"> + <label htmlFor="feed-url" className="text-text-secondary"> + feed url + </label> + <input + id="feed-url" + type="url" + value={feedUrl} + onChange={(event) => setFeedUrl(event.target.value)} + required + placeholder="https://example.com/feed.xml" + className="w-full border border-border bg-background-primary px-3 py-2 text-text-primary outline-none placeholder:text-text-dim focus:border-text-dim" + /> + </div> + <div className="space-y-2"> + <label htmlFor="custom-title" className="text-text-secondary"> + custom title (optional) + </label> + <input + id="custom-title" + type="text" + value={customTitle} + onChange={(event) => setCustomTitle(event.target.value)} + className="w-full border border-border bg-background-primary px-3 py-2 text-text-primary outline-none placeholder:text-text-dim focus:border-text-dim" + /> + </div> + <div className="space-y-2"> + <label htmlFor="folder-select" className="text-text-secondary"> + folder (optional) + </label> + <select + id="folder-select" + value={selectedFolderIdentifier ?? ""} + onChange={(event) => + setSelectedFolderIdentifier(event.target.value || null) + } + className="w-full border border-border bg-background-primary px-3 py-2 text-text-primary outline-none" + > + <option value="">no folder</option> + {subscriptionsData?.folders.map((folder) => ( + <option + key={folder.folderIdentifier} + value={folder.folderIdentifier} + > + {folder.name} + </option> + ))} + </select> + </div> + <div className="flex gap-2"> + <button + type="button" + onClick={handleClose} + className="flex-1 border border-border px-4 py-2 text-text-secondary transition-colors hover:bg-background-tertiary hover:text-text-primary" + > + cancel + </button> + <button + type="submit" + disabled={subscribeToFeed.isPending} + className="flex-1 border border-border bg-background-tertiary px-4 py-2 text-text-primary transition-colors hover:bg-border disabled:opacity-50" + > + {subscribeToFeed.isPending ? "adding..." : "add feed"} + </button> + </div> + </form> + </div> + </div> + ) +} |