"use client" import { useState } from "react" import { useSubscriptions } from "@/lib/queries/use-subscriptions" import { useCreateFolder, useRenameFolder, useDeleteFolder, } from "@/lib/queries/use-folder-mutations" import { useUserProfile } from "@/lib/queries/use-user-profile" import { TIER_LIMITS } from "@asa-news/shared" export function FoldersSettings() { const [newFolderName, setNewFolderName] = useState("") const [searchQuery, setSearchQuery] = useState("") const { data: subscriptionsData, isLoading } = useSubscriptions() const { data: userProfile } = useUserProfile() const createFolder = useCreateFolder() const renameFolder = useRenameFolder() const deleteFolder = useDeleteFolder() const folders = subscriptionsData?.folders ?? [] const subscriptions = subscriptionsData?.subscriptions ?? [] const tier = userProfile?.tier ?? "free" const tierLimits = TIER_LIMITS[tier] function feedCountForFolder(folderIdentifier: string): number { return subscriptions.filter( (subscription) => subscription.folderIdentifier === folderIdentifier ).length } function handleCreateFolder(event: React.FormEvent) { event.preventDefault() const trimmedName = newFolderName.trim() if (!trimmedName) return createFolder.mutate({ name: trimmedName }) setNewFolderName("") } if (isLoading) { return

loading folders ...

} const normalizedQuery = searchQuery.toLowerCase().trim() const filteredFolders = normalizedQuery ? folders.filter((folder) => folder.name.toLowerCase().includes(normalizedQuery)) : folders return (

{folders.length} / {tierLimits.maximumFolders} folders used

setNewFolderName(event.target.value)} placeholder="new folder name" className="min-w-0 flex-1 border border-border bg-background-primary px-3 py-2 text-text-primary outline-none placeholder:text-text-dim focus:border-text-dim" />
{folders.length > 5 && ( setSearchQuery(event.target.value)} placeholder="search folders..." className="w-full border border-border bg-background-primary px-3 py-1.5 text-text-primary outline-none placeholder:text-text-dim focus:border-text-dim" /> )}
{filteredFolders.length === 0 ? (

{folders.length === 0 ? "no folders yet" : "no folders match your search"}

) : (
{filteredFolders.map((folder) => ( renameFolder.mutate({ folderIdentifier: folder.folderIdentifier, name, iconUrl, }) } onDelete={() => deleteFolder.mutate({ folderIdentifier: folder.folderIdentifier, }) } /> ))}
)}
) } function FolderRow(properties: { folderIdentifier: string name: string iconUrl: string | null feedCount: number onSave: (name: string, iconUrl: string | null) => void onDelete: () => void }) { const { name, iconUrl, feedCount, onSave, onDelete } = properties const [isEditing, setIsEditing] = useState(false) const [editedName, setEditedName] = useState(name) const [editedIconUrl, setEditedIconUrl] = useState(iconUrl ?? "") const [showDeleteConfirm, setShowDeleteConfirm] = useState(false) function handleSave() { const trimmedName = editedName.trim() if (trimmedName) { onSave(trimmedName, editedIconUrl.trim() || null) } setIsEditing(false) } return (
{isEditing ? (
setEditedName(event.target.value)} className="min-w-0 flex-1 border border-border bg-background-primary px-2 py-1 text-text-primary outline-none focus:border-text-dim" onKeyDown={(event) => { if (event.key === "Enter") handleSave() if (event.key === "Escape") setIsEditing(false) }} autoFocus />
setEditedIconUrl(event.target.value)} placeholder="icon url (optional)" className="w-full border border-border bg-background-primary px-2 py-1 text-text-primary outline-none placeholder:text-text-dim focus:border-text-dim" />
) : (
{iconUrl && ( )} {name} ({feedCount} feed{feedCount !== 1 && "s"})
)}
{showDeleteConfirm ? (
{feedCount > 0 ? "has feeds, delete?" : "delete?"}
) : ( )}
) }