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:
@@ -65,14 +65,14 @@ export function CustomStepModal({ isOpen, onClose, onInsertStep }: CustomStepMod
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="fixed inset-0 z-50 flex items-end justify-center bg-black/80 backdrop-blur-xs sm:items-center sm:p-4">
|
||||
<div className="relative flex h-[95vh] w-full max-w-full flex-col border border-border bg-card shadow-lg sm:h-[90vh] sm:max-w-4xl sm:rounded-2xl">
|
||||
<div className="fixed inset-0 z-50 flex items-end justify-center bg-black/80 sm:items-center sm:p-4">
|
||||
<div className="relative flex h-[95vh] w-full max-w-full flex-col border border-[#1e2130] bg-[#14161d] shadow-lg sm:h-[90vh] sm:max-w-4xl sm:rounded-2xl">
|
||||
{/* Header */}
|
||||
<div className="flex items-center justify-between border-b border-border p-4">
|
||||
<h2 className="text-lg font-semibold text-foreground">Add Custom Step</h2>
|
||||
<div className="flex items-center justify-between border-b border-[#1e2130] p-4">
|
||||
<h2 className="text-lg font-semibold text-[#e2e5eb]">Add Custom Step</h2>
|
||||
<button
|
||||
onClick={onClose}
|
||||
className="rounded-md p-1.5 text-muted-foreground hover:bg-accent hover:text-foreground"
|
||||
className="rounded-md p-1.5 text-[#848b9b] hover:bg-accent hover:text-[#e2e5eb]"
|
||||
aria-label="Close"
|
||||
>
|
||||
<X className="h-5 w-5" />
|
||||
@@ -80,15 +80,15 @@ export function CustomStepModal({ isOpen, onClose, onInsertStep }: CustomStepMod
|
||||
</div>
|
||||
|
||||
{/* Tabs */}
|
||||
<div className="flex border-b border-border">
|
||||
<div className="flex border-b border-[#1e2130]">
|
||||
{canCreateSteps && (
|
||||
<button
|
||||
onClick={() => setActiveTab('create')}
|
||||
className={cn(
|
||||
'flex-1 px-4 py-3 text-sm font-medium transition-colors',
|
||||
activeTab === 'create'
|
||||
? 'border-b-2 border-primary bg-primary/5 text-foreground'
|
||||
: 'text-muted-foreground hover:bg-accent hover:text-foreground'
|
||||
? 'border-b-2 border-primary bg-primary/5 text-[#e2e5eb]'
|
||||
: 'text-[#848b9b] hover:bg-accent hover:text-[#e2e5eb]'
|
||||
)}
|
||||
>
|
||||
Type My Own
|
||||
@@ -99,8 +99,8 @@ export function CustomStepModal({ isOpen, onClose, onInsertStep }: CustomStepMod
|
||||
className={cn(
|
||||
'flex-1 px-4 py-3 text-sm font-medium transition-colors',
|
||||
activeTab === 'browse'
|
||||
? 'border-b-2 border-primary bg-primary/5 text-primary'
|
||||
: 'text-muted-foreground hover:bg-muted/50 hover:text-foreground'
|
||||
? 'border-b-2 border-primary bg-primary/5 text-[#22d3ee]'
|
||||
: 'text-[#848b9b] hover:bg-muted/50 hover:text-[#e2e5eb]'
|
||||
)}
|
||||
>
|
||||
Browse Library
|
||||
@@ -133,10 +133,10 @@ export function CustomStepModal({ isOpen, onClose, onInsertStep }: CustomStepMod
|
||||
|
||||
{/* Loading Overlay */}
|
||||
{isSubmitting && (
|
||||
<div className="absolute inset-0 flex items-center justify-center bg-black/80 backdrop-blur-xs">
|
||||
<div className="absolute inset-0 flex items-center justify-center bg-black/80">
|
||||
<div className="flex flex-col items-center gap-3">
|
||||
<Spinner className="border-t-foreground" />
|
||||
<p className="text-sm text-muted-foreground">Creating step...</p>
|
||||
<p className="text-sm text-[#848b9b]">Creating step...</p>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -33,7 +33,7 @@ export function StepCard({ step, onPreview, onInsert, onEdit, onDelete, onSave,
|
||||
const isOwn = currentUserId ? step.created_by === currentUserId : false
|
||||
|
||||
return (
|
||||
<div className="group rounded-lg border border-border bg-card p-4 transition-shadow hover:shadow-md">
|
||||
<div className="group rounded-lg border border-[#1e2130] bg-[#14161d] p-4 transition-shadow hover:shadow-md">
|
||||
{/* Header */}
|
||||
<div className="mb-3 flex items-start justify-between gap-2">
|
||||
<div className="flex-1">
|
||||
@@ -65,12 +65,12 @@ export function StepCard({ step, onPreview, onInsert, onEdit, onDelete, onSave,
|
||||
</div>
|
||||
|
||||
{/* Title */}
|
||||
<h3 className="font-semibold text-foreground line-clamp-2">{step.title}</h3>
|
||||
<h3 className="font-semibold text-[#e2e5eb] line-clamp-2">{step.title}</h3>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Metadata */}
|
||||
<div className="mb-3 space-y-1.5 text-sm text-muted-foreground">
|
||||
<div className="mb-3 space-y-1.5 text-sm text-[#848b9b]">
|
||||
{/* Category */}
|
||||
{step.category_name && (
|
||||
<div className="flex items-center gap-1.5">
|
||||
@@ -116,13 +116,13 @@ export function StepCard({ step, onPreview, onInsert, onEdit, onDelete, onSave,
|
||||
{visibleTags.map(tag => (
|
||||
<span
|
||||
key={tag}
|
||||
className="rounded-full bg-accent px-2 py-0.5 text-xs text-muted-foreground"
|
||||
className="rounded-full bg-accent px-2 py-0.5 text-xs text-[#848b9b]"
|
||||
>
|
||||
{tag}
|
||||
</span>
|
||||
))}
|
||||
{remainingTags > 0 && (
|
||||
<span className="rounded-full bg-muted px-2 py-0.5 text-xs text-muted-foreground">
|
||||
<span className="rounded-full bg-muted px-2 py-0.5 text-xs text-[#848b9b]">
|
||||
+{remainingTags} more
|
||||
</span>
|
||||
)}
|
||||
@@ -138,14 +138,14 @@ export function StepCard({ step, onPreview, onInsert, onEdit, onDelete, onSave,
|
||||
<>
|
||||
<button
|
||||
onClick={() => onPreview(step)}
|
||||
className="flex flex-1 items-center justify-center gap-2 rounded-md border border-border px-3 py-2 text-sm font-medium text-muted-foreground hover:bg-accent hover:text-foreground transition-colors"
|
||||
className="flex flex-1 items-center justify-center gap-2 rounded-md border border-[#1e2130] px-3 py-2 text-sm font-medium text-[#848b9b] hover:bg-accent hover:text-[#e2e5eb] transition-colors"
|
||||
>
|
||||
<Eye className="h-4 w-4" />
|
||||
Preview
|
||||
</button>
|
||||
<span
|
||||
title="Managed by source flow — fork to customize"
|
||||
className="flex items-center justify-center rounded-md border border-border px-3 py-2 text-muted-foreground opacity-50 cursor-default"
|
||||
className="flex items-center justify-center rounded-md border border-[#1e2130] px-3 py-2 text-[#848b9b] opacity-50 cursor-default"
|
||||
>
|
||||
<Lock className="h-4 w-4" />
|
||||
</span>
|
||||
@@ -155,21 +155,21 @@ export function StepCard({ step, onPreview, onInsert, onEdit, onDelete, onSave,
|
||||
<>
|
||||
<button
|
||||
onClick={() => onPreview(step)}
|
||||
className="flex flex-1 items-center justify-center gap-2 rounded-md border border-border px-3 py-2 text-sm font-medium text-muted-foreground hover:bg-accent hover:text-foreground transition-colors"
|
||||
className="flex flex-1 items-center justify-center gap-2 rounded-md border border-[#1e2130] px-3 py-2 text-sm font-medium text-[#848b9b] hover:bg-accent hover:text-[#e2e5eb] transition-colors"
|
||||
>
|
||||
<Eye className="h-4 w-4" />
|
||||
Preview
|
||||
</button>
|
||||
<button
|
||||
onClick={() => onEdit?.(step)}
|
||||
className="flex flex-1 items-center justify-center gap-2 rounded-md border border-border px-3 py-2 text-sm font-medium text-muted-foreground hover:bg-accent hover:text-foreground transition-colors"
|
||||
className="flex flex-1 items-center justify-center gap-2 rounded-md border border-[#1e2130] px-3 py-2 text-sm font-medium text-[#848b9b] hover:bg-accent hover:text-[#e2e5eb] transition-colors"
|
||||
>
|
||||
<Pencil className="h-4 w-4" />
|
||||
Edit
|
||||
</button>
|
||||
<button
|
||||
onClick={() => onDelete?.(step)}
|
||||
className="flex items-center justify-center rounded-md border border-border px-3 py-2 text-muted-foreground hover:bg-red-400/10 hover:text-red-400 hover:border-red-400/30 transition-colors"
|
||||
className="flex items-center justify-center rounded-md border border-[#1e2130] px-3 py-2 text-[#848b9b] hover:bg-red-400/10 hover:text-red-400 hover:border-red-400/30 transition-colors"
|
||||
aria-label="Delete step"
|
||||
>
|
||||
<Trash2 className="h-4 w-4" />
|
||||
@@ -181,14 +181,14 @@ export function StepCard({ step, onPreview, onInsert, onEdit, onDelete, onSave,
|
||||
<>
|
||||
<button
|
||||
onClick={() => onPreview(step)}
|
||||
className="flex flex-1 items-center justify-center gap-2 rounded-md border border-border px-3 py-2 text-sm font-medium text-muted-foreground hover:bg-accent hover:text-foreground transition-colors"
|
||||
className="flex flex-1 items-center justify-center gap-2 rounded-md border border-[#1e2130] px-3 py-2 text-sm font-medium text-[#848b9b] hover:bg-accent hover:text-[#e2e5eb] transition-colors"
|
||||
>
|
||||
<Eye className="h-4 w-4" />
|
||||
Preview
|
||||
</button>
|
||||
<button
|
||||
onClick={() => onSave?.(step)}
|
||||
className="flex flex-1 items-center justify-center gap-2 rounded-md bg-gradient-brand text-white shadow-lg shadow-primary/20 px-3 py-2 text-sm font-medium hover:opacity-90 transition-colors"
|
||||
className="flex flex-1 items-center justify-center gap-2 rounded-md bg-[#22d3ee] text-white px-3 py-2 text-sm font-medium hover:brightness-110 transition-colors"
|
||||
>
|
||||
<Bookmark className="h-4 w-4" />
|
||||
Save
|
||||
@@ -200,14 +200,14 @@ export function StepCard({ step, onPreview, onInsert, onEdit, onDelete, onSave,
|
||||
<>
|
||||
<button
|
||||
onClick={() => onPreview(step)}
|
||||
className="flex flex-1 items-center justify-center gap-2 rounded-md border border-border px-3 py-2 text-sm font-medium text-muted-foreground hover:bg-accent hover:text-foreground transition-colors"
|
||||
className="flex flex-1 items-center justify-center gap-2 rounded-md border border-[#1e2130] px-3 py-2 text-sm font-medium text-[#848b9b] hover:bg-accent hover:text-[#e2e5eb] transition-colors"
|
||||
>
|
||||
<Eye className="h-4 w-4" />
|
||||
Preview
|
||||
</button>
|
||||
<button
|
||||
onClick={() => onInsert?.(step)}
|
||||
className="flex flex-1 items-center justify-center gap-2 rounded-md bg-gradient-brand text-white shadow-lg shadow-primary/20 px-3 py-2 text-sm font-medium hover:opacity-90 transition-colors"
|
||||
className="flex flex-1 items-center justify-center gap-2 rounded-md bg-[#22d3ee] text-white px-3 py-2 text-sm font-medium hover:brightness-110 transition-colors"
|
||||
>
|
||||
<Plus className="h-4 w-4" />
|
||||
Insert
|
||||
|
||||
@@ -76,10 +76,10 @@ export function StepDetailModal({ stepId, onClose, onInsert }: StepDetailModalPr
|
||||
const visibleReviews = showAllReviews ? allTextReviews : allTextReviews.slice(0, 3)
|
||||
|
||||
return (
|
||||
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/80 backdrop-blur-xs">
|
||||
<div className="relative flex h-[90vh] w-full max-w-3xl flex-col bg-card border border-border rounded-2xl shadow-lg">
|
||||
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/80">
|
||||
<div className="relative flex h-[90vh] w-full max-w-3xl flex-col bg-[#14161d] border border-[#1e2130] rounded-2xl shadow-lg">
|
||||
{/* Header */}
|
||||
<div className="flex items-start justify-between border-b border-border p-6 pb-4">
|
||||
<div className="flex items-start justify-between border-b border-[#1e2130] p-6 pb-4">
|
||||
{isLoading ? (
|
||||
<div className="h-6 w-48 animate-pulse rounded bg-accent" />
|
||||
) : error ? (
|
||||
@@ -97,7 +97,7 @@ export function StepDetailModal({ stepId, onClose, onInsert }: StepDetailModalPr
|
||||
{step.step_type}
|
||||
</span>
|
||||
{step.category_name && (
|
||||
<span className="text-xs text-muted-foreground">{step.category_name}</span>
|
||||
<span className="text-xs text-[#848b9b]">{step.category_name}</span>
|
||||
)}
|
||||
{step.is_featured && (
|
||||
<span className="rounded bg-yellow-400/10 px-2 py-0.5 text-xs font-medium text-yellow-400">
|
||||
@@ -110,12 +110,12 @@ export function StepDetailModal({ stepId, onClose, onInsert }: StepDetailModalPr
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<h2 className="text-xl font-semibold text-foreground">{step.title}</h2>
|
||||
<h2 className="text-xl font-semibold text-[#e2e5eb]">{step.title}</h2>
|
||||
</div>
|
||||
) : null}
|
||||
<button
|
||||
onClick={onClose}
|
||||
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]"
|
||||
aria-label="Close"
|
||||
>
|
||||
<X className="h-5 w-5" />
|
||||
@@ -131,13 +131,13 @@ export function StepDetailModal({ stepId, onClose, onInsert }: StepDetailModalPr
|
||||
<div className="h-4 w-5/6 animate-pulse rounded bg-accent" />
|
||||
</div>
|
||||
) : error ? (
|
||||
<p className="text-sm text-muted-foreground">{error}</p>
|
||||
<p className="text-sm text-[#848b9b]">{error}</p>
|
||||
) : step ? (
|
||||
<div className="space-y-6">
|
||||
{/* Rating */}
|
||||
{hasRating && (
|
||||
<div>
|
||||
<h3 className="mb-2 text-sm font-semibold text-foreground">Rating</h3>
|
||||
<h3 className="mb-2 text-sm font-semibold text-[#e2e5eb]">Rating</h3>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="flex items-center gap-1">
|
||||
{[1, 2, 3, 4, 5].map(i => (
|
||||
@@ -147,12 +147,12 @@ export function StepDetailModal({ stepId, onClose, onInsert }: StepDetailModalPr
|
||||
'h-4 w-4',
|
||||
i <= Math.round(step.rating_average)
|
||||
? 'fill-yellow-400 text-yellow-400'
|
||||
: 'text-muted-foreground'
|
||||
: 'text-[#848b9b]'
|
||||
)}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
<span className="text-sm text-muted-foreground">
|
||||
<span className="text-sm text-[#848b9b]">
|
||||
{step.rating_average.toFixed(1)} ({step.rating_count} {step.rating_count === 1 ? 'rating' : 'ratings'})
|
||||
</span>
|
||||
</div>
|
||||
@@ -162,12 +162,12 @@ export function StepDetailModal({ stepId, onClose, onInsert }: StepDetailModalPr
|
||||
{/* Tags */}
|
||||
{step.tags.length > 0 && (
|
||||
<div>
|
||||
<h3 className="mb-2 text-sm font-semibold text-foreground">Tags</h3>
|
||||
<h3 className="mb-2 text-sm font-semibold text-[#e2e5eb]">Tags</h3>
|
||||
<div className="flex flex-wrap gap-1.5">
|
||||
{step.tags.map(tag => (
|
||||
<span
|
||||
key={tag}
|
||||
className="rounded-full bg-accent px-2 py-1 text-xs text-muted-foreground"
|
||||
className="rounded-full bg-accent px-2 py-1 text-xs text-[#848b9b]"
|
||||
>
|
||||
{tag}
|
||||
</span>
|
||||
@@ -179,7 +179,7 @@ export function StepDetailModal({ stepId, onClose, onInsert }: StepDetailModalPr
|
||||
{/* Instructions */}
|
||||
<div>
|
||||
<h3 className="mb-2 text-sm font-semibold">Instructions</h3>
|
||||
<div className="rounded-lg border border-border bg-accent/50 p-4">
|
||||
<div className="rounded-lg border border-[#1e2130] bg-accent/50 p-4">
|
||||
<MarkdownContent content={step.content.instructions} />
|
||||
</div>
|
||||
</div>
|
||||
@@ -187,8 +187,8 @@ export function StepDetailModal({ stepId, onClose, onInsert }: StepDetailModalPr
|
||||
{/* Help Text */}
|
||||
{step.content.help_text && (
|
||||
<div>
|
||||
<h3 className="mb-2 text-sm font-semibold text-foreground">Help Text</h3>
|
||||
<div className="rounded-lg border border-border bg-blue-400/5 p-4 text-sm">
|
||||
<h3 className="mb-2 text-sm font-semibold text-[#e2e5eb]">Help Text</h3>
|
||||
<div className="rounded-lg border border-[#1e2130] bg-blue-400/5 p-4 text-sm">
|
||||
<MarkdownContent content={step.content.help_text} />
|
||||
</div>
|
||||
</div>
|
||||
@@ -197,19 +197,19 @@ export function StepDetailModal({ stepId, onClose, onInsert }: StepDetailModalPr
|
||||
{/* Commands */}
|
||||
{step.content.commands && step.content.commands.length > 0 && (
|
||||
<div>
|
||||
<h3 className="mb-2 text-sm font-semibold text-foreground">Commands</h3>
|
||||
<h3 className="mb-2 text-sm font-semibold text-[#e2e5eb]">Commands</h3>
|
||||
<div className="space-y-2">
|
||||
{step.content.commands.map((cmd, index) => (
|
||||
<div key={index} className="group relative">
|
||||
<div className="mb-1 flex items-center justify-between">
|
||||
<span className="text-xs font-medium text-muted-foreground">{cmd.label}</span>
|
||||
<span className="text-xs font-medium text-[#848b9b]">{cmd.label}</span>
|
||||
<button
|
||||
onClick={() => handleCopyCommand(cmd.command, index)}
|
||||
className={cn(
|
||||
'flex items-center gap-1 rounded px-2 py-1 text-xs transition-colors',
|
||||
copiedCommandIndex === index
|
||||
? 'bg-emerald-400/10 text-emerald-400'
|
||||
: 'bg-accent text-muted-foreground hover:bg-accent hover:text-foreground'
|
||||
: 'bg-accent text-[#848b9b] hover:bg-accent hover:text-[#e2e5eb]'
|
||||
)}
|
||||
>
|
||||
{copiedCommandIndex === index ? (
|
||||
@@ -225,7 +225,7 @@ export function StepDetailModal({ stepId, onClose, onInsert }: StepDetailModalPr
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
<pre className="overflow-x-auto rounded bg-card p-3 text-xs text-foreground">
|
||||
<pre className="overflow-x-auto rounded bg-[#14161d] p-3 text-xs text-[#e2e5eb]">
|
||||
<code>{cmd.command}</code>
|
||||
</pre>
|
||||
</div>
|
||||
@@ -238,11 +238,11 @@ export function StepDetailModal({ stepId, onClose, onInsert }: StepDetailModalPr
|
||||
{visibleReviews.length > 0 && (
|
||||
<div>
|
||||
<div className="mb-2 flex items-center justify-between">
|
||||
<h3 className="text-sm font-semibold text-foreground">Reviews</h3>
|
||||
<h3 className="text-sm font-semibold text-[#e2e5eb]">Reviews</h3>
|
||||
{allTextReviews.length > 3 && (
|
||||
<button
|
||||
onClick={() => setShowAllReviews(v => !v)}
|
||||
className="text-xs text-muted-foreground hover:text-foreground hover:underline"
|
||||
className="text-xs text-[#848b9b] hover:text-[#e2e5eb] hover:underline"
|
||||
>
|
||||
{showAllReviews ? 'Show less' : `See all ${allTextReviews.length} reviews`}
|
||||
</button>
|
||||
@@ -250,11 +250,11 @@ export function StepDetailModal({ stepId, onClose, onInsert }: StepDetailModalPr
|
||||
</div>
|
||||
<div className="space-y-3">
|
||||
{visibleReviews.map(review => (
|
||||
<div key={review.id} className="rounded-lg border border-border bg-accent/50 p-3">
|
||||
<div key={review.id} className="rounded-lg border border-[#1e2130] bg-accent/50 p-3">
|
||||
<div className="mb-2 flex items-center justify-between">
|
||||
<div className="flex items-center gap-2 text-sm">
|
||||
<User className="h-3.5 w-3.5" />
|
||||
<span className="font-medium text-foreground">{review.user_name || 'Anonymous'}</span>
|
||||
<span className="font-medium text-[#e2e5eb]">{review.user_name || 'Anonymous'}</span>
|
||||
{review.verified_use && (
|
||||
<span className="rounded bg-emerald-400/10 px-1.5 py-0.5 text-xs text-emerald-400">
|
||||
Verified Use
|
||||
@@ -269,14 +269,14 @@ export function StepDetailModal({ stepId, onClose, onInsert }: StepDetailModalPr
|
||||
'h-3 w-3',
|
||||
i <= review.rating
|
||||
? 'fill-yellow-400 text-yellow-400'
|
||||
: 'text-muted-foreground'
|
||||
: 'text-[#848b9b]'
|
||||
)}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-sm text-muted-foreground">{review.review_text}</p>
|
||||
<div className="mt-2 flex items-center gap-2 text-xs text-muted-foreground">
|
||||
<p className="text-sm text-[#848b9b]">{review.review_text}</p>
|
||||
<div className="mt-2 flex items-center gap-2 text-xs text-[#848b9b]">
|
||||
<Calendar className="h-3 w-3" />
|
||||
{new Date(review.created_at).toLocaleDateString()}
|
||||
</div>
|
||||
@@ -287,28 +287,28 @@ export function StepDetailModal({ stepId, onClose, onInsert }: StepDetailModalPr
|
||||
)}
|
||||
|
||||
{/* Metadata */}
|
||||
<div className="rounded-lg border border-border bg-accent/50 p-4">
|
||||
<div className="rounded-lg border border-[#1e2130] bg-accent/50 p-4">
|
||||
<div className="grid grid-cols-2 gap-3 text-sm">
|
||||
<div>
|
||||
<span className="text-muted-foreground">Author:</span>
|
||||
<span className="ml-2 font-medium text-foreground">{step.author_name || 'Unknown'}</span>
|
||||
<span className="text-[#848b9b]">Author:</span>
|
||||
<span className="ml-2 font-medium text-[#e2e5eb]">{step.author_name || 'Unknown'}</span>
|
||||
</div>
|
||||
{step.is_flow_synced && step.source_tree_name && (
|
||||
<div className="col-span-2 flex items-center gap-1.5 text-muted-foreground">
|
||||
<div className="col-span-2 flex items-center gap-1.5 text-[#848b9b]">
|
||||
<GitBranch className="h-3.5 w-3.5 shrink-0" />
|
||||
<span>Sourced from <span className="font-medium text-foreground">{step.source_tree_name}</span></span>
|
||||
<span>Sourced from <span className="font-medium text-[#e2e5eb]">{step.source_tree_name}</span></span>
|
||||
</div>
|
||||
)}
|
||||
<div>
|
||||
<span className="text-muted-foreground">Usage Count:</span>
|
||||
<span className="ml-2 font-medium text-foreground">{step.usage_count}</span>
|
||||
<span className="text-[#848b9b]">Usage Count:</span>
|
||||
<span className="ml-2 font-medium text-[#e2e5eb]">{step.usage_count}</span>
|
||||
</div>
|
||||
<div>
|
||||
<span className="text-muted-foreground">Created:</span>
|
||||
<span className="ml-2 font-medium text-foreground">{new Date(step.created_at).toLocaleDateString()}</span>
|
||||
<span className="text-[#848b9b]">Created:</span>
|
||||
<span className="ml-2 font-medium text-[#e2e5eb]">{new Date(step.created_at).toLocaleDateString()}</span>
|
||||
</div>
|
||||
<div>
|
||||
<span className="text-muted-foreground">Visibility:</span>
|
||||
<span className="text-[#848b9b]">Visibility:</span>
|
||||
<span className="ml-2 font-medium capitalize">{step.visibility}</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -318,7 +318,7 @@ export function StepDetailModal({ stepId, onClose, onInsert }: StepDetailModalPr
|
||||
</div>
|
||||
|
||||
{/* Footer - Actions */}
|
||||
<div className="flex gap-2 border-t border-border p-4">
|
||||
<div className="flex gap-2 border-t border-[#1e2130] p-4">
|
||||
<Button
|
||||
variant="secondary"
|
||||
onClick={onClose}
|
||||
|
||||
@@ -141,7 +141,7 @@ export function StepForm({ onSubmit, onCancel, initialData, submitLabel, isSubmi
|
||||
<form onSubmit={handleSubmit} className="space-y-6">
|
||||
{/* Step Type */}
|
||||
<div>
|
||||
<label className="mb-2 block text-sm font-medium text-foreground">
|
||||
<label className="mb-2 block text-sm font-medium text-[#e2e5eb]">
|
||||
Step Type <span className="text-red-400">*</span>
|
||||
</label>
|
||||
<div className="grid grid-cols-3 gap-2">
|
||||
@@ -155,15 +155,15 @@ export function StepForm({ onSubmit, onCancel, initialData, submitLabel, isSubmi
|
||||
className={cn(
|
||||
'rounded-lg border p-3 text-left transition-colors',
|
||||
stepType === option.value
|
||||
? 'border-border bg-accent ring-2 ring-primary/20'
|
||||
: 'border-border hover:border-border'
|
||||
? 'border-[#1e2130] bg-accent ring-2 ring-primary/20'
|
||||
: 'border-[#1e2130] hover:border-[#1e2130]'
|
||||
)}
|
||||
>
|
||||
<div className="mb-1 flex items-center gap-2">
|
||||
<Icon className="h-4 w-4" />
|
||||
<span className="font-medium text-sm text-foreground">{option.label}</span>
|
||||
<span className="font-medium text-sm text-[#e2e5eb]">{option.label}</span>
|
||||
</div>
|
||||
<p className="text-xs text-muted-foreground">{option.description}</p>
|
||||
<p className="text-xs text-[#848b9b]">{option.description}</p>
|
||||
</button>
|
||||
)
|
||||
})}
|
||||
@@ -172,7 +172,7 @@ export function StepForm({ onSubmit, onCancel, initialData, submitLabel, isSubmi
|
||||
|
||||
{/* Title */}
|
||||
<div>
|
||||
<label htmlFor="title" className="mb-2 block text-sm font-medium text-foreground">
|
||||
<label htmlFor="title" className="mb-2 block text-sm font-medium text-[#e2e5eb]">
|
||||
Title <span className="text-red-400">*</span>
|
||||
</label>
|
||||
<Input
|
||||
@@ -187,9 +187,9 @@ export function StepForm({ onSubmit, onCancel, initialData, submitLabel, isSubmi
|
||||
|
||||
{/* Instructions */}
|
||||
<div>
|
||||
<label htmlFor="instructions" className="mb-2 block text-sm font-medium text-foreground">
|
||||
<label htmlFor="instructions" className="mb-2 block text-sm font-medium text-[#e2e5eb]">
|
||||
Instructions <span className="text-red-400">*</span>
|
||||
<span className="ml-2 text-xs font-normal text-muted-foreground">(Markdown supported)</span>
|
||||
<span className="ml-2 text-xs font-normal text-[#848b9b]">(Markdown supported)</span>
|
||||
</label>
|
||||
<Textarea
|
||||
id="instructions"
|
||||
@@ -203,8 +203,8 @@ export function StepForm({ onSubmit, onCancel, initialData, submitLabel, isSubmi
|
||||
|
||||
{/* Help Text */}
|
||||
<div>
|
||||
<label htmlFor="helpText" className="mb-2 block text-sm font-medium text-foreground">
|
||||
Help Text <span className="text-xs font-normal text-muted-foreground">(Optional)</span>
|
||||
<label htmlFor="helpText" className="mb-2 block text-sm font-medium text-[#e2e5eb]">
|
||||
Help Text <span className="text-xs font-normal text-[#848b9b]">(Optional)</span>
|
||||
</label>
|
||||
<Textarea
|
||||
id="helpText"
|
||||
@@ -218,13 +218,13 @@ export function StepForm({ onSubmit, onCancel, initialData, submitLabel, isSubmi
|
||||
{/* Commands */}
|
||||
<div>
|
||||
<div className="mb-2 flex items-center justify-between">
|
||||
<label className="text-sm font-medium text-foreground">
|
||||
Commands <span className="text-xs font-normal text-muted-foreground">(Optional)</span>
|
||||
<label className="text-sm font-medium text-[#e2e5eb]">
|
||||
Commands <span className="text-xs font-normal text-[#848b9b]">(Optional)</span>
|
||||
</label>
|
||||
<button
|
||||
type="button"
|
||||
onClick={addCommand}
|
||||
className="flex items-center gap-1 rounded-md bg-accent px-2 py-1 text-xs font-medium text-muted-foreground hover:bg-accent hover:text-foreground"
|
||||
className="flex items-center gap-1 rounded-md bg-accent px-2 py-1 text-xs font-medium text-[#848b9b] hover:bg-accent hover:text-[#e2e5eb]"
|
||||
>
|
||||
<Plus className="h-3 w-3" />
|
||||
Add Command
|
||||
@@ -233,13 +233,13 @@ export function StepForm({ onSubmit, onCancel, initialData, submitLabel, isSubmi
|
||||
{commands.length > 0 && (
|
||||
<div className="space-y-3">
|
||||
{commands.map((cmd, index) => (
|
||||
<div key={index} className="rounded-lg border border-border bg-accent/50 p-3">
|
||||
<div key={index} className="rounded-lg border border-[#1e2130] bg-accent/50 p-3">
|
||||
<div className="mb-2 flex items-center justify-between">
|
||||
<span className="text-xs font-medium text-muted-foreground">Command {index + 1}</span>
|
||||
<span className="text-xs font-medium text-[#848b9b]">Command {index + 1}</span>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => removeCommand(index)}
|
||||
className="rounded p-1 text-muted-foreground hover:bg-red-400/10 hover:text-red-400"
|
||||
className="rounded p-1 text-[#848b9b] hover:bg-red-400/10 hover:text-red-400"
|
||||
>
|
||||
<X className="h-3 w-3" />
|
||||
</button>
|
||||
@@ -270,14 +270,14 @@ export function StepForm({ onSubmit, onCancel, initialData, submitLabel, isSubmi
|
||||
|
||||
{/* Category */}
|
||||
<div>
|
||||
<label htmlFor="category" className="mb-2 block text-sm font-medium text-foreground">
|
||||
Category <span className="text-xs font-normal text-muted-foreground">(Optional)</span>
|
||||
<label htmlFor="category" className="mb-2 block text-sm font-medium text-[#e2e5eb]">
|
||||
Category <span className="text-xs font-normal text-[#848b9b]">(Optional)</span>
|
||||
</label>
|
||||
<select
|
||||
id="category"
|
||||
value={categoryId}
|
||||
onChange={(e) => setCategoryId(e.target.value)}
|
||||
className="w-full rounded-md border border-border bg-card px-3 py-2 text-sm text-foreground focus:outline-hidden focus:border-primary focus:ring-1 focus:ring-primary/20"
|
||||
className="w-full rounded-md border border-[#1e2130] bg-[#14161d] px-3 py-2 text-sm text-[#e2e5eb] focus:outline-hidden focus:border-primary focus:ring-1 focus:ring-primary/20"
|
||||
>
|
||||
<option value="">None</option>
|
||||
{categories.map(cat => (
|
||||
@@ -288,8 +288,8 @@ export function StepForm({ onSubmit, onCancel, initialData, submitLabel, isSubmi
|
||||
|
||||
{/* Tags */}
|
||||
<div>
|
||||
<label htmlFor="tagInput" className="mb-2 block text-sm font-medium text-foreground">
|
||||
Tags <span className="text-xs font-normal text-muted-foreground">(Optional)</span>
|
||||
<label htmlFor="tagInput" className="mb-2 block text-sm font-medium text-[#e2e5eb]">
|
||||
Tags <span className="text-xs font-normal text-[#848b9b]">(Optional)</span>
|
||||
</label>
|
||||
<div className="flex gap-2">
|
||||
<Input
|
||||
@@ -304,7 +304,7 @@ export function StepForm({ onSubmit, onCancel, initialData, submitLabel, isSubmi
|
||||
<button
|
||||
type="button"
|
||||
onClick={addTag}
|
||||
className="rounded-md bg-accent px-4 py-2 text-sm font-medium text-muted-foreground hover:bg-accent hover:text-foreground"
|
||||
className="rounded-md bg-accent px-4 py-2 text-sm font-medium text-[#848b9b] hover:bg-accent hover:text-[#e2e5eb]"
|
||||
>
|
||||
Add
|
||||
</button>
|
||||
@@ -314,7 +314,7 @@ export function StepForm({ onSubmit, onCancel, initialData, submitLabel, isSubmi
|
||||
{tags.map(tag => (
|
||||
<span
|
||||
key={tag}
|
||||
className="flex items-center gap-1 rounded-full bg-accent px-2.5 py-1 text-xs text-muted-foreground"
|
||||
className="flex items-center gap-1 rounded-full bg-accent px-2.5 py-1 text-xs text-[#848b9b]"
|
||||
>
|
||||
{tag}
|
||||
<button
|
||||
@@ -333,14 +333,14 @@ export function StepForm({ onSubmit, onCancel, initialData, submitLabel, isSubmi
|
||||
|
||||
{/* Visibility */}
|
||||
<div>
|
||||
<label htmlFor="visibility" className="mb-2 block text-sm font-medium text-foreground">
|
||||
<label htmlFor="visibility" className="mb-2 block text-sm font-medium text-[#e2e5eb]">
|
||||
Visibility
|
||||
</label>
|
||||
<select
|
||||
id="visibility"
|
||||
value={visibility}
|
||||
onChange={(e) => setVisibility(e.target.value as 'private' | 'team' | 'public')}
|
||||
className="w-full rounded-md border border-border bg-card px-3 py-2 text-sm text-foreground focus:outline-hidden focus:border-primary focus:ring-1 focus:ring-primary/20"
|
||||
className="w-full rounded-md border border-[#1e2130] bg-[#14161d] px-3 py-2 text-sm text-[#e2e5eb] focus:outline-hidden focus:border-primary focus:ring-1 focus:ring-primary/20"
|
||||
>
|
||||
<option value="private">Private (only me)</option>
|
||||
<option value="team">Team (my team members)</option>
|
||||
|
||||
@@ -49,17 +49,17 @@ export function StepFormModal({ isOpen, onClose, onSuccess, editingStep }: StepF
|
||||
} : undefined
|
||||
|
||||
return (
|
||||
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/80 backdrop-blur-xs p-4">
|
||||
<div className="relative flex h-[90vh] w-full max-w-2xl flex-col bg-card border border-border rounded-2xl shadow-lg">
|
||||
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/80 p-4">
|
||||
<div className="relative flex h-[90vh] w-full max-w-2xl flex-col bg-[#14161d] border border-[#1e2130] rounded-2xl shadow-lg">
|
||||
{/* Header */}
|
||||
<div className="flex items-center justify-between border-b border-border p-6 pb-4">
|
||||
<h2 className="text-lg font-semibold text-foreground">
|
||||
<div className="flex items-center justify-between border-b border-[#1e2130] p-6 pb-4">
|
||||
<h2 className="text-lg font-semibold text-[#e2e5eb]">
|
||||
{isEditMode ? 'Edit Step' : 'Create Step'}
|
||||
</h2>
|
||||
<button
|
||||
onClick={onClose}
|
||||
disabled={isSubmitting}
|
||||
className="rounded-md p-1.5 text-muted-foreground hover:bg-accent hover:text-foreground disabled:opacity-50"
|
||||
className="rounded-md p-1.5 text-[#848b9b] hover:bg-accent hover:text-[#e2e5eb] disabled:opacity-50"
|
||||
aria-label="Close"
|
||||
>
|
||||
<X className="h-5 w-5" />
|
||||
|
||||
@@ -145,16 +145,16 @@ export function StepLibraryBrowser({ onInsert, onCreateNew, showCreateButton = f
|
||||
return (
|
||||
<div className="flex h-full flex-col">
|
||||
{/* Header - Filters */}
|
||||
<div className="space-y-4 border-b border-border p-4">
|
||||
<div className="space-y-4 border-b border-[#1e2130] p-4">
|
||||
{/* Search */}
|
||||
<div className="relative">
|
||||
<Search className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
|
||||
<Search className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-[#848b9b]" />
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Search steps..."
|
||||
value={searchQuery}
|
||||
onChange={(e) => setSearchQuery(e.target.value)}
|
||||
className="w-full rounded-md border border-border bg-card py-2 pl-10 pr-4 text-sm text-foreground placeholder:text-muted-foreground focus:outline-hidden focus:border-primary focus:ring-1 focus:ring-primary/20"
|
||||
className="w-full rounded-md border border-[#1e2130] bg-[#14161d] py-2 pl-10 pr-4 text-sm text-[#e2e5eb] placeholder:text-[#848b9b] focus:outline-hidden focus:border-primary focus:ring-1 focus:ring-primary/20"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -165,7 +165,7 @@ export function StepLibraryBrowser({ onInsert, onCreateNew, showCreateButton = f
|
||||
aria-label="Filter by category"
|
||||
value={selectedCategoryId || ''}
|
||||
onChange={(e) => setSelectedCategoryId(e.target.value || undefined)}
|
||||
className="rounded-md border border-border bg-card px-3 py-2 text-sm text-foreground focus:outline-hidden focus:border-primary focus:ring-1 focus:ring-primary/20"
|
||||
className="rounded-md border border-[#1e2130] bg-[#14161d] px-3 py-2 text-sm text-[#e2e5eb] focus:outline-hidden focus:border-primary focus:ring-1 focus:ring-primary/20"
|
||||
>
|
||||
<option value="">All Categories</option>
|
||||
{categories.map(cat => (
|
||||
@@ -178,7 +178,7 @@ export function StepLibraryBrowser({ onInsert, onCreateNew, showCreateButton = f
|
||||
aria-label="Filter by step type"
|
||||
value={selectedStepType || ''}
|
||||
onChange={(e) => setSelectedStepType((e.target.value as 'decision' | 'action' | 'solution') || undefined)}
|
||||
className="rounded-md border border-border bg-card px-3 py-2 text-sm text-foreground focus:outline-hidden focus:border-primary focus:ring-1 focus:ring-primary/20"
|
||||
className="rounded-md border border-[#1e2130] bg-[#14161d] px-3 py-2 text-sm text-[#e2e5eb] focus:outline-hidden focus:border-primary focus:ring-1 focus:ring-primary/20"
|
||||
>
|
||||
<option value="">All Types</option>
|
||||
<option value="decision">Decision</option>
|
||||
@@ -191,7 +191,7 @@ export function StepLibraryBrowser({ onInsert, onCreateNew, showCreateButton = f
|
||||
aria-label="Filter by minimum rating"
|
||||
value={minRating?.toString() || ''}
|
||||
onChange={(e) => setMinRating(e.target.value ? Number(e.target.value) : undefined)}
|
||||
className="rounded-md border border-border bg-card px-3 py-2 text-sm text-foreground focus:outline-hidden focus:border-primary focus:ring-1 focus:ring-primary/20"
|
||||
className="rounded-md border border-[#1e2130] bg-[#14161d] px-3 py-2 text-sm text-[#e2e5eb] focus:outline-hidden focus:border-primary focus:ring-1 focus:ring-primary/20"
|
||||
>
|
||||
<option value="">Any Rating</option>
|
||||
<option value="4">4+ Stars</option>
|
||||
@@ -204,7 +204,7 @@ export function StepLibraryBrowser({ onInsert, onCreateNew, showCreateButton = f
|
||||
aria-label="Sort steps by"
|
||||
value={sortBy}
|
||||
onChange={(e) => setSortBy(e.target.value as 'recent' | 'popular' | 'highest_rated' | 'most_used')}
|
||||
className="rounded-md border border-border bg-card px-3 py-2 text-sm text-foreground focus:outline-hidden focus:border-primary focus:ring-1 focus:ring-primary/20"
|
||||
className="rounded-md border border-[#1e2130] bg-[#14161d] px-3 py-2 text-sm text-[#e2e5eb] focus:outline-hidden focus:border-primary focus:ring-1 focus:ring-primary/20"
|
||||
>
|
||||
<option value="recent">Most Recent</option>
|
||||
<option value="popular">Most Popular</option>
|
||||
@@ -216,7 +216,7 @@ export function StepLibraryBrowser({ onInsert, onCreateNew, showCreateButton = f
|
||||
{/* Popular Tags */}
|
||||
{popularTags.length > 0 && (
|
||||
<div>
|
||||
<div className="mb-2 text-xs font-medium text-muted-foreground">Popular Tags:</div>
|
||||
<div className="mb-2 text-xs font-medium text-[#848b9b]">Popular Tags:</div>
|
||||
<div className="flex flex-wrap gap-1.5">
|
||||
{popularTags.map(tag => (
|
||||
<button
|
||||
@@ -225,8 +225,8 @@ export function StepLibraryBrowser({ onInsert, onCreateNew, showCreateButton = f
|
||||
className={cn(
|
||||
'rounded-full px-2.5 py-1 text-xs transition-colors',
|
||||
selectedTag === tag.tag
|
||||
? 'bg-gradient-brand text-white shadow-lg shadow-primary/20'
|
||||
: 'bg-accent text-muted-foreground hover:bg-accent'
|
||||
? 'bg-[#22d3ee] text-white'
|
||||
: 'bg-accent text-[#848b9b] hover:bg-accent'
|
||||
)}
|
||||
>
|
||||
{tag.tag} ({tag.count})
|
||||
@@ -240,7 +240,7 @@ export function StepLibraryBrowser({ onInsert, onCreateNew, showCreateButton = f
|
||||
{hasActiveFilters && (
|
||||
<button
|
||||
onClick={clearFilters}
|
||||
className="text-sm text-muted-foreground hover:text-foreground hover:underline"
|
||||
className="text-sm text-[#848b9b] hover:text-[#e2e5eb] hover:underline"
|
||||
>
|
||||
Clear all filters
|
||||
</button>
|
||||
@@ -251,7 +251,7 @@ export function StepLibraryBrowser({ onInsert, onCreateNew, showCreateButton = f
|
||||
<div className="flex-1 overflow-y-auto p-4">
|
||||
{isLoading ? (
|
||||
<div className="flex items-center justify-center py-12">
|
||||
<Loader2 className="h-8 w-8 animate-spin text-muted-foreground" />
|
||||
<Loader2 className="h-8 w-8 animate-spin text-[#848b9b]" />
|
||||
</div>
|
||||
) : error ? (
|
||||
<div className="rounded-lg border border-red-400/20 bg-red-400/10 p-4 text-center">
|
||||
@@ -262,9 +262,9 @@ export function StepLibraryBrowser({ onInsert, onCreateNew, showCreateButton = f
|
||||
</div>
|
||||
) : steps.length === 0 ? (
|
||||
hasActiveFilters ? (
|
||||
<div className="rounded-lg border border-border bg-accent/50 p-12 text-center">
|
||||
<p className="mb-2 text-lg font-medium text-foreground">No steps found</p>
|
||||
<p className="text-sm text-muted-foreground">Try adjusting your filters</p>
|
||||
<div className="rounded-lg border border-[#1e2130] bg-accent/50 p-12 text-center">
|
||||
<p className="mb-2 text-lg font-medium text-[#e2e5eb]">No steps found</p>
|
||||
<p className="text-sm text-[#848b9b]">Try adjusting your filters</p>
|
||||
</div>
|
||||
) : (
|
||||
<EmptyState
|
||||
@@ -288,7 +288,7 @@ export function StepLibraryBrowser({ onInsert, onCreateNew, showCreateButton = f
|
||||
onClick={() => toggleSection('private')}
|
||||
className="mb-3 flex w-full items-center justify-between"
|
||||
>
|
||||
<h3 className="text-sm font-semibold text-foreground">My Steps ({groupedSteps.private.length})</h3>
|
||||
<h3 className="text-sm font-semibold text-[#e2e5eb]">My Steps ({groupedSteps.private.length})</h3>
|
||||
{collapsedSections.private ? (
|
||||
<ChevronDown className="h-4 w-4" />
|
||||
) : (
|
||||
@@ -321,7 +321,7 @@ export function StepLibraryBrowser({ onInsert, onCreateNew, showCreateButton = f
|
||||
onClick={() => toggleSection('team')}
|
||||
className="mb-3 flex w-full items-center justify-between"
|
||||
>
|
||||
<h3 className="text-sm font-semibold text-foreground">Team Steps ({groupedSteps.team.length})</h3>
|
||||
<h3 className="text-sm font-semibold text-[#e2e5eb]">Team Steps ({groupedSteps.team.length})</h3>
|
||||
{collapsedSections.team ? (
|
||||
<ChevronDown className="h-4 w-4" />
|
||||
) : (
|
||||
@@ -354,7 +354,7 @@ export function StepLibraryBrowser({ onInsert, onCreateNew, showCreateButton = f
|
||||
onClick={() => toggleSection('public')}
|
||||
className="mb-3 flex w-full items-center justify-between"
|
||||
>
|
||||
<h3 className="text-sm font-semibold text-foreground">Community ({groupedSteps.public.length})</h3>
|
||||
<h3 className="text-sm font-semibold text-[#e2e5eb]">Community ({groupedSteps.public.length})</h3>
|
||||
{collapsedSections.public ? (
|
||||
<ChevronDown className="h-4 w-4" />
|
||||
) : (
|
||||
@@ -385,7 +385,7 @@ export function StepLibraryBrowser({ onInsert, onCreateNew, showCreateButton = f
|
||||
|
||||
{/* Footer - Optional Create Button */}
|
||||
{showCreateButton && onCreateNew && (
|
||||
<div className="border-t border-border p-4">
|
||||
<div className="border-t border-[#1e2130] p-4">
|
||||
<Button onClick={onCreateNew} className="w-full">
|
||||
+ Create New Step
|
||||
</Button>
|
||||
|
||||
Reference in New Issue
Block a user