refactor: remove category feature from UI, focus on tags
All checks were successful
Basil CI/CD Pipeline / Shared Package Tests (push) Successful in 1m22s
Basil CI/CD Pipeline / Code Linting (push) Successful in 1m30s
Basil CI/CD Pipeline / Web Tests (push) Successful in 1m37s
Basil CI/CD Pipeline / API Tests (push) Successful in 1m50s
Basil CI/CD Pipeline / Security Scanning (push) Successful in 1m16s
Basil CI/CD Pipeline / Build All Packages (push) Successful in 1m32s
Basil CI/CD Pipeline / E2E Tests (push) Has been skipped
Basil CI/CD Pipeline / Build & Push Docker Images (push) Successful in 5m6s
Basil CI/CD Pipeline / Trigger Deployment (push) Successful in 12s

Removed all category-related UI elements from the web application to simplify recipe organization. Users will now use tags exclusively for categorizing recipes and cookbooks.

Changes:
- Remove category input fields from RecipeForm and UnifiedEditRecipe
- Remove category filters from CookbookDetail
- Remove category auto-add feature from Cookbooks and EditCookbook
- Preserve category data in database for backward compatibility
- Keep API category support for future use or migrations

This change reduces user confusion by having a single organizational method (tags) instead of overlapping categories and tags.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Paul R Kartchner
2026-01-16 17:25:06 -07:00
parent da085b7332
commit c41cb5723f
5 changed files with 2 additions and 291 deletions

View File

@@ -27,8 +27,6 @@ function UnifiedEditRecipe() {
const [cookTime, setCookTime] = useState('');
const [servings, setServings] = useState('');
const [cuisine, setCuisine] = useState('');
const [recipeCategories, setRecipeCategories] = useState<string[]>([]);
const [categoryInput, setCategoryInput] = useState('');
const [recipeTags, setRecipeTags] = useState<string[]>([]);
const [tagInput, setTagInput] = useState('');
const [availableTags, setAvailableTags] = useState<Tag[]>([]);
@@ -92,7 +90,6 @@ function UnifiedEditRecipe() {
setCookTime(loadedRecipe.cookTime?.toString() || '');
setServings(loadedRecipe.servings?.toString() || '');
setCuisine(loadedRecipe.cuisine || '');
setRecipeCategories(loadedRecipe.categories || []);
// Handle tags - API returns array of {tag: {id, name}} objects, we need string[]
const tagNames = (loadedRecipe.tags as any)?.map((t: any) => t.tag?.name || t).filter(Boolean) || [];
@@ -482,7 +479,6 @@ function UnifiedEditRecipe() {
cookTime: cookTime ? parseInt(cookTime) : undefined,
servings: servings ? parseInt(servings) : undefined,
cuisine: cuisine || undefined,
categories: recipeCategories.length > 0 ? recipeCategories : undefined,
tags: recipeTags,
};
@@ -602,33 +598,6 @@ function UnifiedEditRecipe() {
navigate(`/recipes/${id}`);
};
// Category management functions
const handleAddCategory = (categoryName: string) => {
const trimmedCategory = categoryName.trim();
if (!trimmedCategory) return;
if (recipeCategories.includes(trimmedCategory)) {
setCategoryInput('');
return; // Category already exists
}
setRecipeCategories([...recipeCategories, trimmedCategory]);
setCategoryInput('');
setHasChanges(true);
};
const handleRemoveCategory = (categoryToRemove: string) => {
setRecipeCategories(recipeCategories.filter(cat => cat !== categoryToRemove));
setHasChanges(true);
};
const handleCategoryInputKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === 'Enter') {
e.preventDefault();
handleAddCategory(categoryInput);
}
};
// Tag management functions
const handleAddTag = async (tagName: string) => {
const trimmedTag = tagName.trim();
@@ -840,45 +809,6 @@ function UnifiedEditRecipe() {
</div>
{/* Categories */}
<div className="form-group">
<label htmlFor="categories">Categories</label>
<div className="tags-input-container">
<div className="tags-list">
{recipeCategories.map((category) => (
<span key={category} className="tag">
{category}
<button
type="button"
onClick={() => handleRemoveCategory(category)}
className="tag-remove"
title="Remove category"
>
×
</button>
</span>
))}
</div>
<div className="tag-input-row">
<input
type="text"
id="categories"
value={categoryInput}
onChange={(e) => setCategoryInput(e.target.value)}
onKeyDown={handleCategoryInputKeyDown}
placeholder="Add a category and press Enter"
/>
<button
type="button"
onClick={() => handleAddCategory(categoryInput)}
className="btn-add-tag"
>
Add Category
</button>
</div>
</div>
</div>
{/* Tags */}
<div className="form-group">
<label htmlFor="tags">Tags</label>