ge-tool/components/PathBar.tsx

129 lines
6.5 KiB
TypeScript
Raw Normal View History

2025-12-10 06:41:43 +00:00
import React from 'react';
interface PathBarProps {
currentPath: string;
canGoBack: boolean;
canGoForward: boolean;
onNavigateBack: () => void;
onNavigateForward: () => void;
currentMode?: 'api' | 'sharing' | null;
hasCustomPath?: boolean;
isCustomPath?: boolean;
onSaveCustomPath?: () => void;
isSavingCustomPath?: boolean;
searchQuery?: string;
onSearchChange?: (query: string) => void;
}
/**
* PathBar component hiển thị đưng dẫn hiện tại nút điều hướng Back/Forward
*/
export function PathBar({
currentPath,
canGoBack,
canGoForward,
onNavigateBack,
onNavigateForward,
currentMode = null,
hasCustomPath = false,
isCustomPath = false,
onSaveCustomPath,
isSavingCustomPath = false,
searchQuery = '',
onSearchChange,
}: PathBarProps) {
return (
<div className="flex items-center gap-3 px-4 py-2 bg-slate-900/50 border-b border-slate-700">
{/* Navigation Buttons */}
<div className="flex items-center gap-1">
<button
onClick={onNavigateBack}
disabled={!canGoBack}
className={`p-1.5 rounded transition-colors ${canGoBack
? 'hover:bg-slate-700 text-slate-300 hover:text-white'
: 'text-slate-600 cursor-not-allowed'
}`}
title="Quay lại"
>
<svg className="w-5 h-5" viewBox="0 0 24 24" fill="currentColor">
<path fillRule="evenodd" d="M7.72 12.53a.75.75 0 0 1 0-1.06l7.5-7.5a.75.75 0 1 1 1.06 1.06L9.31 12l6.97 6.97a.75.75 0 1 1-1.06 1.06l-7.5-7.5Z" clipRule="evenodd" />
</svg>
</button>
<button
onClick={onNavigateForward}
disabled={!canGoForward}
className={`p-1.5 rounded transition-colors ${canGoForward
? 'hover:bg-slate-700 text-slate-300 hover:text-white'
: 'text-slate-600 cursor-not-allowed'
}`}
title="Tiến tới"
>
<svg className="w-5 h-5" viewBox="0 0 24 24" fill="currentColor">
<path fillRule="evenodd" d="M16.28 11.47a.75.75 0 0 1 0 1.06l-7.5 7.5a.75.75 0 0 1-1.06-1.06L14.69 12 7.72 5.03a.75.75 0 0 1 1.06-1.06l7.5 7.5Z" clipRule="evenodd" />
</svg>
</button>
</div>
{/* Current Path - Highlight if custom path */}
<div className="flex-1 min-w-0">
<div
className={`font-mono text-sm truncate transition-colors ${isCustomPath
? 'text-amber-400 font-semibold'
: 'text-slate-300'
}`}
title={`${currentPath || '/'}${isCustomPath ? ' (Custom Path)' : ''}`}
>
{currentPath || '/'}
</div>
</div>
{/* Search Input */}
{onSearchChange && (
<div className="w-auto">
<input
type="text"
value={searchQuery}
onChange={(e) => onSearchChange(e.target.value)}
placeholder="Tìm kiếm..."
className="w-32 px-3 py-1.5 text-sm bg-slate-800 border border-slate-600 rounded-lg text-slate-200 placeholder-slate-500 focus:outline-none focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500 transition-colors"
/>
</div>
)}
{/* Save Custom Path Button - Only show in Sharing mode */}
{onSaveCustomPath && currentMode === 'sharing' && (
<button
onClick={onSaveCustomPath}
disabled={isSavingCustomPath}
className={`px-3 py-1.5 text-xs font-medium rounded-lg border transition-all duration-200 flex items-center gap-1.5 ${hasCustomPath
? 'bg-indigo-600/20 text-indigo-300 border border-indigo-500/50 hover:bg-indigo-600/30 hover:border-indigo-500/70'
: 'bg-emerald-600/20 text-emerald-300 border border-emerald-500/50 hover:bg-emerald-600/30 hover:border-emerald-500/70'
} disabled:opacity-50 disabled:cursor-not-allowed`}
title={hasCustomPath ? 'Cập nhật custom path' : 'Lưu path hiện tại làm custom path'}
>
{isSavingCustomPath ? (
<>
<svg className="animate-spin h-3 w-3" fill="none" viewBox="0 0 24 24">
<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>
<span>Đang lưu...</span>
</>
) : (
<>
<svg className="w-3.5 h-3.5" viewBox="0 0 24 24" fill="currentColor">
{hasCustomPath ? (
<path fillRule="evenodd" d="M4.755 10.059a7.5 7.5 0 0 1 12.548-3.364l1.903 1.903h-3.183a.75.75 0 1 0 0 1.5h4.992a.75.75 0 0 0 .75-.75V4.356a.75.75 0 0 0-1.5 0v3.18l-1.9-1.9A9 9 0 0 0 3.306 9.67a.75.75 0 1 0 1.45.388Zm15.408 3.352a.75.75 0 0 0-.919.53 7.5 7.5 0 0 1-12.548 3.364l-1.902-1.903h3.183a.75.75 0 0 0 0-1.5H2.984a.75.75 0 0 0-.75.75v4.992a.75.75 0 0 0 1.5 0v-3.18l1.9 1.9a9 9 0 0 0 15.059-4.035.75.75 0 0 0-.53-.918Z" clipRule="evenodd" />
) : (
<path fillRule="evenodd" d="M12 3.75a.75.75 0 0 1 .75.75v6.75h6.75a.75.75 0 0 1 0 1.5h-6.75v6.75a.75.75 0 0 1-1.5 0v-6.75H4.5a.75.75 0 0 1 0-1.5h6.75V4.5a.75.75 0 0 1 .75-.75Z" clipRule="evenodd" />
)}
</svg>
<span>{hasCustomPath ? 'Update' : 'Add'}</span>
</>
)}
</button>
)}
</div>
);
}