refactor: migrate remaining components to Design System v4
111 files across 14 directories: common, tree-editor, kb-accelerator, copilot, assistant, analytics, library, procedural, procedural-editor, public, script-editor, ui, admin, step-library. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -89,8 +89,8 @@ export function AddToFolderMenu({ treeId, onFolderCreated }: AddToFolderMenuProp
|
||||
setIsOpen(!isOpen)
|
||||
}}
|
||||
className={cn(
|
||||
'rounded-md border border-border p-1.5 text-muted-foreground',
|
||||
'hover:bg-accent hover:text-foreground'
|
||||
'rounded-md border border-[#1e2130] p-1.5 text-[#848b9b]',
|
||||
'hover:bg-accent hover:text-[#e2e5eb]'
|
||||
)}
|
||||
title="Add to folder"
|
||||
aria-label="Add to folder"
|
||||
@@ -101,14 +101,14 @@ export function AddToFolderMenu({ treeId, onFolderCreated }: AddToFolderMenuProp
|
||||
{isOpen && (
|
||||
<div
|
||||
className={cn(
|
||||
'absolute right-0 top-full z-20 mt-1 w-48 rounded-md border border-border',
|
||||
'bg-card backdrop-blur-xs py-1 shadow-lg'
|
||||
'absolute right-0 top-full z-20 mt-1 w-48 rounded-md border border-[#1e2130]',
|
||||
'bg-[#14161d] py-1 shadow-lg'
|
||||
)}
|
||||
>
|
||||
{isLoading ? (
|
||||
<div className="px-3 py-2 text-sm text-muted-foreground">Loading...</div>
|
||||
<div className="px-3 py-2 text-sm text-[#848b9b]">Loading...</div>
|
||||
) : folders.length === 0 ? (
|
||||
<div className="px-3 py-2 text-sm text-muted-foreground">No folders yet</div>
|
||||
<div className="px-3 py-2 text-sm text-[#848b9b]">No folders yet</div>
|
||||
) : (
|
||||
folders.map((folder) => (
|
||||
<button
|
||||
@@ -117,7 +117,7 @@ export function AddToFolderMenu({ treeId, onFolderCreated }: AddToFolderMenuProp
|
||||
e.stopPropagation()
|
||||
toggleFolder(folder.id)
|
||||
}}
|
||||
className="flex w-full items-center gap-2 px-3 py-1.5 text-sm text-muted-foreground hover:bg-accent hover:text-foreground"
|
||||
className="flex w-full items-center gap-2 px-3 py-1.5 text-sm text-[#848b9b] hover:bg-accent hover:text-[#e2e5eb]"
|
||||
>
|
||||
<div
|
||||
className="h-3 w-3 rounded-sm"
|
||||
@@ -125,13 +125,13 @@ export function AddToFolderMenu({ treeId, onFolderCreated }: AddToFolderMenuProp
|
||||
/>
|
||||
<span className="flex-1 truncate text-left">{folder.name}</span>
|
||||
{treeFolderIds.has(folder.id) && (
|
||||
<Check className="h-4 w-4 text-foreground" />
|
||||
<Check className="h-4 w-4 text-[#e2e5eb]" />
|
||||
)}
|
||||
</button>
|
||||
))
|
||||
)}
|
||||
|
||||
<div className="border-t border-border my-1" />
|
||||
<div className="border-t border-[#1e2130] my-1" />
|
||||
|
||||
<button
|
||||
onClick={(e) => {
|
||||
@@ -139,7 +139,7 @@ export function AddToFolderMenu({ treeId, onFolderCreated }: AddToFolderMenuProp
|
||||
setIsOpen(false)
|
||||
onFolderCreated?.()
|
||||
}}
|
||||
className="flex w-full items-center gap-2 px-3 py-1.5 text-sm text-muted-foreground hover:bg-accent hover:text-foreground"
|
||||
className="flex w-full items-center gap-2 px-3 py-1.5 text-sm text-[#848b9b] hover:bg-accent hover:text-[#e2e5eb]"
|
||||
>
|
||||
<Plus className="h-4 w-4" />
|
||||
Create new folder
|
||||
|
||||
@@ -53,19 +53,19 @@ export function ExportFlowModal({ treeId, treeName, onClose }: ExportFlowModalPr
|
||||
onClick={onClose}
|
||||
>
|
||||
<div
|
||||
className="w-full max-w-sm rounded-xl border border-border bg-card shadow-xl"
|
||||
className="w-full max-w-sm rounded-xl border border-[#1e2130] bg-[#14161d] shadow-xl"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
{/* Header */}
|
||||
<div className="flex items-center justify-between border-b border-border px-5 py-4">
|
||||
<div className="flex items-center justify-between border-b border-[#1e2130] px-5 py-4">
|
||||
<div className="flex items-center gap-2">
|
||||
<Download className="h-4 w-4 text-muted-foreground" />
|
||||
<h2 className="text-sm font-semibold text-foreground">Export Flow</h2>
|
||||
<Download className="h-4 w-4 text-[#848b9b]" />
|
||||
<h2 className="text-sm font-semibold text-[#e2e5eb]">Export Flow</h2>
|
||||
</div>
|
||||
<button
|
||||
onClick={onClose}
|
||||
aria-label="Close"
|
||||
className="rounded-md p-1 text-muted-foreground hover:bg-accent hover:text-foreground"
|
||||
className="rounded-md p-1 text-[#848b9b] hover:bg-accent hover:text-[#e2e5eb]"
|
||||
>
|
||||
<X className="h-4 w-4" />
|
||||
</button>
|
||||
@@ -73,13 +73,13 @@ export function ExportFlowModal({ treeId, treeName, onClose }: ExportFlowModalPr
|
||||
|
||||
{/* Body */}
|
||||
<div className="px-5 py-4">
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Export <span className="font-medium text-foreground">{treeName}</span> as a <code className="text-xs font-label">.rfflow</code> file (JSON format).
|
||||
<p className="text-sm text-[#848b9b]">
|
||||
Export <span className="font-medium text-[#e2e5eb]">{treeName}</span> as a <code className="text-xs font-sans text-xs">.rfflow</code> file (JSON format).
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Footer */}
|
||||
<div className="flex justify-end gap-2 border-t border-border px-5 py-3">
|
||||
<div className="flex justify-end gap-2 border-t border-[#1e2130] px-5 py-3">
|
||||
<Button variant="secondary" onClick={onClose}>
|
||||
Cancel
|
||||
</Button>
|
||||
|
||||
@@ -175,15 +175,15 @@ export function FolderEditModal({
|
||||
return (
|
||||
<div className="fixed inset-0 z-50 flex items-center justify-center">
|
||||
{/* Backdrop */}
|
||||
<div className="absolute inset-0 bg-black/80 backdrop-blur-xs" onClick={onClose} />
|
||||
<div className="absolute inset-0 bg-black/80" onClick={onClose} />
|
||||
|
||||
{/* Modal */}
|
||||
<div className="relative z-10 w-full max-w-md bg-card border border-border rounded-2xl p-6 shadow-lg">
|
||||
<div className="relative z-10 w-full max-w-md bg-[#14161d] border border-[#1e2130] rounded-2xl p-6 shadow-lg">
|
||||
<div className="mb-4 flex items-center justify-between">
|
||||
<h2 className="text-lg font-semibold text-foreground">
|
||||
<h2 className="text-lg font-semibold text-[#e2e5eb]">
|
||||
{isEditMode ? 'Edit Folder' : initialParentId ? 'Create Subfolder' : 'Create Folder'}
|
||||
</h2>
|
||||
<button onClick={onClose} className="rounded-md p-1 text-muted-foreground hover:bg-accent/50 hover:text-foreground">
|
||||
<button onClick={onClose} className="rounded-md p-1 text-[#848b9b] hover:bg-accent/50 hover:text-[#e2e5eb]">
|
||||
<X className="h-5 w-5" />
|
||||
</button>
|
||||
</div>
|
||||
@@ -191,7 +191,7 @@ export function FolderEditModal({
|
||||
<form onSubmit={handleSubmit}>
|
||||
{/* Name input */}
|
||||
<div className="mb-4">
|
||||
<label htmlFor="folder-name" className="block text-sm font-medium text-foreground">
|
||||
<label htmlFor="folder-name" className="block text-sm font-medium text-[#e2e5eb]">
|
||||
Name
|
||||
</label>
|
||||
<input
|
||||
@@ -202,9 +202,9 @@ export function FolderEditModal({
|
||||
placeholder="e.g., Citrix Issues"
|
||||
className={cn(
|
||||
'mt-1 block w-full rounded-md border px-3 py-2 text-sm',
|
||||
'bg-card text-foreground placeholder:text-muted-foreground',
|
||||
'bg-[#14161d] text-[#e2e5eb] placeholder:text-[#848b9b]',
|
||||
'focus:border-primary focus:outline-hidden focus:ring-1 focus:ring-primary/20',
|
||||
'border-border'
|
||||
'border-[#1e2130]'
|
||||
)}
|
||||
autoFocus
|
||||
/>
|
||||
@@ -212,7 +212,7 @@ export function FolderEditModal({
|
||||
|
||||
{/* Parent folder dropdown */}
|
||||
<div className="mb-4">
|
||||
<label htmlFor="folder-parent" className="block text-sm font-medium text-foreground">
|
||||
<label htmlFor="folder-parent" className="block text-sm font-medium text-[#e2e5eb]">
|
||||
Parent Folder
|
||||
</label>
|
||||
<select
|
||||
@@ -221,9 +221,9 @@ export function FolderEditModal({
|
||||
onChange={(e) => setParentId(e.target.value || null)}
|
||||
className={cn(
|
||||
'mt-1 block w-full rounded-md border px-3 py-2 text-sm',
|
||||
'bg-card text-foreground',
|
||||
'bg-[#14161d] text-[#e2e5eb]',
|
||||
'focus:border-primary focus:outline-hidden focus:ring-1 focus:ring-primary/20',
|
||||
'border-border'
|
||||
'border-[#1e2130]'
|
||||
)}
|
||||
>
|
||||
<option value="">None (root level)</option>
|
||||
@@ -233,14 +233,14 @@ export function FolderEditModal({
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
<p className="mt-1 text-xs text-muted-foreground">
|
||||
<p className="mt-1 text-xs text-[#848b9b]">
|
||||
Folders can be nested up to 3 levels deep.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Color picker */}
|
||||
<div className="mb-6">
|
||||
<label className="block text-sm font-medium text-foreground">Color</label>
|
||||
<label className="block text-sm font-medium text-[#e2e5eb]">Color</label>
|
||||
<div className="mt-2 flex flex-wrap gap-2">
|
||||
{FOLDER_COLORS.map((c) => (
|
||||
<button
|
||||
|
||||
@@ -115,7 +115,7 @@ function FolderItem({
|
||||
className={cn(
|
||||
'flex w-full items-center gap-1 rounded-md py-1.5 text-sm',
|
||||
'transition-colors hover:bg-accent',
|
||||
selectedFolderId === folder.id && 'bg-accent text-foreground font-medium'
|
||||
selectedFolderId === folder.id && 'bg-accent text-[#e2e5eb] font-medium'
|
||||
)}
|
||||
style={{ paddingLeft: `${8 + depth * 16}px`, paddingRight: '8px' }}
|
||||
>
|
||||
@@ -139,7 +139,7 @@ function FolderItem({
|
||||
)}
|
||||
<Folder className="h-4 w-4 shrink-0" style={{ color: folder.color }} />
|
||||
<span className="flex-1 truncate text-left">{folder.name}</span>
|
||||
<span className="text-xs text-muted-foreground group-hover:hidden">{folder.tree_count}</span>
|
||||
<span className="text-xs text-[#848b9b] group-hover:hidden">{folder.tree_count}</span>
|
||||
</button>
|
||||
|
||||
{/* Folder menu button - replaces tree count on hover */}
|
||||
@@ -161,8 +161,8 @@ function FolderItem({
|
||||
{menuOpenId === folder.id && (
|
||||
<div
|
||||
className={cn(
|
||||
'absolute right-0 top-full z-10 mt-1 w-40 rounded-md border border-border',
|
||||
'bg-card backdrop-blur-xs py-1 shadow-lg'
|
||||
'absolute right-0 top-full z-10 mt-1 w-40 rounded-md border border-[#1e2130]',
|
||||
'bg-[#14161d] py-1 shadow-lg'
|
||||
)}
|
||||
>
|
||||
<button
|
||||
@@ -171,7 +171,7 @@ function FolderItem({
|
||||
onEditFolder(folder)
|
||||
onMenuToggle(null)
|
||||
}}
|
||||
className="flex w-full items-center gap-2 px-3 py-1.5 text-sm text-muted-foreground hover:bg-accent hover:text-foreground"
|
||||
className="flex w-full items-center gap-2 px-3 py-1.5 text-sm text-[#848b9b] hover:bg-accent hover:text-[#e2e5eb]"
|
||||
>
|
||||
<Pencil className="h-3 w-3" />
|
||||
Edit
|
||||
@@ -183,7 +183,7 @@ function FolderItem({
|
||||
onAddSubfolder(folder.id)
|
||||
onMenuToggle(null)
|
||||
}}
|
||||
className="flex w-full items-center gap-2 px-3 py-1.5 text-sm text-muted-foreground hover:bg-accent hover:text-foreground"
|
||||
className="flex w-full items-center gap-2 px-3 py-1.5 text-sm text-[#848b9b] hover:bg-accent hover:text-[#e2e5eb]"
|
||||
>
|
||||
<FolderPlus className="h-3 w-3" />
|
||||
Add Subfolder
|
||||
@@ -362,13 +362,13 @@ export function FolderSidebar({
|
||||
{/* Mobile backdrop */}
|
||||
{mobileOpen && (
|
||||
<div
|
||||
className="fixed inset-0 z-40 bg-black/80 backdrop-blur-xs md:hidden"
|
||||
className="fixed inset-0 z-40 bg-black/80 md:hidden"
|
||||
onClick={onMobileClose}
|
||||
aria-hidden="true"
|
||||
/>
|
||||
)}
|
||||
<div className={cn(
|
||||
'w-56 shrink-0 border-r border-border bg-transparent',
|
||||
'w-56 shrink-0 border-r border-[#1e2130] bg-transparent',
|
||||
'hidden md:block',
|
||||
mobileOpen && 'fixed inset-y-0 left-0 z-50 block animate-slide-in-left md:relative md:animate-none'
|
||||
)}>
|
||||
@@ -376,10 +376,10 @@ export function FolderSidebar({
|
||||
{/* Mobile close button */}
|
||||
{mobileOpen && (
|
||||
<div className="mb-3 flex items-center justify-between md:hidden">
|
||||
<span className="text-sm font-medium text-foreground">Folders</span>
|
||||
<span className="text-sm font-medium text-[#e2e5eb]">Folders</span>
|
||||
<button
|
||||
onClick={onMobileClose}
|
||||
className="rounded-md p-1.5 text-muted-foreground hover:bg-accent"
|
||||
className="rounded-md p-1.5 text-[#848b9b] hover:bg-accent"
|
||||
aria-label="Close folders"
|
||||
>
|
||||
<X className="h-4 w-4" />
|
||||
@@ -388,7 +388,7 @@ export function FolderSidebar({
|
||||
)}
|
||||
<button
|
||||
onClick={() => setIsExpanded(!isExpanded)}
|
||||
className="flex w-full items-center gap-2 text-sm font-medium text-foreground"
|
||||
className="flex w-full items-center gap-2 text-sm font-medium text-[#e2e5eb]"
|
||||
>
|
||||
{isExpanded ? (
|
||||
<ChevronDown className="h-4 w-4" />
|
||||
@@ -406,7 +406,7 @@ export function FolderSidebar({
|
||||
className={cn(
|
||||
'flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-sm',
|
||||
'transition-colors hover:bg-accent',
|
||||
selectedFolderId === null && 'bg-accent text-foreground font-medium'
|
||||
selectedFolderId === null && 'bg-accent text-[#e2e5eb] font-medium'
|
||||
)}
|
||||
>
|
||||
<Folder className="h-4 w-4" />
|
||||
@@ -415,7 +415,7 @@ export function FolderSidebar({
|
||||
|
||||
{/* Loading state */}
|
||||
{isLoading ? (
|
||||
<div className="px-2 py-1.5 text-sm text-muted-foreground">Loading...</div>
|
||||
<div className="px-2 py-1.5 text-sm text-[#848b9b]">Loading...</div>
|
||||
) : (
|
||||
<>
|
||||
{/* User folders (hierarchical) */}
|
||||
@@ -445,7 +445,7 @@ export function FolderSidebar({
|
||||
onClick={() => onCreateFolder(null)}
|
||||
className={cn(
|
||||
'flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-sm',
|
||||
'text-muted-foreground transition-colors hover:bg-accent hover:text-foreground'
|
||||
'text-[#848b9b] transition-colors hover:bg-accent hover:text-[#e2e5eb]'
|
||||
)}
|
||||
>
|
||||
<Plus className="h-4 w-4" />
|
||||
@@ -460,8 +460,8 @@ export function FolderSidebar({
|
||||
{contextMenu && (
|
||||
<div
|
||||
className={cn(
|
||||
'fixed z-50 w-44 rounded-md border border-border',
|
||||
'bg-card backdrop-blur-xs py-1 shadow-lg'
|
||||
'fixed z-50 w-44 rounded-md border border-[#1e2130]',
|
||||
'bg-[#14161d] py-1 shadow-lg'
|
||||
)}
|
||||
style={{ left: contextMenu.x, top: contextMenu.y }}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
@@ -471,7 +471,7 @@ export function FolderSidebar({
|
||||
onEditFolder(contextMenu.folder)
|
||||
closeContextMenu()
|
||||
}}
|
||||
className="flex w-full items-center gap-2 px-3 py-1.5 text-sm text-muted-foreground hover:bg-accent hover:text-foreground"
|
||||
className="flex w-full items-center gap-2 px-3 py-1.5 text-sm text-[#848b9b] hover:bg-accent hover:text-[#e2e5eb]"
|
||||
>
|
||||
<Pencil className="h-3 w-3" />
|
||||
Edit
|
||||
@@ -482,7 +482,7 @@ export function FolderSidebar({
|
||||
handleAddSubfolder(contextMenu.folder.id)
|
||||
closeContextMenu()
|
||||
}}
|
||||
className="flex w-full items-center gap-2 px-3 py-1.5 text-sm text-muted-foreground hover:bg-accent hover:text-foreground"
|
||||
className="flex w-full items-center gap-2 px-3 py-1.5 text-sm text-[#848b9b] hover:bg-accent hover:text-[#e2e5eb]"
|
||||
>
|
||||
<FolderPlus className="h-3 w-3" />
|
||||
Add Subfolder
|
||||
|
||||
@@ -54,19 +54,19 @@ export function ForkModal({ treeId, treeName, onClose }: ForkModalProps) {
|
||||
onClick={onClose}
|
||||
>
|
||||
<div
|
||||
className="w-full max-w-md rounded-xl border border-border bg-card shadow-xl"
|
||||
className="w-full max-w-md rounded-xl border border-[#1e2130] bg-[#14161d] shadow-xl"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
{/* Header */}
|
||||
<div className="flex items-center justify-between border-b border-border px-5 py-4">
|
||||
<div className="flex items-center justify-between border-b border-[#1e2130] px-5 py-4">
|
||||
<div className="flex items-center gap-2">
|
||||
<GitBranch className="h-4 w-4 text-muted-foreground" />
|
||||
<h2 className="text-sm font-semibold text-foreground">Fork Flow</h2>
|
||||
<GitBranch className="h-4 w-4 text-[#848b9b]" />
|
||||
<h2 className="text-sm font-semibold text-[#e2e5eb]">Fork Flow</h2>
|
||||
</div>
|
||||
<button
|
||||
onClick={onClose}
|
||||
aria-label="Close"
|
||||
className="rounded-md p-1 text-muted-foreground hover:bg-accent hover:text-foreground"
|
||||
className="rounded-md p-1 text-[#848b9b] hover:bg-accent hover:text-[#e2e5eb]"
|
||||
>
|
||||
<X className="h-4 w-4" />
|
||||
</button>
|
||||
@@ -75,7 +75,7 @@ export function ForkModal({ treeId, treeName, onClose }: ForkModalProps) {
|
||||
{/* Body */}
|
||||
<form onSubmit={handleSubmit} className="space-y-4 px-5 py-4">
|
||||
<div>
|
||||
<label htmlFor="fork-name" className="mb-1.5 block text-xs font-medium text-muted-foreground">
|
||||
<label htmlFor="fork-name" className="mb-1.5 block text-xs font-medium text-[#848b9b]">
|
||||
Name <span className="text-red-400">*</span>
|
||||
</label>
|
||||
<input
|
||||
@@ -87,16 +87,16 @@ export function ForkModal({ treeId, treeName, onClose }: ForkModalProps) {
|
||||
autoFocus
|
||||
maxLength={255}
|
||||
className={cn(
|
||||
'w-full rounded-lg border border-border bg-card px-3 py-2 text-sm text-foreground',
|
||||
'placeholder:text-muted-foreground focus:border-primary focus:outline-hidden focus:ring-1 focus:ring-primary/20'
|
||||
'w-full rounded-lg border border-[#1e2130] bg-[#14161d] px-3 py-2 text-sm text-[#e2e5eb]',
|
||||
'placeholder:text-[#848b9b] focus:border-primary focus:outline-hidden focus:ring-1 focus:ring-primary/20'
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label htmlFor="fork-reason" className="mb-1.5 block text-xs font-medium text-muted-foreground">
|
||||
<label htmlFor="fork-reason" className="mb-1.5 block text-xs font-medium text-[#848b9b]">
|
||||
Reason for Forking{' '}
|
||||
<span className="text-muted-foreground/60">(optional)</span>
|
||||
<span className="text-[#848b9b]/60">(optional)</span>
|
||||
</label>
|
||||
<textarea
|
||||
id="fork-reason"
|
||||
@@ -105,8 +105,8 @@ export function ForkModal({ treeId, treeName, onClose }: ForkModalProps) {
|
||||
rows={3}
|
||||
placeholder="e.g. customizing for a specific client…"
|
||||
className={cn(
|
||||
'w-full resize-none rounded-lg border border-border bg-card px-3 py-2 text-sm text-foreground',
|
||||
'placeholder:text-muted-foreground focus:border-primary focus:outline-hidden focus:ring-1 focus:ring-primary/20'
|
||||
'w-full resize-none rounded-lg border border-[#1e2130] bg-[#14161d] px-3 py-2 text-sm text-[#e2e5eb]',
|
||||
'placeholder:text-[#848b9b] focus:border-primary focus:outline-hidden focus:ring-1 focus:ring-primary/20'
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -95,19 +95,19 @@ export function ImportFlowModal({ onClose }: ImportFlowModalProps) {
|
||||
onClick={onClose}
|
||||
>
|
||||
<div
|
||||
className="w-full max-w-md rounded-xl border border-border bg-card shadow-xl"
|
||||
className="w-full max-w-md rounded-xl border border-[#1e2130] bg-[#14161d] shadow-xl"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
{/* Header */}
|
||||
<div className="flex items-center justify-between border-b border-border px-5 py-4">
|
||||
<div className="flex items-center justify-between border-b border-[#1e2130] px-5 py-4">
|
||||
<div className="flex items-center gap-2">
|
||||
<FileUp className="h-4 w-4 text-muted-foreground" />
|
||||
<h2 className="text-sm font-semibold text-foreground">Import Flow</h2>
|
||||
<FileUp className="h-4 w-4 text-[#848b9b]" />
|
||||
<h2 className="text-sm font-semibold text-[#e2e5eb]">Import Flow</h2>
|
||||
</div>
|
||||
<button
|
||||
onClick={onClose}
|
||||
aria-label="Close"
|
||||
className="rounded-md p-1 text-muted-foreground hover:bg-accent hover:text-foreground"
|
||||
className="rounded-md p-1 text-[#848b9b] hover:bg-accent hover:text-[#e2e5eb]"
|
||||
>
|
||||
<X className="h-4 w-4" />
|
||||
</button>
|
||||
@@ -122,18 +122,18 @@ export function ImportFlowModal({ onClose }: ImportFlowModalProps) {
|
||||
'flex flex-col items-center justify-center rounded-lg border-2 border-dashed px-4 py-8 text-center transition-colors cursor-pointer',
|
||||
isDragging
|
||||
? 'border-primary/50 bg-primary/5'
|
||||
: 'border-border hover:border-white/[0.12]'
|
||||
: 'border-[#1e2130] hover:border-white/[0.12]'
|
||||
)}
|
||||
onClick={() => fileInputRef.current?.click()}
|
||||
onDragOver={(e) => { e.preventDefault(); setIsDragging(true) }}
|
||||
onDragLeave={() => setIsDragging(false)}
|
||||
onDrop={handleDrop}
|
||||
>
|
||||
<FileUp className="mb-2 h-8 w-8 text-muted-foreground" />
|
||||
<p className="text-sm text-foreground">
|
||||
Drop .rfflow file here or <span className="text-primary cursor-pointer">browse</span>
|
||||
<FileUp className="mb-2 h-8 w-8 text-[#848b9b]" />
|
||||
<p className="text-sm text-[#e2e5eb]">
|
||||
Drop .rfflow file here or <span className="text-[#22d3ee] cursor-pointer">browse</span>
|
||||
</p>
|
||||
<p className="mt-1 text-xs text-muted-foreground">JSON format</p>
|
||||
<p className="mt-1 text-xs text-[#848b9b]">JSON format</p>
|
||||
</div>
|
||||
<input
|
||||
ref={fileInputRef}
|
||||
@@ -155,7 +155,7 @@ export function ImportFlowModal({ onClose }: ImportFlowModalProps) {
|
||||
<div className="space-y-4">
|
||||
{/* Editable name */}
|
||||
<div>
|
||||
<label htmlFor="import-name" className="mb-1.5 block text-xs font-medium text-muted-foreground">
|
||||
<label htmlFor="import-name" className="mb-1.5 block text-xs font-medium text-[#848b9b]">
|
||||
Name
|
||||
</label>
|
||||
<input
|
||||
@@ -165,8 +165,8 @@ export function ImportFlowModal({ onClose }: ImportFlowModalProps) {
|
||||
onChange={(e) => setNameOverride(e.target.value)}
|
||||
maxLength={255}
|
||||
className={cn(
|
||||
'w-full rounded-lg border border-border bg-card px-3 py-2 text-sm text-foreground',
|
||||
'placeholder:text-muted-foreground focus:border-primary focus:outline-hidden focus:ring-1 focus:ring-primary/20'
|
||||
'w-full rounded-lg border border-[#1e2130] bg-[#14161d] px-3 py-2 text-sm text-[#e2e5eb]',
|
||||
'placeholder:text-[#848b9b] focus:border-primary focus:outline-hidden focus:ring-1 focus:ring-primary/20'
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
@@ -174,31 +174,31 @@ export function ImportFlowModal({ onClose }: ImportFlowModalProps) {
|
||||
{/* Flow info */}
|
||||
<div className="space-y-2 text-xs">
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="text-muted-foreground">Type:</span>
|
||||
<span className="rounded bg-primary/10 px-2 py-0.5 font-label text-primary">
|
||||
<span className="text-[#848b9b]">Type:</span>
|
||||
<span className="rounded bg-[rgba(34,211,238,0.10)] px-2 py-0.5 font-sans text-xs text-[#22d3ee]">
|
||||
{TYPE_LABELS[parsed.flow.tree_type] || parsed.flow.tree_type}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{parsed.flow.description && (
|
||||
<div>
|
||||
<span className="text-muted-foreground">Description:</span>
|
||||
<p className="mt-0.5 text-foreground line-clamp-2">{parsed.flow.description}</p>
|
||||
<span className="text-[#848b9b]">Description:</span>
|
||||
<p className="mt-0.5 text-[#e2e5eb] line-clamp-2">{parsed.flow.description}</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{parsed.flow.category && (
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="text-muted-foreground">Category:</span>
|
||||
<span className="text-foreground">{parsed.flow.category.name}</span>
|
||||
<span className="text-[#848b9b]">Category:</span>
|
||||
<span className="text-[#e2e5eb]">{parsed.flow.category.name}</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{parsed.flow.tags.length > 0 && (
|
||||
<div className="flex flex-wrap items-center gap-1.5">
|
||||
<span className="text-muted-foreground">Tags:</span>
|
||||
<span className="text-[#848b9b]">Tags:</span>
|
||||
{parsed.flow.tags.map((tag) => (
|
||||
<span key={tag} className="rounded bg-card border border-border px-2 py-0.5 font-label text-foreground">
|
||||
<span key={tag} className="rounded bg-[#14161d] border border-[#1e2130] px-2 py-0.5 font-sans text-xs text-[#e2e5eb]">
|
||||
{tag}
|
||||
</span>
|
||||
))}
|
||||
@@ -207,26 +207,26 @@ export function ImportFlowModal({ onClose }: ImportFlowModalProps) {
|
||||
|
||||
{parsed.flow.author_name && (
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="text-muted-foreground">Original author:</span>
|
||||
<span className="text-foreground">{parsed.flow.author_name}</span>
|
||||
<span className="text-[#848b9b]">Original author:</span>
|
||||
<span className="text-[#e2e5eb]">{parsed.flow.author_name}</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="text-muted-foreground">Version:</span>
|
||||
<span className="text-foreground">v{parsed.flow.version}</span>
|
||||
<span className="text-[#848b9b]">Version:</span>
|
||||
<span className="text-[#e2e5eb]">v{parsed.flow.version}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p className="text-xs text-muted-foreground">
|
||||
Flow will be imported as a <span className="font-medium text-foreground">draft</span>.
|
||||
<p className="text-xs text-[#848b9b]">
|
||||
Flow will be imported as a <span className="font-medium text-[#e2e5eb]">draft</span>.
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Footer */}
|
||||
<div className="flex justify-end gap-2 border-t border-border px-5 py-3">
|
||||
<div className="flex justify-end gap-2 border-t border-[#1e2130] px-5 py-3">
|
||||
{step === 'preview' && (
|
||||
<Button
|
||||
variant="secondary"
|
||||
|
||||
@@ -115,18 +115,18 @@ export function ShareTreeModal({ tree, isOpen, onClose }: ShareTreeModalProps) {
|
||||
<div className="fixed inset-0 z-50 flex items-end justify-center p-0 sm:items-center sm:p-4">
|
||||
{/* Backdrop */}
|
||||
<div
|
||||
className="absolute inset-0 bg-black/80 backdrop-blur-xs"
|
||||
className="absolute inset-0 bg-black/80"
|
||||
onClick={onClose}
|
||||
/>
|
||||
|
||||
{/* Modal */}
|
||||
<div className="relative w-full max-w-full rounded-t-2xl bg-card border border-border shadow-lg sm:max-w-lg sm:rounded-2xl">
|
||||
<div className="relative w-full max-w-full rounded-t-2xl bg-[#14161d] border border-[#1e2130] shadow-lg sm:max-w-lg sm:rounded-2xl">
|
||||
{/* Header */}
|
||||
<div className="flex items-center justify-between border-b border-border px-6 py-4">
|
||||
<h2 className="text-lg font-semibold text-foreground">Share Tree</h2>
|
||||
<div className="flex items-center justify-between border-b border-[#1e2130] px-6 py-4">
|
||||
<h2 className="text-lg font-semibold text-[#e2e5eb]">Share Tree</h2>
|
||||
<button
|
||||
onClick={onClose}
|
||||
className="rounded-md p-1 text-muted-foreground hover:bg-accent/50 hover:text-foreground"
|
||||
className="rounded-md p-1 text-[#848b9b] hover:bg-accent/50 hover:text-[#e2e5eb]"
|
||||
>
|
||||
<X className="h-5 w-5" />
|
||||
</button>
|
||||
@@ -136,9 +136,9 @@ export function ShareTreeModal({ tree, isOpen, onClose }: ShareTreeModalProps) {
|
||||
<div className="px-6 py-4 space-y-6">
|
||||
{/* Tree Info */}
|
||||
<div>
|
||||
<h3 className="font-medium text-foreground">{tree.name}</h3>
|
||||
<h3 className="font-medium text-[#e2e5eb]">{tree.name}</h3>
|
||||
{tree.description && (
|
||||
<p className="mt-1 text-sm text-muted-foreground line-clamp-2">
|
||||
<p className="mt-1 text-sm text-[#848b9b] line-clamp-2">
|
||||
{tree.description}
|
||||
</p>
|
||||
)}
|
||||
@@ -146,7 +146,7 @@ export function ShareTreeModal({ tree, isOpen, onClose }: ShareTreeModalProps) {
|
||||
|
||||
{/* Visibility Settings */}
|
||||
<div>
|
||||
<label className="mb-2 block text-sm font-medium text-foreground">
|
||||
<label className="mb-2 block text-sm font-medium text-[#e2e5eb]">
|
||||
Visibility
|
||||
</label>
|
||||
<div className="space-y-2">
|
||||
@@ -157,14 +157,14 @@ export function ShareTreeModal({ tree, isOpen, onClose }: ShareTreeModalProps) {
|
||||
className={cn(
|
||||
'flex w-full items-center gap-3 rounded-md border px-4 py-3 text-left transition-colors',
|
||||
visibility === level
|
||||
? 'border-border bg-accent text-foreground'
|
||||
: 'border-border bg-transparent text-muted-foreground hover:border-primary/30 hover:bg-accent/50'
|
||||
? 'border-[#1e2130] bg-accent text-[#e2e5eb]'
|
||||
: 'border-[#1e2130] bg-transparent text-[#848b9b] hover:border-primary/30 hover:bg-accent/50'
|
||||
)}
|
||||
>
|
||||
{getVisibilityIcon(level)}
|
||||
<div className="flex-1">
|
||||
<div className="text-sm font-medium capitalize">{level}</div>
|
||||
<div className="text-xs text-muted-foreground">
|
||||
<div className="text-xs text-[#848b9b]">
|
||||
{getVisibilityDescription(level)}
|
||||
</div>
|
||||
</div>
|
||||
@@ -179,7 +179,7 @@ export function ShareTreeModal({ tree, isOpen, onClose }: ShareTreeModalProps) {
|
||||
{/* Share Link Generation */}
|
||||
{visibility !== 'private' && (
|
||||
<div>
|
||||
<label className="mb-2 block text-sm font-medium text-foreground">
|
||||
<label className="mb-2 block text-sm font-medium text-[#e2e5eb]">
|
||||
Share Link
|
||||
</label>
|
||||
|
||||
@@ -190,11 +190,11 @@ export function ShareTreeModal({ tree, isOpen, onClose }: ShareTreeModalProps) {
|
||||
id="allow-forking"
|
||||
checked={allowForking}
|
||||
onChange={(e) => setAllowForking(e.target.checked)}
|
||||
className="h-4 w-4 rounded border-border bg-card text-foreground focus:ring-2 focus:ring-primary/20 focus:ring-offset-2 focus:ring-offset-black"
|
||||
className="h-4 w-4 rounded border-[#1e2130] bg-[#14161d] text-[#e2e5eb] focus:ring-2 focus:ring-primary/20 focus:ring-offset-2 focus:ring-offset-black"
|
||||
/>
|
||||
<label
|
||||
htmlFor="allow-forking"
|
||||
className="text-sm text-muted-foreground cursor-pointer"
|
||||
className="text-sm text-[#848b9b] cursor-pointer"
|
||||
>
|
||||
Allow recipients to fork this tree
|
||||
</label>
|
||||
@@ -214,20 +214,20 @@ export function ShareTreeModal({ tree, isOpen, onClose }: ShareTreeModalProps) {
|
||||
{/* Active Share Link */}
|
||||
{activeShare && (
|
||||
<div className="space-y-2">
|
||||
<div className="flex items-center gap-2 rounded-md border border-border bg-card p-3">
|
||||
<div className="flex items-center gap-2 rounded-md border border-[#1e2130] bg-[#14161d] p-3">
|
||||
<input
|
||||
type="text"
|
||||
value={activeShare.share_url}
|
||||
readOnly
|
||||
className="flex-1 bg-transparent text-sm text-foreground outline-hidden"
|
||||
className="flex-1 bg-transparent text-sm text-[#e2e5eb] outline-hidden"
|
||||
/>
|
||||
<button
|
||||
onClick={handleCopyLink}
|
||||
className={cn(
|
||||
'flex items-center gap-2 rounded-md border border-border px-3 py-1.5 text-sm font-medium transition-colors',
|
||||
'flex items-center gap-2 rounded-md border border-[#1e2130] px-3 py-1.5 text-sm font-medium transition-colors',
|
||||
copied
|
||||
? 'border-green-500 bg-green-500/10 text-green-400'
|
||||
: 'text-muted-foreground hover:bg-accent hover:text-foreground'
|
||||
: 'text-[#848b9b] hover:bg-accent hover:text-[#e2e5eb]'
|
||||
)}
|
||||
>
|
||||
{copied ? (
|
||||
@@ -243,13 +243,13 @@ export function ShareTreeModal({ tree, isOpen, onClose }: ShareTreeModalProps) {
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
<p className="text-xs text-[#848b9b]">
|
||||
{activeShare.allow_forking
|
||||
? 'Recipients can fork this tree'
|
||||
: 'Forking disabled for this share'}
|
||||
</p>
|
||||
{shares.length > 1 && (
|
||||
<p className="text-xs text-muted-foreground">
|
||||
<p className="text-xs text-[#848b9b]">
|
||||
{shares.length} active share links
|
||||
</p>
|
||||
)}
|
||||
@@ -260,7 +260,7 @@ export function ShareTreeModal({ tree, isOpen, onClose }: ShareTreeModalProps) {
|
||||
</div>
|
||||
|
||||
{/* Footer */}
|
||||
<div className="flex justify-end gap-3 border-t border-border px-6 py-4">
|
||||
<div className="flex justify-end gap-3 border-t border-[#1e2130] px-6 py-4">
|
||||
<Button variant="secondary" onClick={onClose}>
|
||||
Close
|
||||
</Button>
|
||||
|
||||
@@ -21,7 +21,7 @@ const sortOptions: { value: SortBy; label: string }[] = [
|
||||
export function SortDropdown({ value, onChange, className }: SortDropdownProps) {
|
||||
return (
|
||||
<div className={cn('relative inline-flex items-center', className)}>
|
||||
<span className="mr-2 flex items-center gap-1.5 text-sm text-muted-foreground">
|
||||
<span className="mr-2 flex items-center gap-1.5 text-sm text-[#848b9b]">
|
||||
<ArrowUpDown className="h-4 w-4" />
|
||||
<span className="hidden sm:inline">Sort:</span>
|
||||
</span>
|
||||
@@ -29,8 +29,8 @@ export function SortDropdown({ value, onChange, className }: SortDropdownProps)
|
||||
value={value}
|
||||
onChange={(e) => onChange(e.target.value as SortBy)}
|
||||
className={cn(
|
||||
'rounded-md border border-border bg-card px-3 py-1.5 text-sm',
|
||||
'text-foreground focus:border-primary focus:outline-hidden focus:ring-1 focus:ring-primary/20'
|
||||
'rounded-md border border-[#1e2130] bg-[#14161d] px-3 py-1.5 text-sm',
|
||||
'text-[#e2e5eb] focus:border-primary focus:outline-hidden focus:ring-1 focus:ring-primary/20'
|
||||
)}
|
||||
>
|
||||
{sortOptions.map((option) => (
|
||||
|
||||
@@ -34,11 +34,11 @@ export function TreeGridView({
|
||||
{trees.map((tree) => (
|
||||
<div
|
||||
key={tree.id}
|
||||
className="relative bg-card border border-border rounded-2xl p-4 transition-all hover:-translate-y-0.5 hover:border-primary/30 hover:shadow-md sm:p-6"
|
||||
className="relative bg-[#14161d] border border-[#1e2130] rounded-2xl p-4 transition-all hover:-translate-y-0.5 hover:border-primary/30 hover:shadow-md sm:p-6"
|
||||
>
|
||||
<div className="mb-2 flex items-start justify-between gap-2">
|
||||
<div className="flex items-center gap-2">
|
||||
<h3 className="font-semibold text-foreground">{tree.name}</h3>
|
||||
<h3 className="font-semibold text-[#e2e5eb]">{tree.name}</h3>
|
||||
{tree.status === 'draft' && (
|
||||
<span className="inline-flex items-center gap-1 rounded-full bg-yellow-400/10 px-2 py-0.5 text-xs font-medium text-yellow-400">
|
||||
<FileText className="h-3 w-3" />
|
||||
@@ -46,7 +46,7 @@ export function TreeGridView({
|
||||
</span>
|
||||
)}
|
||||
{tree.tree_type === 'maintenance' && (
|
||||
<span className="inline-flex items-center gap-1 rounded-full border border-amber-500/30 bg-amber-500/10 px-2 py-0.5 font-label text-[0.625rem] uppercase tracking-wide text-amber-400">
|
||||
<span className="inline-flex items-center gap-1 rounded-full border border-amber-500/30 bg-amber-500/10 px-2 py-0.5 font-sans text-xs text-[0.625rem] uppercase tracking-wide text-amber-400">
|
||||
<Wrench className="h-3 w-3" />
|
||||
Maintenance
|
||||
</span>
|
||||
@@ -60,21 +60,21 @@ export function TreeGridView({
|
||||
<div className="flex items-center gap-2">
|
||||
{tree.is_public ? (
|
||||
<span title="Public tree">
|
||||
<Globe className="h-4 w-4 text-muted-foreground" />
|
||||
<Globe className="h-4 w-4 text-[#848b9b]" />
|
||||
</span>
|
||||
) : (
|
||||
<span title="Private tree">
|
||||
<Lock className="h-4 w-4 text-muted-foreground" />
|
||||
<Lock className="h-4 w-4 text-[#848b9b]" />
|
||||
</span>
|
||||
)}
|
||||
{tree.category_info && (
|
||||
<span className="rounded-full bg-accent px-2 py-0.5 text-xs text-muted-foreground">
|
||||
<span className="rounded-full bg-accent px-2 py-0.5 text-xs text-[#848b9b]">
|
||||
{tree.category_info.name}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<p className="mb-3 text-sm text-muted-foreground line-clamp-2">
|
||||
<p className="mb-3 text-sm text-[#848b9b] line-clamp-2">
|
||||
{tree.description || 'No description available'}
|
||||
</p>
|
||||
|
||||
@@ -86,7 +86,7 @@ export function TreeGridView({
|
||||
)}
|
||||
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="text-xs text-muted-foreground">
|
||||
<span className="text-xs text-[#848b9b]">
|
||||
v{tree.version} · {tree.usage_count} uses
|
||||
</span>
|
||||
<div className="flex items-center gap-2">
|
||||
@@ -95,8 +95,8 @@ export function TreeGridView({
|
||||
type="button"
|
||||
onClick={() => onExportTree(tree.id)}
|
||||
className={cn(
|
||||
'rounded-md border border-border p-2 text-muted-foreground',
|
||||
'hover:bg-accent hover:text-foreground'
|
||||
'rounded-md border border-[#1e2130] p-2 text-[#848b9b]',
|
||||
'hover:bg-accent hover:text-[#e2e5eb]'
|
||||
)}
|
||||
title="Export flow"
|
||||
aria-label="Export flow"
|
||||
@@ -109,8 +109,8 @@ export function TreeGridView({
|
||||
type="button"
|
||||
onClick={() => onForkTree(tree.id)}
|
||||
className={cn(
|
||||
'rounded-md border border-border p-2 text-muted-foreground',
|
||||
'hover:bg-accent hover:text-foreground'
|
||||
'rounded-md border border-[#1e2130] p-2 text-[#848b9b]',
|
||||
'hover:bg-accent hover:text-[#e2e5eb]'
|
||||
)}
|
||||
title="Fork tree"
|
||||
aria-label="Fork tree"
|
||||
@@ -122,8 +122,8 @@ export function TreeGridView({
|
||||
<Link
|
||||
to={getTreeEditorPath(tree.id, tree.tree_type)}
|
||||
className={cn(
|
||||
'rounded-md border border-border p-2 text-muted-foreground',
|
||||
'hover:bg-accent hover:text-foreground'
|
||||
'rounded-md border border-[#1e2130] p-2 text-[#848b9b]',
|
||||
'hover:bg-accent hover:text-[#e2e5eb]'
|
||||
)}
|
||||
title="Edit tree"
|
||||
aria-label="Edit tree"
|
||||
@@ -136,7 +136,7 @@ export function TreeGridView({
|
||||
type="button"
|
||||
onClick={() => onDeleteTree(tree)}
|
||||
className={cn(
|
||||
'rounded-md border border-border p-1.5 text-muted-foreground',
|
||||
'rounded-md border border-[#1e2130] p-1.5 text-[#848b9b]',
|
||||
'hover:bg-red-400/10 hover:text-red-400'
|
||||
)}
|
||||
title="Delete tree"
|
||||
@@ -150,7 +150,7 @@ export function TreeGridView({
|
||||
type="button"
|
||||
onClick={() => onPrepareSession(tree)}
|
||||
className={cn(
|
||||
'rounded-md border border-border p-2 text-muted-foreground',
|
||||
'rounded-md border border-[#1e2130] p-2 text-[#848b9b]',
|
||||
'hover:bg-cyan-500/10 hover:text-cyan-400 hover:border-cyan-500/30'
|
||||
)}
|
||||
title="Prepare session for engineer"
|
||||
@@ -163,8 +163,8 @@ export function TreeGridView({
|
||||
type="button"
|
||||
onClick={() => onStartSession(tree.id, tree.tree_type)}
|
||||
className={cn(
|
||||
'rounded-md bg-gradient-brand px-3 py-2 text-sm font-medium text-white shadow-lg shadow-primary/20',
|
||||
'hover:opacity-90'
|
||||
'rounded-md bg-[#22d3ee] px-3 py-2 text-sm font-medium text-white',
|
||||
'hover:brightness-110'
|
||||
)}
|
||||
>
|
||||
Start Session
|
||||
|
||||
@@ -33,12 +33,12 @@ export function TreeListView({
|
||||
{trees.map((tree) => (
|
||||
<div
|
||||
key={tree.id}
|
||||
className="flex items-center gap-4 bg-card border border-border rounded-2xl p-4 transition-all hover:border-primary/30 hover:shadow-xs"
|
||||
className="flex items-center gap-4 bg-[#14161d] border border-[#1e2130] rounded-2xl p-4 transition-all hover:border-primary/30 hover:shadow-xs"
|
||||
>
|
||||
{/* Left: Name and Description */}
|
||||
<div className="flex-1 min-w-0">
|
||||
<div className="flex items-center gap-2 mb-1">
|
||||
<h3 className="font-semibold text-foreground truncate">{tree.name}</h3>
|
||||
<h3 className="font-semibold text-[#e2e5eb] truncate">{tree.name}</h3>
|
||||
{tree.status === 'draft' && (
|
||||
<span className="inline-flex items-center gap-1 rounded-full bg-yellow-400/10 px-2 py-0.5 text-xs font-medium text-yellow-400 shrink-0">
|
||||
<FileText className="h-3 w-3" />
|
||||
@@ -46,7 +46,7 @@ export function TreeListView({
|
||||
</span>
|
||||
)}
|
||||
{tree.tree_type === 'maintenance' && (
|
||||
<span className="inline-flex items-center gap-1 rounded-full border border-amber-500/30 bg-amber-500/10 px-2 py-0.5 font-label text-[0.625rem] uppercase tracking-wide text-amber-400 shrink-0">
|
||||
<span className="inline-flex items-center gap-1 rounded-full border border-amber-500/30 bg-amber-500/10 px-2 py-0.5 font-sans text-xs text-[0.625rem] uppercase tracking-wide text-amber-400 shrink-0">
|
||||
<Wrench className="h-3 w-3" />
|
||||
Maintenance
|
||||
</span>
|
||||
@@ -58,15 +58,15 @@ export function TreeListView({
|
||||
)}
|
||||
{tree.is_public ? (
|
||||
<span title="Public tree">
|
||||
<Globe className="h-3.5 w-3.5 text-muted-foreground shrink-0" />
|
||||
<Globe className="h-3.5 w-3.5 text-[#848b9b] shrink-0" />
|
||||
</span>
|
||||
) : (
|
||||
<span title="Private tree">
|
||||
<Lock className="h-3.5 w-3.5 text-muted-foreground shrink-0" />
|
||||
<Lock className="h-3.5 w-3.5 text-[#848b9b] shrink-0" />
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<p className="text-sm text-muted-foreground truncate">
|
||||
<p className="text-sm text-[#848b9b] truncate">
|
||||
{tree.description || 'No description available'}
|
||||
</p>
|
||||
</div>
|
||||
@@ -74,7 +74,7 @@ export function TreeListView({
|
||||
{/* Center: Category and Tags */}
|
||||
<div className="hidden lg:flex items-center gap-2 min-w-0" style={{ maxWidth: '300px' }}>
|
||||
{tree.category_info && (
|
||||
<span className="rounded-full bg-accent px-2 py-0.5 text-xs text-muted-foreground whitespace-nowrap">
|
||||
<span className="rounded-full bg-accent px-2 py-0.5 text-xs text-[#848b9b] whitespace-nowrap">
|
||||
{tree.category_info.name}
|
||||
</span>
|
||||
)}
|
||||
@@ -87,7 +87,7 @@ export function TreeListView({
|
||||
|
||||
{/* Right: Metadata and Actions */}
|
||||
<div className="flex items-center gap-3 shrink-0">
|
||||
<div className="hidden sm:flex flex-col items-end text-xs text-muted-foreground">
|
||||
<div className="hidden sm:flex flex-col items-end text-xs text-[#848b9b]">
|
||||
<span>v{tree.version}</span>
|
||||
<span>{tree.usage_count} uses</span>
|
||||
</div>
|
||||
@@ -98,8 +98,8 @@ export function TreeListView({
|
||||
type="button"
|
||||
onClick={() => onExportTree(tree.id)}
|
||||
className={cn(
|
||||
'rounded-md border border-border p-1.5 text-muted-foreground',
|
||||
'hover:bg-accent hover:text-foreground'
|
||||
'rounded-md border border-[#1e2130] p-1.5 text-[#848b9b]',
|
||||
'hover:bg-accent hover:text-[#e2e5eb]'
|
||||
)}
|
||||
title="Export flow"
|
||||
aria-label="Export flow"
|
||||
@@ -112,8 +112,8 @@ export function TreeListView({
|
||||
type="button"
|
||||
onClick={() => onForkTree(tree.id)}
|
||||
className={cn(
|
||||
'rounded-md border border-border p-1.5 text-muted-foreground',
|
||||
'hover:bg-accent hover:text-foreground'
|
||||
'rounded-md border border-[#1e2130] p-1.5 text-[#848b9b]',
|
||||
'hover:bg-accent hover:text-[#e2e5eb]'
|
||||
)}
|
||||
title="Fork tree"
|
||||
aria-label="Fork tree"
|
||||
@@ -126,8 +126,8 @@ export function TreeListView({
|
||||
<Link
|
||||
to={getTreeEditorPath(tree.id, tree.tree_type)}
|
||||
className={cn(
|
||||
'rounded-md border border-border p-1.5 text-muted-foreground',
|
||||
'hover:bg-accent hover:text-foreground'
|
||||
'rounded-md border border-[#1e2130] p-1.5 text-[#848b9b]',
|
||||
'hover:bg-accent hover:text-[#e2e5eb]'
|
||||
)}
|
||||
title="Edit tree"
|
||||
aria-label="Edit tree"
|
||||
@@ -138,7 +138,7 @@ export function TreeListView({
|
||||
type="button"
|
||||
onClick={() => onDeleteTree(tree)}
|
||||
className={cn(
|
||||
'rounded-md border border-border p-1.5 text-muted-foreground',
|
||||
'rounded-md border border-[#1e2130] p-1.5 text-[#848b9b]',
|
||||
'hover:bg-red-500/20 hover:text-red-400'
|
||||
)}
|
||||
title="Delete tree"
|
||||
@@ -153,7 +153,7 @@ export function TreeListView({
|
||||
type="button"
|
||||
onClick={() => onPrepareSession(tree)}
|
||||
className={cn(
|
||||
'rounded-md border border-border p-1.5 text-muted-foreground',
|
||||
'rounded-md border border-[#1e2130] p-1.5 text-[#848b9b]',
|
||||
'hover:bg-cyan-500/10 hover:text-cyan-400 hover:border-cyan-500/30'
|
||||
)}
|
||||
title="Prepare session for engineer"
|
||||
@@ -166,8 +166,8 @@ export function TreeListView({
|
||||
type="button"
|
||||
onClick={() => onStartSession(tree.id, tree.tree_type)}
|
||||
className={cn(
|
||||
'rounded-md bg-gradient-brand px-3 py-1.5 text-sm font-medium text-white shadow-lg shadow-primary/20',
|
||||
'hover:opacity-90 whitespace-nowrap'
|
||||
'rounded-md bg-[#22d3ee] px-3 py-1.5 text-sm font-medium text-white',
|
||||
'hover:brightness-110 whitespace-nowrap'
|
||||
)}
|
||||
>
|
||||
Start
|
||||
|
||||
@@ -73,12 +73,12 @@ export function TreeTableView({
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="overflow-x-auto rounded-2xl border border-border">
|
||||
<div className="overflow-x-auto rounded-2xl border border-[#1e2130]">
|
||||
<table className="w-full">
|
||||
<thead className="bg-accent/50 sticky top-0 z-10">
|
||||
<tr className="border-b border-border">
|
||||
<tr className="border-b border-[#1e2130]">
|
||||
<th
|
||||
className="px-4 py-3 text-left text-sm font-medium text-muted-foreground cursor-pointer hover:text-foreground"
|
||||
className="px-4 py-3 text-left text-sm font-medium text-[#848b9b] cursor-pointer hover:text-[#e2e5eb]"
|
||||
onClick={() => handleSort('name')}
|
||||
>
|
||||
<div className="flex items-center gap-1">
|
||||
@@ -86,11 +86,11 @@ export function TreeTableView({
|
||||
{getSortIcon('name')}
|
||||
</div>
|
||||
</th>
|
||||
<th className="hidden md:table-cell px-4 py-3 text-left text-sm font-medium text-muted-foreground">
|
||||
<th className="hidden md:table-cell px-4 py-3 text-left text-sm font-medium text-[#848b9b]">
|
||||
Description
|
||||
</th>
|
||||
<th
|
||||
className="hidden lg:table-cell px-4 py-3 text-left text-sm font-medium text-muted-foreground cursor-pointer hover:text-foreground"
|
||||
className="hidden lg:table-cell px-4 py-3 text-left text-sm font-medium text-[#848b9b] cursor-pointer hover:text-[#e2e5eb]"
|
||||
onClick={() => handleSort('category')}
|
||||
>
|
||||
<div className="flex items-center gap-1">
|
||||
@@ -98,11 +98,11 @@ export function TreeTableView({
|
||||
{getSortIcon('category')}
|
||||
</div>
|
||||
</th>
|
||||
<th className="hidden xl:table-cell px-4 py-3 text-left text-sm font-medium text-muted-foreground">
|
||||
<th className="hidden xl:table-cell px-4 py-3 text-left text-sm font-medium text-[#848b9b]">
|
||||
Tags
|
||||
</th>
|
||||
<th
|
||||
className="hidden sm:table-cell px-4 py-3 text-center text-sm font-medium text-muted-foreground cursor-pointer hover:text-foreground"
|
||||
className="hidden sm:table-cell px-4 py-3 text-center text-sm font-medium text-[#848b9b] cursor-pointer hover:text-[#e2e5eb]"
|
||||
onClick={() => handleSort('version')}
|
||||
>
|
||||
<div className="flex items-center justify-center gap-1">
|
||||
@@ -111,7 +111,7 @@ export function TreeTableView({
|
||||
</div>
|
||||
</th>
|
||||
<th
|
||||
className="hidden sm:table-cell px-4 py-3 text-center text-sm font-medium text-muted-foreground cursor-pointer hover:text-foreground"
|
||||
className="hidden sm:table-cell px-4 py-3 text-center text-sm font-medium text-[#848b9b] cursor-pointer hover:text-[#e2e5eb]"
|
||||
onClick={() => handleSort('usage')}
|
||||
>
|
||||
<div className="flex items-center justify-center gap-1">
|
||||
@@ -120,7 +120,7 @@ export function TreeTableView({
|
||||
</div>
|
||||
</th>
|
||||
<th
|
||||
className="hidden md:table-cell px-4 py-3 text-left text-sm font-medium text-muted-foreground cursor-pointer hover:text-foreground"
|
||||
className="hidden md:table-cell px-4 py-3 text-left text-sm font-medium text-[#848b9b] cursor-pointer hover:text-[#e2e5eb]"
|
||||
onClick={() => handleSort('updated')}
|
||||
>
|
||||
<div className="flex items-center gap-1">
|
||||
@@ -128,17 +128,17 @@ export function TreeTableView({
|
||||
{getSortIcon('updated')}
|
||||
</div>
|
||||
</th>
|
||||
<th className="px-4 py-3 text-right text-sm font-medium text-muted-foreground">
|
||||
<th className="px-4 py-3 text-right text-sm font-medium text-[#848b9b]">
|
||||
Actions
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="bg-transparent">
|
||||
{trees.map((tree) => (
|
||||
<tr key={tree.id} className="border-b border-border last:border-0 hover:bg-accent/50">
|
||||
<tr key={tree.id} className="border-b border-[#1e2130] last:border-0 hover:bg-accent/50">
|
||||
<td className="px-4 py-3">
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="font-medium text-foreground truncate max-w-[200px]">
|
||||
<span className="font-medium text-[#e2e5eb] truncate max-w-[200px]">
|
||||
{tree.name}
|
||||
</span>
|
||||
{tree.status === 'draft' && (
|
||||
@@ -148,7 +148,7 @@ export function TreeTableView({
|
||||
</span>
|
||||
)}
|
||||
{tree.tree_type === 'maintenance' && (
|
||||
<span className="inline-flex items-center gap-1 rounded-full border border-amber-500/30 bg-amber-500/10 px-2 py-0.5 font-label text-[0.625rem] uppercase tracking-wide text-amber-400 shrink-0">
|
||||
<span className="inline-flex items-center gap-1 rounded-full border border-amber-500/30 bg-amber-500/10 px-2 py-0.5 font-sans text-xs text-[0.625rem] uppercase tracking-wide text-amber-400 shrink-0">
|
||||
<Wrench className="h-3 w-3" />
|
||||
Maintenance
|
||||
</span>
|
||||
@@ -160,23 +160,23 @@ export function TreeTableView({
|
||||
)}
|
||||
{tree.is_public ? (
|
||||
<span title="Public tree">
|
||||
<Globe className="h-3.5 w-3.5 text-muted-foreground shrink-0" />
|
||||
<Globe className="h-3.5 w-3.5 text-[#848b9b] shrink-0" />
|
||||
</span>
|
||||
) : (
|
||||
<span title="Private tree">
|
||||
<Lock className="h-3.5 w-3.5 text-muted-foreground shrink-0" />
|
||||
<Lock className="h-3.5 w-3.5 text-[#848b9b] shrink-0" />
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</td>
|
||||
<td className="hidden md:table-cell px-4 py-3 text-sm text-muted-foreground">
|
||||
<td className="hidden md:table-cell px-4 py-3 text-sm text-[#848b9b]">
|
||||
<span className="truncate block max-w-[250px]">
|
||||
{tree.description || 'No description'}
|
||||
</span>
|
||||
</td>
|
||||
<td className="hidden lg:table-cell px-4 py-3">
|
||||
{tree.category_info && (
|
||||
<span className="inline-block rounded-full bg-accent px-2 py-0.5 text-xs text-muted-foreground">
|
||||
<span className="inline-block rounded-full bg-accent px-2 py-0.5 text-xs text-[#848b9b]">
|
||||
{tree.category_info.name}
|
||||
</span>
|
||||
)}
|
||||
@@ -186,13 +186,13 @@ export function TreeTableView({
|
||||
<TagBadges tags={tree.tags} maxVisible={2} onTagClick={onTagClick} />
|
||||
)}
|
||||
</td>
|
||||
<td className="hidden sm:table-cell px-4 py-3 text-center text-sm text-muted-foreground">
|
||||
<td className="hidden sm:table-cell px-4 py-3 text-center text-sm text-[#848b9b]">
|
||||
v{tree.version}
|
||||
</td>
|
||||
<td className="hidden sm:table-cell px-4 py-3 text-center text-sm text-muted-foreground">
|
||||
<td className="hidden sm:table-cell px-4 py-3 text-center text-sm text-[#848b9b]">
|
||||
{tree.usage_count}
|
||||
</td>
|
||||
<td className="hidden md:table-cell px-4 py-3 text-sm text-muted-foreground">
|
||||
<td className="hidden md:table-cell px-4 py-3 text-sm text-[#848b9b]">
|
||||
{formatDate(tree.updated_at)}
|
||||
</td>
|
||||
<td className="px-4 py-3">
|
||||
@@ -202,8 +202,8 @@ export function TreeTableView({
|
||||
type="button"
|
||||
onClick={() => onExportTree(tree.id)}
|
||||
className={cn(
|
||||
'rounded-md border border-border p-1.5 text-muted-foreground',
|
||||
'hover:bg-accent hover:text-foreground'
|
||||
'rounded-md border border-[#1e2130] p-1.5 text-[#848b9b]',
|
||||
'hover:bg-accent hover:text-[#e2e5eb]'
|
||||
)}
|
||||
title="Export flow"
|
||||
aria-label="Export flow"
|
||||
@@ -216,8 +216,8 @@ export function TreeTableView({
|
||||
type="button"
|
||||
onClick={() => onForkTree(tree.id)}
|
||||
className={cn(
|
||||
'rounded-md border border-border p-1.5 text-muted-foreground',
|
||||
'hover:bg-accent hover:text-foreground'
|
||||
'rounded-md border border-[#1e2130] p-1.5 text-[#848b9b]',
|
||||
'hover:bg-accent hover:text-[#e2e5eb]'
|
||||
)}
|
||||
title="Fork tree"
|
||||
aria-label="Fork tree"
|
||||
@@ -230,8 +230,8 @@ export function TreeTableView({
|
||||
<Link
|
||||
to={getTreeEditorPath(tree.id, tree.tree_type)}
|
||||
className={cn(
|
||||
'rounded-md border border-border p-1.5 text-muted-foreground',
|
||||
'hover:bg-accent hover:text-foreground'
|
||||
'rounded-md border border-[#1e2130] p-1.5 text-[#848b9b]',
|
||||
'hover:bg-accent hover:text-[#e2e5eb]'
|
||||
)}
|
||||
title="Edit tree"
|
||||
aria-label="Edit tree"
|
||||
@@ -242,7 +242,7 @@ export function TreeTableView({
|
||||
type="button"
|
||||
onClick={() => onDeleteTree(tree)}
|
||||
className={cn(
|
||||
'rounded-md border border-border p-1.5 text-muted-foreground',
|
||||
'rounded-md border border-[#1e2130] p-1.5 text-[#848b9b]',
|
||||
'hover:bg-red-500/20 hover:text-red-400'
|
||||
)}
|
||||
title="Delete tree"
|
||||
@@ -257,7 +257,7 @@ export function TreeTableView({
|
||||
type="button"
|
||||
onClick={() => onPrepareSession(tree)}
|
||||
className={cn(
|
||||
'rounded-md border border-border p-1.5 text-muted-foreground',
|
||||
'rounded-md border border-[#1e2130] p-1.5 text-[#848b9b]',
|
||||
'hover:bg-cyan-500/10 hover:text-cyan-400 hover:border-cyan-500/30'
|
||||
)}
|
||||
title="Prepare session for engineer"
|
||||
@@ -270,8 +270,8 @@ export function TreeTableView({
|
||||
type="button"
|
||||
onClick={() => onStartSession(tree.id, tree.tree_type)}
|
||||
className={cn(
|
||||
'rounded-md bg-gradient-brand px-3 py-1.5 text-xs font-medium text-white shadow-lg shadow-primary/20',
|
||||
'hover:opacity-90 whitespace-nowrap'
|
||||
'rounded-md bg-[#22d3ee] px-3 py-1.5 text-xs font-medium text-white',
|
||||
'hover:brightness-110 whitespace-nowrap'
|
||||
)}
|
||||
>
|
||||
Start
|
||||
|
||||
@@ -11,15 +11,15 @@ interface ViewToggleProps {
|
||||
|
||||
export function ViewToggle({ view, onChange, className }: ViewToggleProps) {
|
||||
return (
|
||||
<div className={cn('flex items-center gap-1 rounded-md border border-border p-1', className)}>
|
||||
<div className={cn('flex items-center gap-1 rounded-md border border-[#1e2130] p-1', className)}>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => onChange('grid')}
|
||||
className={cn(
|
||||
'rounded p-1.5 transition-colors',
|
||||
view === 'grid'
|
||||
? 'bg-accent text-foreground border-border'
|
||||
: 'text-muted-foreground hover:bg-accent hover:text-foreground'
|
||||
? 'bg-accent text-[#e2e5eb] border-[#1e2130]'
|
||||
: 'text-[#848b9b] hover:bg-accent hover:text-[#e2e5eb]'
|
||||
)}
|
||||
title="Grid view"
|
||||
aria-label="Grid view"
|
||||
@@ -32,8 +32,8 @@ export function ViewToggle({ view, onChange, className }: ViewToggleProps) {
|
||||
className={cn(
|
||||
'rounded p-1.5 transition-colors',
|
||||
view === 'list'
|
||||
? 'bg-accent text-foreground border-border'
|
||||
: 'text-muted-foreground hover:bg-accent hover:text-foreground'
|
||||
? 'bg-accent text-[#e2e5eb] border-[#1e2130]'
|
||||
: 'text-[#848b9b] hover:bg-accent hover:text-[#e2e5eb]'
|
||||
)}
|
||||
title="List view"
|
||||
aria-label="List view"
|
||||
@@ -46,8 +46,8 @@ export function ViewToggle({ view, onChange, className }: ViewToggleProps) {
|
||||
className={cn(
|
||||
'rounded p-1.5 transition-colors',
|
||||
view === 'table'
|
||||
? 'bg-accent text-foreground border-border'
|
||||
: 'text-muted-foreground hover:bg-accent hover:text-foreground'
|
||||
? 'bg-accent text-[#e2e5eb] border-[#1e2130]'
|
||||
: 'text-[#848b9b] hover:bg-accent hover:text-[#e2e5eb]'
|
||||
)}
|
||||
title="Table view"
|
||||
aria-label="Table view"
|
||||
|
||||
Reference in New Issue
Block a user