Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7e0baebc20 | |||
| 2520c2b248 |
+57
-34
@@ -1,5 +1,3 @@
|
||||
|
||||
|
||||
import React, { useEffect, useState, useCallback, useRef } from 'react';
|
||||
import { Playlist, ServerType, SyncStrategy, PlexServerConnection, PathMappingConfig, PathMappingMode, SyncState, ScheduleSettings, ScheduleMode, BackupSettings } from './types';
|
||||
import { apiService } from './services/api';
|
||||
@@ -17,7 +15,7 @@ import { SYNC_BANNER_PADDING_X, SYNC_BANNER_PADDING_Y, SYNC_BANNER_MIN_WIDTH } f
|
||||
import ServerPanel from './components/ServerPanel';
|
||||
import StrategySelector from './components/StrategySelector';
|
||||
import ConnectionModal from './components/ConnectionModal';
|
||||
import { ArrowLeftRight, ShieldCheck, X, Server, ServerOff, Clock, Eye, EyeOff, Type, Code2 } from 'lucide-react';
|
||||
import { ArrowLeftRight, ShieldCheck, X, Server, ServerOff, Clock, Eye, EyeOff, Type, Code2, Archive } from 'lucide-react';
|
||||
|
||||
interface Toast {
|
||||
id: number;
|
||||
@@ -542,6 +540,24 @@ const App: React.FC = () => {
|
||||
|
||||
const pathMappingInfo = getPathMappingDisplayInfo(pathMappingConfig);
|
||||
|
||||
// Helper: Calculate Backup Info
|
||||
const getBackupDisplayInfo = (settings: BackupSettings) => {
|
||||
if (!settings.enabled) {
|
||||
return {
|
||||
label: 'Backups',
|
||||
value: 'Disabled',
|
||||
active: false
|
||||
};
|
||||
}
|
||||
return {
|
||||
label: 'Backups',
|
||||
value: `Keep ${settings.retentionCount}`,
|
||||
active: true
|
||||
};
|
||||
};
|
||||
|
||||
const backupInfo = getBackupDisplayInfo(backupSettings);
|
||||
|
||||
return (
|
||||
<div className="min-h-screen flex flex-col bg-gray-900 text-gray-100 font-sans overflow-hidden bg-[radial-gradient(ellipse_at_top,_var(--tw-gradient-stops))] from-gray-800 via-gray-900 to-black">
|
||||
|
||||
@@ -619,39 +635,46 @@ const App: React.FC = () => {
|
||||
|
||||
{/* Normal Toolbar Right */}
|
||||
<div className="flex items-center gap-4">
|
||||
{/* Path Mapping Info */}
|
||||
<div className="flex flex-col items-end hidden md:flex border-r border-gray-700/50 pr-4 mr-1">
|
||||
<span className="text-[10px] uppercase font-bold text-gray-500 tracking-wider">
|
||||
{pathMappingInfo.label}
|
||||
</span>
|
||||
<div className={`text-xs font-mono flex items-center gap-1.5 ${pathMappingInfo.active ? 'text-plex-orange' : 'text-gray-600'}`}>
|
||||
{pathMappingInfo.active && <pathMappingInfo.Icon size={12} />}
|
||||
<span>{pathMappingInfo.value}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Unified Status Dock */}
|
||||
<div className="hidden md:flex items-center bg-gray-900/40 border border-gray-700/50 rounded-lg p-1 mr-2 backdrop-blur-sm shadow-sm transition-all hover:bg-gray-900/60 hover:border-gray-600/50">
|
||||
|
||||
{/* Path Mapping Section */}
|
||||
<div className="flex flex-col px-3 py-0.5 border-r border-gray-700/30 min-w-[90px] group/item">
|
||||
<span className="text-[9px] font-bold text-gray-500 uppercase tracking-widest group-hover/item:text-gray-400 transition-colors">Mapping</span>
|
||||
<div className={`flex items-center gap-1.5 text-xs font-medium ${pathMappingInfo.active ? 'text-blue-400' : 'text-gray-600'}`}>
|
||||
<pathMappingInfo.Icon size={12} strokeWidth={2.5} />
|
||||
<span className="truncate">{pathMappingInfo.value === 'Not Set' ? 'None' : pathMappingInfo.value}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Schedule Info */}
|
||||
<div className="flex flex-col items-end mr-2 md:mr-0 hidden md:flex">
|
||||
<span className="text-[10px] uppercase font-bold text-gray-500 tracking-wider">
|
||||
{scheduleInfo.label}
|
||||
</span>
|
||||
<div className="text-xs font-mono flex items-center gap-1.5">
|
||||
{/* Schedule Part */}
|
||||
<div className={`flex items-center gap-1.5 ${scheduleInfo.active ? 'text-plex-orange' : 'text-gray-600'}`}>
|
||||
{scheduleInfo.active && <Clock size={12} />}
|
||||
<span>{scheduleInfo.value}</span>
|
||||
</div>
|
||||
{/* Backup Section */}
|
||||
<div className="flex flex-col px-3 py-0.5 border-r border-gray-700/30 min-w-[90px] group/item">
|
||||
<span className="text-[9px] font-bold text-gray-500 uppercase tracking-widest group-hover/item:text-gray-400 transition-colors">Backup</span>
|
||||
<div className={`flex items-center gap-1.5 text-xs font-medium ${backupInfo.active ? 'text-indigo-400' : 'text-gray-600'}`}>
|
||||
<Archive size={12} strokeWidth={2.5} />
|
||||
<span>{backupInfo.active ? backupInfo.value.replace('Keep ', 'Retain: ') : 'Disabled'}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Watch Part */}
|
||||
<span className="text-gray-700 mx-0.5">|</span>
|
||||
<div
|
||||
className={`flex items-center gap-1 ${scheduleInfo.autoWatch ? 'text-plex-orange' : 'text-gray-600'}`}
|
||||
title={scheduleInfo.autoWatch ? "Local Playlist Monitoring Enabled" : "Local Playlist Monitoring Disabled"}
|
||||
>
|
||||
{scheduleInfo.autoWatch ? <Eye size={12} /> : <EyeOff size={12} />}
|
||||
<span className="text-[10px] font-sans font-bold">WATCH</span>
|
||||
</div>
|
||||
</div>
|
||||
{/* Schedule Section */}
|
||||
<div className="flex flex-col px-3 py-0.5 min-w-[140px] group/item">
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="text-[9px] font-bold text-gray-500 uppercase tracking-widest group-hover/item:text-gray-400 transition-colors">Auto-Sync</span>
|
||||
{/* Watch Indicator Badge */}
|
||||
<div
|
||||
className={`flex items-center gap-1 px-1 rounded-[2px] transition-colors ${scheduleInfo.autoWatch ? 'text-plex-orange bg-plex-orange/10' : 'text-gray-700 bg-gray-800'}`}
|
||||
title={scheduleInfo.autoWatch ? "Watch Mode: Active" : "Watch Mode: Disabled"}
|
||||
>
|
||||
{scheduleInfo.autoWatch ? <Eye size={9} /> : <EyeOff size={9} />}
|
||||
<span className="text-[8px] font-bold uppercase">Watch</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className={`flex items-center gap-1.5 text-xs font-medium mt-0.5 ${scheduleInfo.active ? 'text-green-400' : 'text-gray-600'}`}>
|
||||
<Clock size={12} strokeWidth={2.5} />
|
||||
<span className="truncate max-w-[120px]">{scheduleInfo.active ? scheduleInfo.value : 'Disabled'}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Connection Status Button */}
|
||||
|
||||
Reference in New Issue
Block a user