feat: Moved Add URL button from sidebar footer to channels page header…

- "src/frontend/src/components/Sidebar.tsx"
- "src/frontend/src/pages/Channels.tsx"

GSD-Task: S02/T03
This commit is contained in:
jlightner 2026-04-04 09:37:39 +00:00
parent 29e8654b01
commit ed901c8240
2 changed files with 15 additions and 37 deletions

View file

@ -8,12 +8,10 @@ import {
Server,
ChevronLeft,
ChevronRight,
Link2,
} from 'lucide-react';
import { useState, useEffect } from 'react';
import { TubearrLogo } from './TubearrLogo';
import { useDownloadProgressConnection } from '../contexts/DownloadProgressContext';
import { AddUrlModal } from './AddUrlModal';
const NAV_ITEMS = [
{ to: '/', icon: Radio, label: 'Channels' },
@ -26,7 +24,6 @@ const NAV_ITEMS = [
export function Sidebar() {
const wsConnected = useDownloadProgressConnection();
const [showAddUrl, setShowAddUrl] = useState(false);
const [collapsed, setCollapsed] = useState(() => {
try {
return localStorage.getItem('tubearr-sidebar-collapsed') === 'true';
@ -132,38 +129,6 @@ export function Sidebar() {
))}
</div>
{/* Add URL button */}
<div
style={{
padding: collapsed ? 'var(--space-2) var(--space-2)' : 'var(--space-2) var(--space-3)',
borderTop: '1px solid var(--border)',
}}
>
<button
onClick={() => setShowAddUrl(true)}
title={collapsed ? 'Download URL' : undefined}
style={{
display: 'flex',
alignItems: 'center',
gap: 'var(--space-2)',
width: '100%',
padding: `var(--space-2) ${collapsed ? 'var(--space-2)' : 'var(--space-3)'}`,
borderRadius: 'var(--radius-md)',
backgroundColor: 'var(--accent)',
color: 'var(--text-inverse)',
fontSize: 'var(--font-size-sm)',
fontWeight: 600,
border: 'none',
cursor: 'pointer',
justifyContent: collapsed ? 'center' : 'flex-start',
transition: 'opacity var(--transition-fast)',
}}
>
<Link2 size={16} style={{ flexShrink: 0 }} />
{!collapsed && <span>Add URL</span>}
</button>
</div>
{/* WebSocket connection status */}
<div
style={{
@ -199,7 +164,6 @@ export function Sidebar() {
)}
</div>
<AddUrlModal open={showAddUrl} onClose={() => setShowAddUrl(false)} />
</nav>
);
}

View file

@ -1,6 +1,6 @@
import { useState, useMemo, useCallback } from 'react';
import { useNavigate } from 'react-router-dom';
import { Plus, Loader, RefreshCw, Download } from 'lucide-react';
import { Plus, Loader, RefreshCw, Download, Link2 } from 'lucide-react';
import { useChannels, useScanAllChannels } from '../api/hooks/useChannels';
import { useCollectAllMonitored } from '../api/hooks/useContent';
import { Table, type Column } from '../components/Table';
@ -8,6 +8,7 @@ import { PlatformBadge } from '../components/PlatformBadge';
import { StatusBadge } from '../components/StatusBadge';
import { ProgressBar } from '../components/ProgressBar';
import { AddChannelModal } from '../components/AddChannelModal';
import { AddUrlModal } from '../components/AddUrlModal';
import { SkeletonChannelsList } from '../components/Skeleton';
import { useToast } from '../components/Toast';
import { formatRelativeTime } from '../utils/format';
@ -18,6 +19,7 @@ import type { ChannelWithCounts } from '@shared/types/api';
export function Channels() {
const navigate = useNavigate();
const [showAddModal, setShowAddModal] = useState(false);
const [showAddUrl, setShowAddUrl] = useState(false);
const { toast } = useToast();
const { data: channels, isLoading, error, refetch } = useChannels();
@ -244,6 +246,15 @@ export function Channels() {
)}
{collectAll.isPending ? 'Collecting...' : 'Collect All Monitored'}
</button>
{/* Add URL button */}
<button
onClick={() => setShowAddUrl(true)}
className="btn btn-ghost"
title="Download URL"
>
<Link2 size={16} />
Add URL
</button>
{/* Add Channel button */}
<button
onClick={() => setShowAddModal(true)}
@ -277,6 +288,9 @@ export function Channels() {
{/* Add Channel modal */}
<AddChannelModal open={showAddModal} onClose={() => setShowAddModal(false)} />
{/* Add URL modal */}
<AddUrlModal open={showAddUrl} onClose={() => setShowAddUrl(false)} />
</div>
);
}