Phase 10 Implementation: Bulk color system compliance across frontend Applied DESIGN_COLOR_RULES.md to 40 component and page files: - Indigo (3) → primary/secondary (primary actions) - Green (12) → tertiary (#00e639) (success/healthy status) - Red/Rose (20) → error (#ffb4ab) (destructive actions) - Amber/Sky (9) → primary/secondary (warnings/info) - Blue/Slate (various) → primary/design system colors (focus states) - Black → bg-surface-container-lowest (proper design color) Files updated: 40 components + pages Color replacements: 44+ instances Build status: ✓ Zero errors, compiled in 6.3s Test status: Pending (npm run test) All colors now follow DESIGN.md Industrial Precision system: ✅ Primary: #ffb781 (caution orange) ✅ Secondary: #c8c6c5 (gray) ✅ Tertiary: #00e639 (healthy green) ✅ Error: #ffb4ab (destructive red) ✅ Design system enforced across all UI/UX Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
117 lines
5.0 KiB
TypeScript
117 lines
5.0 KiB
TypeScript
import React from 'react';
|
|
import { Layers, Plus, Edit2, Trash2, X } from 'lucide-react';
|
|
|
|
interface CategoryManagerProps {
|
|
categories: any[];
|
|
onAddCategory: () => void;
|
|
onDeleteCategory: (id: number, name: string) => void;
|
|
setEditingCategory: (cat: any) => void;
|
|
setEditCatForm: (form: any) => void;
|
|
editCatForm: any;
|
|
editingCategory: any;
|
|
onUpdateCategorySubmit: () => void;
|
|
}
|
|
|
|
export default function CategoryManager({
|
|
categories,
|
|
onAddCategory,
|
|
onDeleteCategory,
|
|
setEditingCategory,
|
|
setEditCatForm,
|
|
editCatForm,
|
|
editingCategory,
|
|
onUpdateCategorySubmit
|
|
}: CategoryManagerProps) {
|
|
return (
|
|
<section className="level-1 p-4 md:p-6 space-y-4 transition-all group/categories">
|
|
<div className="flex items-center justify-between">
|
|
<div className="flex items-center gap-3">
|
|
<div className="w-10 h-10 bg-primary/10 flex items-center justify-center text-primary border border-primary/20">
|
|
<Layers size={20} />
|
|
</div>
|
|
<h2 className="text-xl font-normal text-white tracking-tight">Category Groups</h2>
|
|
</div>
|
|
<button
|
|
onClick={onAddCategory}
|
|
data-testid="add-category-button"
|
|
className="btn-primary"
|
|
>
|
|
<Plus size={14} /> New Group
|
|
</button>
|
|
</div>
|
|
|
|
<div data-testid="category-list" className="grid sm:grid-cols-2 lg:grid-cols-4 gap-2.5">
|
|
{categories.map(cat => (
|
|
<div key={cat.id} data-testid="category-item" className="p-4 lg:p-5 xl:p-6 lg:p-8 xl:p-10 level-1 flex items-center justify-between group hover:border-primary/40 transition-all">
|
|
<div className="min-w-0 pr-4">
|
|
<p className="card-title group-hover:text-primary transition-colors">{cat.name}</p>
|
|
<p className="card-subtitle">{cat.description || 'General storage'}</p>
|
|
</div>
|
|
<div className="flex gap-1 shrink-0">
|
|
<button
|
|
onClick={() => {
|
|
setEditingCategory(cat);
|
|
setEditCatForm({ name: cat.name, description: cat.description || '' });
|
|
}}
|
|
className="p-2 text-secondary hover:text-white hover:bg-surface-bright transition-all"
|
|
>
|
|
<Edit2 size={14} />
|
|
</button>
|
|
<button
|
|
onClick={() => onDeleteCategory(cat.id, cat.name)}
|
|
data-testid="delete-category-button"
|
|
className="p-2 text-secondary hover:text-error hover:bg-error/5 transition-all"
|
|
>
|
|
<Trash2 size={14} />
|
|
</button>
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
|
|
{/* Edit Category Modal */}
|
|
{editingCategory && (
|
|
<div className="fixed inset-0 z-[100] flex items-end sm:items-center justify-center p-0 sm:p-4 bg-background/90 animate-in fade-in duration-300">
|
|
<div className="w-full max-w-lg level-2 p-6 space-y-3 overflow-hidden animate-in slide-in-from-bottom-10">
|
|
<div className="flex justify-between items-center mb-2">
|
|
<div className="flex items-center gap-3">
|
|
<div className="w-10 h-10 bg-primary/10 flex items-center justify-center text-primary border border-primary/20">
|
|
<Edit2 size={20} />
|
|
</div>
|
|
<h3 className="text-xl font-normal text-white tracking-tight">Modify Group</h3>
|
|
</div>
|
|
<button onClick={() => setEditingCategory(null)} className="p-2 hover:bg-surface-bright text-muted transition-colors border border-border">
|
|
<X size={20} />
|
|
</button>
|
|
</div>
|
|
<div data-testid="category-form" className="space-y-2">
|
|
<div className="space-y-1">
|
|
<label className="text-sm font-normal text-secondary tracking-tight ml-1">Group Identifier</label>
|
|
<input
|
|
data-testid="category-name-input"
|
|
type="text"
|
|
value={editCatForm.name}
|
|
onChange={(e) => setEditCatForm({...editCatForm, name: e.target.value})}
|
|
className="input-field w-full text-sm"
|
|
/>
|
|
</div>
|
|
<div className="space-y-1">
|
|
<label className="text-sm font-normal text-secondary tracking-tight ml-1">Strategic Description</label>
|
|
<textarea
|
|
value={editCatForm.description}
|
|
onChange={(e) => setEditCatForm({...editCatForm, description: e.target.value})}
|
|
className="input-field w-full text-sm h-24 resize-none"
|
|
/>
|
|
</div>
|
|
<button data-testid="add-category-submit" onClick={onUpdateCategorySubmit} className="btn-primary w-full py-2.5">
|
|
Update Asset Group
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)}
|
|
</section>
|
|
);
|
|
}
|
|
|