Category Management
Overview
This skill helps you work with blog category management features. Categories organize blog posts and include automatic slug generation from titles.
Key Files and Components
Category Pages
- •
src/app/admin/categories/page.tsx- Category listing page - •
src/app/admin/categories/create/page.tsx- Create new category page - •
src/app/admin/categories/edit/page.tsx- Edit existing category page - •
src/app/admin/categories/category-form.tsx- Main category form component
Domain & Infrastructure
- •
src/domains/category.ts- Category model and types - •
src/infrastructure/das/categories.das.ts- Category data access service - •
src/models/CreateCategoryModel.ts- Create category model - •
src/models/UpdateCategoryModel.ts- Update category model
GraphQL Integration
- •
src/infrastructure/graphQL/queries/categories/get-categories.ts- Fetch categories - •
src/infrastructure/graphQL/queries/categories/get-blog-category-ids.ts- Fetch category IDs - •
src/infrastructure/graphQL/graphql-client.ts- Apollo client setup
Category Structure
A category includes:
- •id: Unique identifier (GUID)
- •name: Category display name
- •slug: URL-friendly identifier (auto-generated)
- •description: Optional category description
- •rowVersion: For optimistic locking
Slug Generation
The project uses the slugify package for automatic slug generation:
typescript
import slugify from 'slugify';
const slug = slugify(name, {
lower: true,
strict: true,
trim: true
});
Slugs are:
- •Lowercase
- •Hyphen-separated
- •URL-safe (special characters removed)
- •Automatically generated from the name field
API Integration
Categories support both REST and GraphQL:
REST API Endpoints
- •
GET /categories- List all categories - •
GET /categories/:id- Get single category - •
POST /categories- Create new category - •
PUT /categories/:id- Update existing category - •
DELETE /categories/:id- Delete category
GraphQL Queries
- •
GET_CATEGORIES- Fetch all categories with posts - •
GET_BLOG_CATEGORY_IDS- Fetch category IDs for blog post filtering
All API calls require Bearer token authentication.
Common Tasks
Creating a Category
- •User enters category name
- •Slug is auto-generated from name
- •Optional description can be added
- •Submit creates category via REST API
- •Navigate back to category list
Editing a Category
- •Fetch existing category by ID
- •Populate form with current data
- •Allow name, slug, and description edits
- •Include rowVersion for optimistic locking
- •Submit updates category via REST API
- •Navigate back to category list
Listing Categories
- •Fetch categories from REST API or GraphQL
- •Display in table or grid format
- •Show name, slug, and action buttons
- •Support edit and delete operations
Category Selection
When assigning categories to blog posts:
- •Fetch all categories
- •Display in dropdown/select component
- •Store selected categoryId with post
Data Access Patterns
Using REST API
typescript
import { getApiUrl, authenticatedFetch } from '@/config/api.config';
// Fetch categories
const response = await authenticatedFetch(
getApiUrl('/categories'),
token
);
const data = await response.json();
Using GraphQL
typescript
import { graphqlClient } from '@/infrastructure/graphQL/graphql-client';
import { GET_CATEGORIES } from '@/infrastructure/graphQL/queries/categories/get-categories';
const { data } = await graphqlClient.query({
query: GET_CATEGORIES
});
Best Practices
- •Always generate slugs from names automatically
- •Validate uniqueness of slugs before submission
- •Handle rowVersion for update operations
- •Check authentication before API calls
- •Show loading states during data fetching
- •Handle errors gracefully with user feedback
- •Use TypeScript types from domain models
- •Cache category lists where appropriate (Apollo handles this for GraphQL)
TypeScript Types
Always use the domain types:
typescript
import type { CategoryModel } from '@/domains/category';
import type { CreateCategoryModel } from '@/models/CreateCategoryModel';
import type { UpdateCategoryModel } from '@/models/UpdateCategoryModel';
Debugging Tips
If you encounter issues:
- •Verify slug generation is working correctly
- •Check API endpoints are reachable
- •Validate authentication token
- •Review GraphQL query syntax
- •Check Apollo cache for stale data
- •Verify rowVersion matches for updates
- •Test category assignment in blog posts
Integration with Blog Posts
Categories are referenced in blog posts:
- •Blog posts have a
categoryIdfield - •Categories can have multiple posts
- •Use category data for filtering and organization
- •Display category name with blog post metadata
Example Workflow
When implementing category features:
- •Read category domain model
- •Review existing category-form.tsx
- •Check API configuration (REST and GraphQL)
- •Test slug generation
- •Implement changes following patterns
- •Validate with TypeScript
- •Test CRUD operations in dev server