Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions app/MessageBanner.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,21 @@ export default function MessageBanner({ type = "info", text }) {
let bg, border, textColor, icon;
switch (type) {
case "error":
bg = "bg-red-100";
border = "border border-red-300";
textColor = "text-red-900";
bg = "bg-red-100 dark:bg-red-900/20";
border = "border border-red-300 dark:border-red-800/40";
textColor = "text-red-900 dark:text-red-300";
icon = "❌";
break;
case "success":
bg = "bg-green-100";
border = "border border-green-300";
textColor = "text-green-900";
bg = "bg-green-100 dark:bg-green-900/20";
border = "border border-green-300 dark:border-green-800/40";
textColor = "text-green-900 dark:text-green-300";
icon = "✅";
break;
default:
bg = "bg-blue-100";
border = "border border-blue-300";
textColor = "text-blue-900";
bg = "bg-blue-100 dark:bg-blue-900/20";
border = "border border-blue-300 dark:border-blue-800/40";
textColor = "text-blue-900 dark:text-blue-300";
icon = "ℹ️";
}
return (
Expand Down
8 changes: 4 additions & 4 deletions app/components/DualDownloadButton.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ export default function DualDownloadButton({

return (
<div className="fixed bottom-4 left-4 right-4 z-[100] pointer-events-none">
<div className="bg-white rounded-lg shadow-lg p-4 space-y-3 pointer-events-auto">
<div className="bg-white dark:bg-zinc-800 rounded-lg shadow-lg p-4 space-y-3 pointer-events-auto">
{/* Wedge toggles when both selected */}
{bothSelected && hasWedges && (
<div className="flex items-center justify-center gap-3 pb-2 border-b border-gray-200">
<span className="text-sm text-gray-700 font-medium">Use FL Wedge:</span>
<div className="flex items-center justify-center gap-3 pb-2 border-b border-gray-200 dark:border-zinc-700">
<span className="text-sm text-gray-700 dark:text-zinc-300 font-medium">Use FL Wedge:</span>
<WedgeToggleButton
active={useBookWedge}
onClick={onToggleBookWedge}
Expand All @@ -42,7 +42,7 @@ export default function DualDownloadButton({
<button
onClick={onDownload}
disabled={disabled}
className="w-full rounded-md bg-pink-400 px-5 py-3 text-base font-semibold text-white hover:bg-pink-500 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-pink-500 disabled:bg-gray-300 disabled:text-gray-600 disabled:cursor-not-allowed transition-colors duration-200 flex items-center justify-center gap-2"
className="w-full rounded-md bg-pink-400 px-5 py-3 text-base font-semibold text-white hover:bg-pink-500 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-pink-500 disabled:bg-gray-300 disabled:text-gray-600 dark:disabled:bg-zinc-600 dark:disabled:text-zinc-400 disabled:cursor-not-allowed transition-colors duration-200 flex items-center justify-center gap-2"
>
{loading ? (
<>
Expand Down
32 changes: 16 additions & 16 deletions app/components/DualSearchResultsList.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export default function DualSearchResultsList({
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle>
<path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
</svg>
<p className="text-gray-600">Searching both categories...</p>
<p className="text-gray-600 dark:text-zinc-400">Searching both categories...</p>
</div>
</div>
);
Expand All @@ -39,7 +39,7 @@ export default function DualSearchResultsList({
const noBooks = bookResults.length === 0;

if (noResults) {
return <p className="text-gray-500 mt-5">No results found for either category. Try a different search...</p>;
return <p className="text-gray-500 dark:text-zinc-400 mt-5">No results found for either category. Try a different search...</p>;
}

// Calculate progress for desktop
Expand Down Expand Up @@ -91,7 +91,7 @@ export default function DualSearchResultsList({
<button
onClick={onDownload}
disabled={disabled}
className="rounded-md bg-pink-400 px-5 py-2.5 text-sm font-semibold text-white hover:bg-pink-500 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-pink-500 disabled:bg-gray-300 disabled:text-gray-600 disabled:cursor-not-allowed cursor-pointer min-w-[100px] flex items-center justify-center gap-2 h-full"
className="rounded-md bg-pink-400 px-5 py-2.5 text-sm font-semibold text-white hover:bg-pink-500 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-pink-500 disabled:bg-gray-300 disabled:text-gray-600 dark:disabled:bg-zinc-600 dark:disabled:text-zinc-400 disabled:cursor-not-allowed cursor-pointer min-w-[100px] flex items-center justify-center gap-2 h-full"
aria-label="Download selected book and audiobook"
>
{downloadLoading ? (
Expand All @@ -118,7 +118,7 @@ export default function DualSearchResultsList({
return (
<div className="mt-6">
{/* Integrated Header: 2-Row Layout */}
<div className="mb-8 p-5 bg-white rounded-xl border border-gray-200">
<div className="mb-8 p-5 bg-white dark:bg-zinc-800 rounded-xl border border-gray-200 dark:border-zinc-700">
{/* Row 1: Progress + Download Button */}
<div className="flex items-center gap-6">
<ProgressIndicator
Expand All @@ -140,7 +140,7 @@ export default function DualSearchResultsList({
{/* FL Wedge toggles */}
{userStats?.flWedges > 0 && (selectedBook?.freeleech === false || selectedAudiobook?.freeleech === false) ? (
<div className="flex items-center gap-3">
<span className="text-gray-600 font-medium">Use FL Wedge:</span>
<span className="text-gray-600 dark:text-zinc-400 font-medium">Use FL Wedge:</span>
{!selectedBook?.freeleech && (
<WedgeToggleButton
active={useBookWedge}
Expand All @@ -163,19 +163,19 @@ export default function DualSearchResultsList({
)}

{/* Center Separator */}
<div className="h-5 w-px bg-gray-300"></div>
<div className="h-5 w-px bg-gray-300 dark:bg-zinc-600"></div>

{/* Combined info */}
{combinedInfo && (
<div className="flex items-center gap-4 text-gray-700">
<div className="flex items-center gap-4 text-gray-700 dark:text-zinc-300">
<span className="flex items-center gap-1.5">
<span className="text-base">📦</span>
<span className="font-semibold text-gray-900">{combinedInfo.totalSize}</span>
<span className="font-semibold text-gray-900 dark:text-zinc-100">{combinedInfo.totalSize}</span>
</span>
<span className="text-gray-400">•</span>
<span className="text-gray-400 dark:text-zinc-500">•</span>
<span className="flex items-center gap-1.5">
<span className="text-base">📊</span>
<span className="font-semibold text-gray-900">
<span className="font-semibold text-gray-900 dark:text-zinc-100">
{combinedInfo.diff ? `${combinedInfo.projectedRatio} (${combinedInfo.diff})` : combinedInfo.projectedRatio}
</span>
</span>
Expand All @@ -189,12 +189,12 @@ export default function DualSearchResultsList({
<div className="grid grid-cols-2 gap-6">
{/* Left Column: Books */}
<div>
<h3 className="text-base font-semibold text-gray-700 mb-4 flex items-center gap-2">
<h3 className="text-base font-semibold text-gray-700 dark:text-zinc-300 mb-4 flex items-center gap-2">
📚 Books
<span className="text-sm font-normal text-gray-500">({bookResults.length})</span>
<span className="text-sm font-normal text-gray-500 dark:text-zinc-400">({bookResults.length})</span>
</h3>
{noBooks ? (
<p className="text-gray-500 text-sm">No books found</p>
<p className="text-gray-500 dark:text-zinc-400 text-sm">No books found</p>
) : (
<ul className="list-none p-0" role="list" aria-label="Book results">
{bookResults.map((result) => (
Expand All @@ -213,12 +213,12 @@ export default function DualSearchResultsList({

{/* Right Column: Audiobooks */}
<div>
<h3 className="text-base font-semibold text-gray-700 mb-4 flex items-center gap-2">
<h3 className="text-base font-semibold text-gray-700 dark:text-zinc-300 mb-4 flex items-center gap-2">
🎧 Audiobooks
<span className="text-sm font-normal text-gray-500">({audiobookResults.length})</span>
<span className="text-sm font-normal text-gray-500 dark:text-zinc-400">({audiobookResults.length})</span>
</h3>
{noAudiobooks ? (
<p className="text-gray-500 text-sm">No audiobooks found</p>
<p className="text-gray-500 dark:text-zinc-400 text-sm">No audiobooks found</p>
) : (
<ul className="list-none p-0" role="list" aria-label="Audiobook results">
{audiobookResults.map((result) => (
Expand Down
44 changes: 24 additions & 20 deletions app/components/Header.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import { useState, useEffect } from 'react';
import Image from 'next/image';
import TokenManager from './TokenManager';
import ThemeToggle from './ThemeToggle';

export default function Header({ onTokenUpdate, mamTokenExists }) {
const [showTokenManager, setShowTokenManager] = useState(false);
Expand All @@ -20,31 +21,34 @@ export default function Header({ onTokenUpdate, mamTokenExists }) {
};

return (
<div className="p-7 rounded-lg bg-gray-50">
<div className="p-7 rounded-lg bg-gray-50 dark:bg-zinc-800">
<div>
<h1 className="text-3xl font-bold flex items-center -ml-1">
<span className="mr-1">
<Image
src="/images/logo.png"
alt="Scurry Logo"
width={36}
height={36}
style={{ display: 'inline', verticalAlign: 'middle', height: 36 }}
priority
unoptimized
/>
</span>
<span className="text-gray-800">Scurry</span>
</h1>
<p className="mt-2 text-gray-500">A nimble little mouse that scurries through MyAnonamouse (MAM) and whisks books & audiobooks into qBittorrent</p>
<div className="flex items-center justify-between">
<h1 className="text-3xl font-bold flex items-center -ml-1">
<span className="mr-1">
<Image
src="/images/logo.png"
alt="Scurry Logo"
width={36}
height={36}
style={{ display: 'inline', verticalAlign: 'middle', height: 36 }}
priority
unoptimized
/>
</span>
<span className="text-gray-800 dark:text-zinc-100">Scurry</span>
</h1>
<ThemeToggle />
</div>
<p className="mt-2 text-gray-500 dark:text-zinc-400">A nimble little mouse that scurries through MyAnonamouse (MAM) and whisks books & audiobooks into qBittorrent</p>

<div className="mt-4 flex gap-3">
<button
onClick={() => setShowTokenManager(!showTokenManager)}
className={`py-2 px-4 rounded font-semibold transition-colors cursor-pointer ${
mamTokenExists
? 'bg-green-100 hover:bg-green-200 text-green-700'
: 'bg-orange-100 hover:bg-orange-200 text-orange-700'
? 'bg-green-100 hover:bg-green-200 text-green-700 dark:bg-green-900/40 dark:hover:bg-green-900/60 dark:text-green-400'
: 'bg-orange-100 hover:bg-orange-200 text-orange-700 dark:bg-orange-900/40 dark:hover:bg-orange-900/60 dark:text-orange-400'
}`}
title={mamTokenExists ? 'Manage MAM Token' : 'MAM Token Missing - Click to Add'}
>
Expand All @@ -53,7 +57,7 @@ export default function Header({ onTokenUpdate, mamTokenExists }) {

<button
onClick={handleLogout}
className="bg-gray-200 hover:bg-gray-300 text-gray-700 font-semibold py-2 px-4 rounded cursor-pointer"
className="bg-gray-200 hover:bg-gray-300 text-gray-700 dark:bg-zinc-700 dark:hover:bg-zinc-600 dark:text-zinc-200 font-semibold py-2 px-4 rounded cursor-pointer"
>
Logout
</button>
Expand All @@ -67,4 +71,4 @@ export default function Header({ onTokenUpdate, mamTokenExists }) {
</div>
</div>
);
}
}
18 changes: 9 additions & 9 deletions app/components/MobileBottomSheet.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,22 +24,22 @@ export default function MobileBottomSheet({
return (
<>
{/* Backdrop */}
<div className="fixed bottom-0 left-0 right-0 h-48 bg-gray-50 rounded-xl z-40 border-t border-gray-200"></div>
<div className="fixed bottom-0 left-0 right-0 h-48 bg-gray-50 dark:bg-zinc-900 rounded-xl z-40 border-t border-gray-200 dark:border-zinc-700"></div>

{/* Content container - single fixed element */}
<div className="fixed bottom-4 left-4 right-4 z-[100] pointer-events-none">
<div className="pointer-events-auto space-y-3">
{/* Progress indicator (only show when not both selected) */}
{!bothSelected && (
<div className="bg-white p-3 rounded-lg border border-gray-200">
<div className="bg-white dark:bg-zinc-800 p-3 rounded-lg border border-gray-200 dark:border-zinc-700">
<div className="flex items-center justify-between mb-2">
<span className="text-sm text-gray-700 whitespace-nowrap">
<span className="text-sm text-gray-700 dark:text-zinc-300 whitespace-nowrap">
<span>Step {currentStep} of 2:</span>
<span className="ml-1 font-medium">Select {stepText}</span>
</span>
<span className="text-sm text-gray-500">{progress}%</span>
<span className="text-sm text-gray-500 dark:text-zinc-400">{progress}%</span>
</div>
<div className="w-full bg-gray-200 rounded-full h-2">
<div className="w-full bg-gray-200 dark:bg-zinc-700 rounded-full h-2">
<div
className="bg-pink-400 h-2 rounded-full transition-all duration-500 ease-in-out"
style={{ width: `${progress}%` }}
Expand All @@ -50,9 +50,9 @@ export default function MobileBottomSheet({

{/* Wedge selector panel (only show when both selected and has wedges) */}
{bothSelected && hasWedges && (showBookWedge || showAudiobookWedge) && (
<div className="bg-white p-3 rounded-lg border border-gray-200">
<div className="bg-white dark:bg-zinc-800 p-3 rounded-lg border border-gray-200 dark:border-zinc-700">
<div className="flex items-center justify-center gap-3">
<span className="text-sm text-gray-700 font-medium">Use FL Wedge:</span>
<span className="text-sm text-gray-700 dark:text-zinc-300 font-medium">Use FL Wedge:</span>
{showBookWedge && (
<WedgeToggleButton
active={useBookWedge}
Expand All @@ -74,11 +74,11 @@ export default function MobileBottomSheet({
)}

{/* Download button panel */}
<div className="bg-white rounded-lg shadow-lg p-4">
<div className="bg-white dark:bg-zinc-800 rounded-lg shadow-lg p-4">
<button
onClick={onDownload}
disabled={disabled}
className="w-full rounded-md bg-pink-400 px-5 py-3 text-base font-semibold text-white hover:bg-pink-500 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-pink-500 disabled:bg-gray-300 disabled:text-gray-600 disabled:cursor-not-allowed transition-colors duration-200 flex items-center justify-center gap-2"
className="w-full rounded-md bg-pink-400 px-5 py-3 text-base font-semibold text-white hover:bg-pink-500 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-pink-500 disabled:bg-gray-300 disabled:text-gray-600 dark:disabled:bg-zinc-600 dark:disabled:text-zinc-400 disabled:cursor-not-allowed transition-colors duration-200 flex items-center justify-center gap-2"
>
{loading ? (
<>
Expand Down
Loading