mirror of
https://github.com/soconnor0919/beenvoice.git
synced 2025-12-13 17:44:44 -05:00
component - Create custom NumberInput component with increment/decrement buttons - Add 0.25 step increments for hours and rates in invoice forms - Implement emerald-themed styling with hover states and accessibility - Add keyboard navigation (arrow keys) and proper ARIA support - Condense invoice editor tax/totals section into efficient grid layout - Update client dropdown to single-line format (name + email) - Add fixed footer with floating action bar pattern matching business forms - Redesign invoice viewer with better space utilization and visual hierarchy - Maintain professional appearance and consistent design system - Fix Next.js 15 params Promise handling across all invoice pages - Resolve TypeScript compilation errors and type-only imports
198 lines
5.6 KiB
Markdown
198 lines
5.6 KiB
Markdown
# Dynamic Breadcrumbs Guide
|
|
|
|
## Overview
|
|
|
|
The breadcrumb system in beenvoice automatically generates navigation trails based on the current URL path. It features intelligent pluralization, proper capitalization, and dynamic resource name fetching.
|
|
|
|
## Key Features
|
|
|
|
### 1. Automatic Pluralization
|
|
|
|
The breadcrumb system intelligently handles singular and plural forms:
|
|
|
|
- **List pages** (e.g., `/dashboard/businesses`) → "Businesses"
|
|
- **Detail pages** (e.g., `/dashboard/businesses/[id]`) → "Business"
|
|
- **New pages** (e.g., `/dashboard/businesses/new`) → "Business" (singular context)
|
|
|
|
### 2. Smart Capitalization
|
|
|
|
All route segments are automatically capitalized:
|
|
- `businesses` → "Businesses"
|
|
- `clients` → "Clients"
|
|
- `invoices` → "Invoices"
|
|
|
|
### 3. Dynamic Resource Names
|
|
|
|
Instead of showing UUIDs, breadcrumbs fetch and display actual resource names:
|
|
- `/dashboard/clients/123e4567-e89b-12d3-a456-426614174000` → "Dashboard / Clients / John Doe"
|
|
- `/dashboard/invoices/987fcdeb-51a2-43f1-b321-123456789abc` → "Dashboard / Invoices / INV-2024-001"
|
|
|
|
### 4. Context-Aware Labels
|
|
|
|
Special pages are handled intelligently:
|
|
- **Edit pages**: Show the resource name instead of "Edit" as the last breadcrumb
|
|
- **New pages**: Show "New" as the last breadcrumb
|
|
- **Import/Export pages**: Show appropriate action labels
|
|
|
|
## Implementation Details
|
|
|
|
### Pluralization Rules
|
|
|
|
The system uses a comprehensive pluralization utility (`src/lib/pluralize.ts`) that handles:
|
|
|
|
```typescript
|
|
// Common business terms
|
|
business → businesses
|
|
client → clients
|
|
invoice → invoices
|
|
category → categories
|
|
company → companies
|
|
|
|
// General rules
|
|
- Words ending in 's', 'ss', 'sh', 'ch', 'x', 'z' → add 'es'
|
|
- Words ending in consonant + 'y' → change to 'ies'
|
|
- Words ending in 'f' or 'fe' → change to 'ves'
|
|
- Default → add 's'
|
|
```
|
|
|
|
### Resource Fetching
|
|
|
|
The breadcrumbs automatically detect resource IDs and fetch the appropriate data:
|
|
|
|
```typescript
|
|
// Detects UUID patterns in the URL
|
|
const isUUID = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/
|
|
|
|
// Fetches data based on resource type
|
|
- Clients: Shows client name
|
|
- Invoices: Shows invoice number or formatted date
|
|
- Businesses: Shows business name
|
|
```
|
|
|
|
### Loading States
|
|
|
|
While fetching resource data, breadcrumbs show loading skeletons:
|
|
```tsx
|
|
<Skeleton className="inline-block h-5 w-24 align-middle" />
|
|
```
|
|
|
|
## Usage Examples
|
|
|
|
### Basic List Page
|
|
**URL**: `/dashboard/clients`
|
|
**Breadcrumbs**: Dashboard / Clients
|
|
|
|
### Resource Detail Page
|
|
**URL**: `/dashboard/clients/550e8400-e29b-41d4-a716-446655440000`
|
|
**Breadcrumbs**: Dashboard / Clients / Jane Smith
|
|
|
|
### Resource Edit Page
|
|
**URL**: `/dashboard/businesses/550e8400-e29b-41d4-a716-446655440000/edit`
|
|
**Breadcrumbs**: Dashboard / Businesses / Acme Corp
|
|
*(Note: "Edit" is hidden when showing the resource name)*
|
|
|
|
### New Resource Page
|
|
**URL**: `/dashboard/invoices/new`
|
|
**Breadcrumbs**: Dashboard / Invoices / New
|
|
|
|
### Nested Resources
|
|
**URL**: `/dashboard/clients/550e8400-e29b-41d4-a716-446655440000/invoices`
|
|
**Breadcrumbs**: Dashboard / Clients / John Doe / Invoices
|
|
|
|
## Customization
|
|
|
|
### Adding New Resource Types
|
|
|
|
To add a new resource type, update the pluralization rules:
|
|
|
|
```typescript
|
|
// In src/lib/pluralize.ts
|
|
const PLURALIZATION_RULES = {
|
|
// ... existing rules
|
|
product: { singular: "Product", plural: "Products" },
|
|
service: { singular: "Service", plural: "Services" },
|
|
};
|
|
```
|
|
|
|
### Custom Resource Labels
|
|
|
|
For resources that need custom display logic, add to the breadcrumb component:
|
|
|
|
```typescript
|
|
// For invoices, show invoice number instead of ID
|
|
if (prevSegment === "invoices") {
|
|
label = invoice.invoiceNumber || format(new Date(invoice.issueDate), "MMM dd, yyyy");
|
|
}
|
|
```
|
|
|
|
### Special Segments
|
|
|
|
Add new special segments to the `SPECIAL_SEGMENTS` object:
|
|
|
|
```typescript
|
|
const SPECIAL_SEGMENTS = {
|
|
new: "New",
|
|
edit: "Edit",
|
|
import: "Import",
|
|
export: "Export",
|
|
duplicate: "Duplicate",
|
|
archive: "Archive",
|
|
};
|
|
```
|
|
|
|
## Best Practices
|
|
|
|
1. **Consistent Naming**: Use consistent URL patterns across your app
|
|
- List pages: `/dashboard/[resource]`
|
|
- Detail pages: `/dashboard/[resource]/[id]`
|
|
- Actions: `/dashboard/[resource]/[id]/[action]`
|
|
|
|
2. **Resource Fetching**: Only fetch data when needed
|
|
- Check resource type before enabling queries
|
|
- Use proper loading states
|
|
|
|
3. **Error Handling**: Handle cases where resources don't exist
|
|
- Show fallback text or maintain UUID display
|
|
- Don't break the breadcrumb trail
|
|
|
|
4. **Performance**: Breadcrumb queries are lightweight
|
|
- Only fetch minimal data (id, name)
|
|
- Use React Query caching effectively
|
|
|
|
## API Integration
|
|
|
|
The breadcrumb component integrates with tRPC routers:
|
|
|
|
```typescript
|
|
// Each resource router should have a getById method
|
|
getById: protectedProcedure
|
|
.input(z.object({ id: z.string() }))
|
|
.query(async ({ ctx, input }) => {
|
|
// Return resource with at least id and name/title
|
|
})
|
|
```
|
|
|
|
## Accessibility
|
|
|
|
- Breadcrumbs use semantic HTML with proper ARIA labels
|
|
- Each segment is a link except the current page
|
|
- Proper keyboard navigation support
|
|
- Screen reader friendly with role="navigation"
|
|
|
|
## Responsive Design
|
|
|
|
- Breadcrumbs wrap on smaller screens
|
|
- Font sizes adjust: `text-sm sm:text-base`
|
|
- Separators scale appropriately
|
|
- Loading skeletons match text size
|
|
|
|
## Migration from Static Breadcrumbs
|
|
|
|
If migrating from hardcoded breadcrumbs:
|
|
|
|
1. Remove static breadcrumb definitions
|
|
2. Ensure URLs follow consistent patterns
|
|
3. Add getById methods to resource routers
|
|
4. Update imports to use `DashboardBreadcrumbs`
|
|
|
|
The dynamic system will automatically generate appropriate breadcrumbs based on the URL structure. |