From e51be9697c8f0e55b28989e86e0f00bc4483283d Mon Sep 17 00:00:00 2001 From: codey Date: Fri, 15 Aug 2025 14:15:18 -0400 Subject: [PATCH] misc --- src/components/TRip/BreadcrumbNav.jsx | 33 +++--- src/components/TRip/MediaRequestForm.jsx | 134 ++++++++++++++++------- 2 files changed, 113 insertions(+), 54 deletions(-) diff --git a/src/components/TRip/BreadcrumbNav.jsx b/src/components/TRip/BreadcrumbNav.jsx index 4c76754..c843603 100644 --- a/src/components/TRip/BreadcrumbNav.jsx +++ b/src/components/TRip/BreadcrumbNav.jsx @@ -7,19 +7,24 @@ export default function BreadcrumbNav({ currentPage }) { ]; return ( - +
+ +
+ Self Service +
+
); } diff --git a/src/components/TRip/MediaRequestForm.jsx b/src/components/TRip/MediaRequestForm.jsx index 4f36ed5..bc27670 100644 --- a/src/components/TRip/MediaRequestForm.jsx +++ b/src/components/TRip/MediaRequestForm.jsx @@ -123,6 +123,8 @@ export default function MediaRequestForm() { metadataFetchToastId.current = toast.info("Retrieving metadata...", { autoClose: false, + progress: 0, + closeOnClick: false, } ); if (type === "artist") { @@ -222,6 +224,42 @@ export default function MediaRequestForm() { } }; + const allTracksLoaded = albums.every(({ id }) => Array.isArray(tracksByAlbum[id]) && tracksByAlbum[id].length > 0); + + const handleToggleAllAlbums = () => { + const allSelected = albums.every(({ id }) => { + const allTracks = tracksByAlbum[id] || []; + return selectedTracks[id]?.length === allTracks.length && allTracks.length > 0; + }); + + const newSelection = {}; + albums.forEach(({ id }) => { + const allTracks = tracksByAlbum[id] || []; + if (allSelected) { + // Uncheck all + newSelection[id] = []; + } else { + // Check all tracks in the album + newSelection[id] = allTracks.map(track => String(track.id)); + } + }); + setSelectedTracks(newSelection); + }; + + { + e.preventDefault(); + if (!allTracksLoaded) return; // prevent clicking before data ready + handleToggleAllAlbums(); + }} + className={`text-sm hover:underline cursor-pointer ${!allTracksLoaded ? "text-gray-400 dark:text-gray-500 pointer-events-none" : "text-blue-600" + }`} + > + Check / Uncheck All Albums + + // Sequentially fetch tracks for albums not loaded yet @@ -233,9 +271,14 @@ export default function MediaRequestForm() { if (albumsToFetch.length === 0) return; const fetchTracksSequentially = async () => { - const minDelay = 600; // ms between API requests + const minDelay = 400; // ms between API requests setIsFetching(true); - for (const album of albumsToFetch) { + + const totalAlbums = albumsToFetch.length; + + for (let index = 0; index < totalAlbums; index++) { + const album = albumsToFetch[index]; + if (isCancelled) break; setLoadingAlbumId(album.id); @@ -263,14 +306,24 @@ export default function MediaRequestForm() { setTracksByAlbum((prev) => ({ ...prev, [album.id]: [] })); setSelectedTracks((prev) => ({ ...prev, [album.id]: [] })); } + + // Update progress toast + toast.update(metadataFetchToastId.current, { + progress: (index + 1) / totalAlbums, + render: `Retrieving metadata... (${index + 1} / ${totalAlbums})`, + }); } + setLoadingAlbumId(null); setIsFetching(false); - try { - toast.done(metadataFetchToastId.current); - } catch (err) { - console.log(err); - }; + + // Finish the toast + toast.update(metadataFetchToastId.current, { + render: "Metadata retrieved!", + type: "success", + progress: 1, + autoClose: 1500, + }); }; fetchTracksSequentially(); @@ -281,6 +334,7 @@ export default function MediaRequestForm() { }, [albums, type]); + // Toggle individual track checkbox const toggleTrack = (albumId, trackId) => { setSelectedTracks((prev) => { @@ -337,21 +391,36 @@ export default function MediaRequestForm() { } setIsSubmitting(true); try { - // Example: simulate submission delay - await new Promise((resolve) => setTimeout(resolve, 1500)); const allSelectedIds = Object.values(selectedTracks) .filter(arr => Array.isArray(arr)) // skip null entries .flat(); + + const response = await authFetch(`${API_URL}/trip/bulk_fetch`, { + method: "POST", + headers: { + "Content-Type": "application/json; charset=utf-8", + }, + body: JSON.stringify({ track_ids: allSelectedIds }), + }); + + if (!response.ok) { + throw new Error(`Server error: ${response.status}`); + } + + const data = await response.json(); toast.success(`Request submitted! (${allSelectedIds.length} tracks)`); console.debug("Requested: ", selectedTracks); console.debug("Flattened: ", allSelectedIds); + console.debug("Server response: ", data); } catch (err) { + console.error(err); toast.error("Failed to submit request."); } finally { setIsSubmitting(false); } }; + return (
-
-
- - - -
-
+ 0 && ( <> +