diff --git a/spotizerr-ui/src/components/AlbumCard.tsx b/spotizerr-ui/src/components/AlbumCard.tsx index 5d5fbfa..b144983 100644 --- a/spotizerr-ui/src/components/AlbumCard.tsx +++ b/spotizerr-ui/src/components/AlbumCard.tsx @@ -11,7 +11,7 @@ export const AlbumCard = ({ album, onDownload }: AlbumCardProps) => { const subtitle = album.artists.map((artist) => artist.name).join(", "); return ( -
+
{album.name} @@ -21,10 +21,10 @@ export const AlbumCard = ({ album, onDownload }: AlbumCardProps) => { e.preventDefault(); onDownload(); }} - className="absolute bottom-2 right-2 p-2 bg-green-600 text-white rounded-full hover:bg-green-700 transition-opacity shadow-lg opacity-0 group-hover:opacity-100 duration-300" + className="absolute bottom-2 right-2 p-2 bg-button-success hover:bg-button-success-hover text-button-success-text rounded-full transition-opacity shadow-lg opacity-0 group-hover:opacity-100 duration-300" title="Download album" > - Download + Download )} @@ -33,11 +33,11 @@ export const AlbumCard = ({ album, onDownload }: AlbumCardProps) => { {album.name} - {subtitle &&

{subtitle}

} + {subtitle &&

{subtitle}

}
); diff --git a/spotizerr-ui/src/components/Queue.tsx b/spotizerr-ui/src/components/Queue.tsx index 8dc64c0..c9b8dc0 100644 --- a/spotizerr-ui/src/components/Queue.tsx +++ b/spotizerr-ui/src/components/Queue.tsx @@ -15,72 +15,83 @@ const isTerminalStatus = (status: QueueStatus) => const statusStyles: Record< QueueStatus, - { icon: React.ReactNode; color: string; bgColor: string; name: string } + { icon: React.ReactNode; color: string; bgColor: string; borderColor: string; name: string } > = { queued: { - icon: , - color: "text-gray-500", - bgColor: "bg-gray-100", + icon: , + color: "text-content-muted dark:text-content-muted-dark", + bgColor: "bg-gradient-to-r from-surface-muted to-surface-accent dark:from-surface-muted-dark dark:to-surface-accent-dark", + borderColor: "border-border dark:border-border-dark", name: "Queued", }, initializing: { - icon: , - color: "text-blue-500", - bgColor: "bg-blue-100", + icon: , + color: "text-info", + bgColor: "bg-gradient-to-r from-blue-50 to-blue-100 dark:from-blue-900/20 dark:to-blue-800/30", + borderColor: "border-info/30 dark:border-info/40", name: "Initializing", }, downloading: { - icon: , - color: "text-blue-500", - bgColor: "bg-blue-100", + icon: , + color: "text-info", + bgColor: "bg-gradient-to-r from-blue-50 to-blue-100 dark:from-blue-900/20 dark:to-blue-800/30", + borderColor: "border-info/30 dark:border-info/40", name: "Downloading", }, processing: { - icon: , - color: "text-purple-500", - bgColor: "bg-purple-100", + icon: , + color: "text-processing", + bgColor: "bg-gradient-to-r from-purple-50 to-purple-100 dark:from-purple-900/20 dark:to-purple-800/30", + borderColor: "border-processing/30 dark:border-processing/40", name: "Processing", }, retrying: { - icon: , - color: "text-orange-500", - bgColor: "bg-orange-100", + icon: , + color: "text-warning", + bgColor: "bg-gradient-to-r from-orange-50 to-orange-100 dark:from-orange-900/20 dark:to-orange-800/30", + borderColor: "border-warning/30 dark:border-warning/40", name: "Retrying", }, completed: { - icon: , - color: "text-green-500", - bgColor: "bg-green-100", + icon: , + color: "text-success", + bgColor: "bg-gradient-to-r from-green-50 to-green-100 dark:from-green-900/20 dark:to-green-800/30", + borderColor: "border-success/30 dark:border-success/40", name: "Completed", }, done: { - icon: , - color: "text-green-500", - bgColor: "bg-green-100", + icon: , + color: "text-success", + bgColor: "bg-gradient-to-r from-green-50 to-green-100 dark:from-green-900/20 dark:to-green-800/30", + borderColor: "border-success/30 dark:border-success/40", name: "Done", }, error: { - icon: , - color: "text-red-500", - bgColor: "bg-red-100", + icon: , + color: "text-error", + bgColor: "bg-gradient-to-r from-red-50 to-red-100 dark:from-red-900/20 dark:to-red-800/30", + borderColor: "border-error/30 dark:border-error/40", name: "Error", }, cancelled: { - icon: , - color: "text-yellow-500", - bgColor: "bg-yellow-100", + icon: , + color: "text-warning", + bgColor: "bg-gradient-to-r from-orange-50 to-orange-100 dark:from-orange-900/20 dark:to-orange-800/30", + borderColor: "border-warning/30 dark:border-warning/40", name: "Cancelled", }, skipped: { - icon: , - color: "text-gray-500", - bgColor: "bg-gray-100", + icon: , + color: "text-content-muted dark:text-content-muted-dark", + bgColor: "bg-gradient-to-r from-surface-muted to-surface-accent dark:from-surface-muted-dark dark:to-surface-accent-dark", + borderColor: "border-border dark:border-border-dark", name: "Skipped", }, pending: { - icon: , - color: "text-gray-500", - bgColor: "bg-gray-100", + icon: , + color: "text-content-muted dark:text-content-muted-dark", + bgColor: "bg-gradient-to-r from-surface-muted to-surface-accent dark:from-surface-muted-dark dark:to-surface-accent-dark", + borderColor: "border-border dark:border-border-dark", name: "Pending", }, }; @@ -116,24 +127,26 @@ const QueueItemCard = ({ item }: { item: QueueItem }) => { const progressText = getProgressText(); return ( -
+
-
-
{statusInfo.icon}
+
+
+ {statusInfo.icon} +
{item.type === "track" && ( <>
- -

+ +

{item.name}

-

+

{item.artist}

{item.albumName && ( -

+

{item.albumName}

)} @@ -142,16 +155,16 @@ const QueueItemCard = ({ item }: { item: QueueItem }) => { {item.type === "album" && ( <>
- -

+ +

{item.name}

-

+

{item.artist}

{item.currentTrackTitle && ( -

+

{item.currentTrackNumber}/{item.totalTracks}: {item.currentTrackTitle}

)} @@ -160,16 +173,16 @@ const QueueItemCard = ({ item }: { item: QueueItem }) => { {item.type === "playlist" && ( <>
- -

+ +

{item.name}

-

+

{item.playlistOwner}

{item.currentTrackTitle && ( -

+

{item.currentTrackNumber}/{item.totalTracks}: {item.currentTrackTitle}

)} @@ -177,60 +190,82 @@ const QueueItemCard = ({ item }: { item: QueueItem }) => { )}
-
+
-

{statusInfo.name}

- {progressText &&

{progressText}

} +
+ {statusInfo.name} +
+ {progressText &&

{progressText}

} +
+
+ {isTerminal ? ( + + ) : ( + + )} + {item.canRetry && ( + + )}
- {isTerminal ? ( - - ) : ( - - )} - {item.canRetry && ( - - )}
{(item.status === "error" || item.status === "retrying") && item.error && ( -

Error: {item.error}

+
+

Error: {item.error}

+
)} {isTerminal && item.summary && (item.summary.total_failed > 0 || item.summary.total_skipped > 0) && ( -
- {item.summary.total_failed > 0 && ( -

{item.summary.total_failed} track(s) failed.

- )} - {item.summary.total_skipped > 0 && ( -

{item.summary.total_skipped} track(s) skipped.

- )} +
+
+ {item.summary.total_failed > 0 && ( + +
+ {item.summary.total_failed} failed +
+ )} + {item.summary.total_skipped > 0 && ( + +
+ {item.summary.total_skipped} skipped +
+ )} +
)} {(item.status === "downloading" || item.status === "processing") && item.type === "track" && item.progress !== undefined && ( -
-
+
+
+ Progress + {item.progress.toFixed(0)}% +
+
+
+
)}
@@ -249,13 +284,15 @@ export const Queue = () => { const hasFinished = items.some((item) => isTerminalStatus(item.status)); return ( -
-
-

Download Queue ({items.length})

+
+
+

+ Download Queue ({items.length}) +

-
-
+
{items.length === 0 ? ( -

The queue is empty.

+
+
+ +
+

The queue is empty.

+

Downloads will appear here

+
) : ( items.map((item) => ) )} diff --git a/spotizerr-ui/src/components/SearchResultCard.tsx b/spotizerr-ui/src/components/SearchResultCard.tsx index 45d8a30..2e49350 100644 --- a/spotizerr-ui/src/components/SearchResultCard.tsx +++ b/spotizerr-ui/src/components/SearchResultCard.tsx @@ -24,24 +24,24 @@ export const SearchResultCard = ({ id, name, subtitle, imageUrl, type, onDownloa }; return ( -
+
{name} {onDownload && ( )}
- + {name} - {subtitle &&

{subtitle}

} + {subtitle &&

{subtitle}

}
); diff --git a/spotizerr-ui/src/components/config/AccountsTab.tsx b/spotizerr-ui/src/components/config/AccountsTab.tsx index 69545c0..0823955 100644 --- a/spotizerr-ui/src/components/config/AccountsTab.tsx +++ b/spotizerr-ui/src/components/config/AccountsTab.tsx @@ -87,61 +87,61 @@ export function AccountsTab() { }; const renderAddForm = () => ( -
-

Add New {activeService === "spotify" ? "Spotify" : "Deezer"} Account

+ +

Add New {activeService === "spotify" ? "Spotify" : "Deezer"} Account

- + - {errors.accountName &&

{errors.accountName.message}

} + {errors.accountName &&

{errors.accountName.message}

}
{activeService === "spotify" && (
- + - {errors.authBlob &&

{errors.authBlob.message}

} + {errors.authBlob &&

{errors.authBlob.message}

}
)} {activeService === "deezer" && (
- + - {errors.arl &&

{errors.arl.message}

} + {errors.arl &&

{errors.arl.message}

}
)}
- +
@@ -151,35 +151,35 @@ export function AccountsTab() { return (
-
+
{isLoading ? ( -

Loading accounts...

+

Loading accounts...

) : (
{credentials?.map((cred) => (
{cred.name} @@ -191,7 +191,7 @@ export function AccountsTab() { {!isAdding && ( diff --git a/spotizerr-ui/src/components/config/DownloadsTab.tsx b/spotizerr-ui/src/components/config/DownloadsTab.tsx index 965d946..850641d 100644 --- a/spotizerr-ui/src/components/config/DownloadsTab.tsx +++ b/spotizerr-ui/src/components/config/DownloadsTab.tsx @@ -89,36 +89,36 @@ export function DownloadsTab({ config, isLoading }: DownloadsTabProps) { {/* Download Settings */}
-

Download Behavior

+

Download Behavior

- +
- +
- +
{/* Source Quality Settings */}
-

Source Quality

+

Source Quality

- +
- +
-

+

This sets the quality of the original download. Conversion settings below are applied after download.

{/* Conversion Settings */}
-

Conversion

+

Conversion

- +
- +
- +
- +
@@ -216,7 +216,7 @@ export function DownloadsTab({ config, isLoading }: DownloadsTabProps) { diff --git a/spotizerr-ui/src/components/config/FormattingTab.tsx b/spotizerr-ui/src/components/config/FormattingTab.tsx index 0228110..2df4e34 100644 --- a/spotizerr-ui/src/components/config/FormattingTab.tsx +++ b/spotizerr-ui/src/components/config/FormattingTab.tsx @@ -50,7 +50,7 @@ const placeholders = { const PlaceholderSelector = ({ onSelect }: { onSelect: (value: string) => void }) => (
- +
- +
- +
@@ -157,7 +157,7 @@ export function FormattingTab({ config, isLoading }: FormattingTabProps) { diff --git a/spotizerr-ui/src/components/config/GeneralTab.tsx b/spotizerr-ui/src/components/config/GeneralTab.tsx index d9c671d..a597d17 100644 --- a/spotizerr-ui/src/components/config/GeneralTab.tsx +++ b/spotizerr-ui/src/components/config/GeneralTab.tsx @@ -70,18 +70,18 @@ export function GeneralTab({ config, isLoading: isConfigLoading }: GeneralTabPro }; const isLoading = isConfigLoading || spotifyLoading || deezerLoading || settingsLoading; - if (isLoading) return

Loading general settings...

; + if (isLoading) return

Loading general settings...

; return (
-

Service Defaults

+

Service Defaults

- + {spotifyAccounts?.map((acc) => (
-

Deezer Settings

+

Deezer Settings

- +
- +
@@ -126,22 +126,22 @@ function WebhookForm() { const onSubmit = (formData: WebhookSettings) => mutation.mutate(formData); - if (isLoading) return

Loading Webhook settings...

; + if (isLoading) return

Loading Webhook settings...

; return (
- +
- +
{data?.available_events.map((event) => ( ( -