### UnifiedInvoiceTable Configuration Example
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/INVOICE_CONSOLIDATION_GUIDE.md
Demonstrates the flexible configuration options for the UnifiedInvoiceTable component. It showcases settings for variant, virtualization, header visibility, and pagination.
```tsx
```
--------------------------------
### Example File Renaming Migration
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/docs/NAMING_CONVENTIONS.md
Provides a practical example of renaming a TypeScript file according to project conventions and updating the corresponding import statement. This illustrates the process of migrating files while maintaining code integrity.
```bash
# Before
utls/FormatCurrency.ts ❌
# After
utls/formatCurrency.ts ✅
# Update imports in affected files:
- import { formatCurrency } from './utils/FormatCurrency';
+ import { formatCurrency } from './utils/formatCurrency';
```
--------------------------------
### Production Environment Variables Example
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/DEPLOYMENT.md
Example of environment variables for the production build of the Invoice Generator SaaS. These variables are typically defined in a .env.production file.
```env
VITE_APP_NAME=Invoice Generator SaaS
VITE_API_URL=https://api.yourdomain.com
VITE_ENABLE_ANALYTICS=true
```
--------------------------------
### Consolidate Dashboard Analytics useQueries Hooks (TypeScript)
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/docs/useQueries-consolidation-guide.md
Demonstrates consolidating multiple 'useQuery' hooks for dashboard analytics into a single 'useQueries' hook. The 'before' example shows repetitive state management and error handling, while the 'after' example illustrates a cleaner approach with unified states and batch refetching.
```tsx
// ❌ Old pattern - multiple separate useQuery hooks
export function AnalyticsComponent({ selectedPeriod }: { selectedPeriod: string }) {
// Four separate query hooks with repetitive state management
const invoicesQuery = useInvoicesQuery();
const customersQuery = useCustomersQuery();
const productsQuery = useProductsQuery();
const dashboardStatsQuery = useDashboardStatsQuery();
// Repetitive loading state logic
const isLoading = invoicesQuery.isLoading ||
customersQuery.isLoading ||
productsQuery.isLoading ||
dashboardStatsQuery.isLoading;
// Repetitive error handling
const error = invoicesQuery.error ||
customersQuery.error ||
productsQuery.error ||
dashboardStatsQuery.error;
// Manual refetch coordination
const refetch = () => {
invoicesQuery.refetch();
customersQuery.refetch();
productsQuery.refetch();
dashboardStatsQuery.refetch();
};
// Component render logic...
}
```
```tsx
// ✅ New pattern - consolidated useQueries hook
export function AnalyticsComponent({ selectedPeriod }: { selectedPeriod: string }) {
const {
invoices,
customers,
products,
stats,
// Unified states - no repetitive logic needed!
isLoading,
isRefetching,
error,
hasError,
refetch, // Batch refetch automatically handled
queryCount,
successCount,
errorCount,
} = useComprehensiveDataQueries();
// Clean, simple component logic with better UX
if (hasError) {
return ;
}
return (
{/* Much cleaner render logic */}
{/* Access individual query data cleanly */}
);
}
```
--------------------------------
### Consolidate Dashboard useQueries Hooks (TypeScript)
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/docs/useQueries-consolidation-guide.md
Illustrates consolidating multiple dashboard-related 'useQuery' hooks into a single 'useQueries' hook. The 'before' example shows separate queries with manual state coordination, while the 'after' example demonstrates a streamlined approach using a consolidated hook for cleaner code and unified error handling.
```tsx
// ❌ Old pattern - multiple dashboard queries
export function Dashboard() {
const statsQuery = useDashboardStatsQuery();
const chartsQuery = useDashboardChartsQuery();
const activityQuery = useRecentActivityQuery(10);
const upcomingQuery = useUpcomingDueInvoicesQuery(7);
const overdueQuery = useOverdueInvoicesQuery();
// Repetitive state management
const isLoading = statsQuery.isLoading || chartsQuery.isLoading;
const error = statsQuery.error || chartsQuery.error;
const refetch = () => {
statsQuery.refetch();
chartsQuery.refetch();
activityQuery.refetch();
upcomingQuery.refetch();
overdueQuery.refetch();
};
// Complex loading state coordination
if (isLoading) return ;
if (error) return ;
// Component logic...
}
```
```tsx
// ✅ New pattern - consolidated dashboard queries
export function Dashboard() {
const {
stats,
charts,
activity,
upcoming,
overdue,
isLoading,
isRefetching,
error,
hasError,
refetch,
queryCount,
successCount,
} = useCombinedDashboardQueries('30d');
// Clean error handling
if (hasError) {
return ;
}
return (
);
}
```
--------------------------------
### Installing Dependencies (Bash)
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/MIGRATION_GUIDE.md
Shows the command to install necessary dependencies for TanStack Query.
```bash
npm install @tanstack/react-query @tanstack/react-query-devtools
```
--------------------------------
### Clipboard Utility Automated Tests (TypeScript)
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/docs/CLIPBOARD_IMPLEMENTATION.md
Example test cases for the clipboard utility functions using TypeScript. These tests verify the fallback mechanisms, prioritizing the Clipboard API and gracefully degrading to execCommand or a manual interface when necessary.
```typescript
// Example test cases
describe('Clipboard Utils', () => {
it('should prefer Clipboard API when available', async () => {
// Mock navigator.clipboard
const result = await copyToClipboard('test@example.com');
expect(result.method).toBe('clipboard-api');
});
it('should fallback to execCommand when Clipboard API fails', async () => {
// Mock clipboard failure
const result = await copyToClipboard('test@example.com');
expect(result.method).toBe('exec-command');
});
it('should provide manual interface as final fallback', async () => {
// Mock all automated methods failing
const result = await copyToClipboard('test@example.com');
expect(result.method).toBe('textarea-fallback');
expect(result.success).toBe(true);
});
});
```
--------------------------------
### CSS BEM Naming Convention Examples
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/docs/NAMING_CONVENTIONS.md
Demonstrates the correct application of the Block, Element, Modifier (BEM) methodology for CSS class naming. This ensures a structured and scalable approach to styling. Incorrect examples show common deviations from the BEM standard.
```css
✅ Correct:
.invoice-table { }
.invoice-table__header { }
.invoice-table__row { }
.invoice-table__cell { }
.button--primary { }
.button--secondary { }
.card__header--highlighted { }
❌ Incorrect:
.invoiceTable { }
.InvoiceTable { }
.invoice_table { }
.INVOICE-TABLE { }
.buttonPrimary { }
```
--------------------------------
### Create Product Data Render Factories (TypeScript)
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/docs/COMPONENT_DECOUPLING_GUIDE.md
This example demonstrates creating render factories for a 'ProductData' interface in TypeScript. It defines specific renderers for 'price', 'stock', and 'status' fields, including conditional styling for low stock and different status badges.
```typescript
// 1. Define your data interface
interface ProductData extends BaseDataItem {
name: string;
price: number;
category: string;
stock: number;
}
// 2. Create render objects (NOT classes)
export const ProductRenderers = {
price: (price: number, product: ProductData): React.ReactNode => (
${price.toFixed(2)}
),
stock: (stock: number, product: ProductData): React.ReactNode => {
const isLowStock = stock < 10;
return (
{stock} units
);
},
status: (status: ProductData['status'], product: ProductData): React.ReactNode => {
const statusConfig = {
available: { label: 'Available', className: 'bg-green-100 text-green-800' },
out_of_stock: { label: 'Out of Stock', className: 'bg-red-100 text-red-800' },
discontinued: { label: 'Discontinued', className: 'bg-gray-100 text-gray-800' },
};
const config = statusConfig[status];
return {config.label};
},
};
// 3. Create column definition function
export const getProductColumnDefinitions = (): TableColumn[] => {
return [
{
key: 'name',
label: 'Product',
sortable: true,
},
{
key: 'price',
label: 'Price',
sortable: true,
render: ProductRenderers.price,
},
{
key: 'stock',
label: 'Stock',
sortable: true,
render: ProductRenderers.stock,
},
{
key: 'status',
label: 'Status',
sortable: true,
render: ProductRenderers.status,
},
];
};
// 4. Use with the generic table
const columns = getProductColumnDefinitions();
data={products} columns={columns} />
```
--------------------------------
### Configure Development and Production Environments
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/docs/SECURITY.md
Provides environment-specific configuration examples for development and production setups. Defines NODE_ENV, API endpoints, and application URLs. Emphasizes keeping API keys out of client-side code and using hosting platforms for secret management in production.
```bash
# .env.development
NODE_ENV=development
API_BASE_URL=http://localhost:3001
APP_URL=http://localhost:3000
# No API keys in .env files!
```
```bash
# .env.production (server-side only)
NODE_ENV=production
API_BASE_URL=https://api.yourdomain.com
APP_URL=https://yourdomain.com
# API keys managed by hosting platform
# DATABASE_URL=managed-by-hosting-provider
# THIRD_PARTY_API_KEY=managed-by-hosting-provider
```
--------------------------------
### Project Build and Development Commands
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/DEPLOYMENT.md
Common npm commands for managing the Invoice Generator SaaS project, including development server, production builds, local preview, and deployment.
```bash
# Development (with SPA routing support)
npm run dev
# Production build
npm run build
# Preview production build locally
npm run preview
# Deploy to Vercel
npm run deploy
```
--------------------------------
### AWS S3 + CloudFront SPA Routing Setup
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/DEPLOYMENT.md
Instructions for configuring AWS S3 and CloudFront to handle SPA routing. This involves setting up static website hosting on S3 and creating custom error responses in CloudFront to serve index.html for 404 errors.
```text
1. Configure S3 bucket for static website hosting
2. Set error document to `index.html`
3. In CloudFront, create custom error pages:
- HTTP Error Code: 404
- Customize Error Response: Yes
- Response Page Path: `/index.html`
- HTTP Response Code: 200
```
--------------------------------
### Install TanStack Query with yarn
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/DEPENDENCIES.md
Shows how to install TanStack Query and its devtools using yarn. This provides an alternative installation method for projects using yarn as their package manager.
```bash
yarn add @tanstack/react-query
yarn add -D @tanstack/react-query-devtools
```
--------------------------------
### Install TanStack Query with npm
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/DEPENDENCIES.md
Demonstrates installing TanStack Query and its devtools using npm. This ensures the project has access to the necessary query management functionalities and debugging tools.
```bash
npm install @tanstack/react-query
npm install -D @tanstack/react-query-devtools
```
--------------------------------
### Clipboard Fallback Strategy (TypeScript)
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/docs/CLIPBOARD_IMPLEMENTATION.md
Demonstrates the fallback strategy for copying text to the clipboard, starting with the modern Clipboard API, then falling back to the deprecated `execCommand('copy')`, and finally providing a manual copy interface.
```typescript
// 1. Try modern Clipboard API (requires HTTPS and permissions)
await navigator.clipboard.writeText(text);
// 2. Try legacy execCommand (deprecated but widely supported)
document.execCommand('copy');
// 3. Show manual copy interface (always works)
// Creates a textarea with the text selected for user to copy manually
```
--------------------------------
### Complete Example Using Enhanced Query Options
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/QUERY_OPTIONS_MIGRATION_NOTE.md
Demonstrates how to utilize the new and existing query option presets with React Query hooks (useQuery, useMutation). It shows examples for safe, real-time, and critical operations, integrating the presets directly into the query configurations.
```typescript
import { useQuery, useMutation } from '@tanstack/react-query';
import {
SAFE_QUERY_OPTIONS,
REALTIME_QUERY_OPTIONS,
CRITICAL_MUTATION_OPTIONS,
queryKeys
} from '../services/queryClient';
// Safe query for user profile
const { data: profile } = useQuery({
queryKey: queryKeys.user(),
queryFn: fetchUserProfile,
...SAFE_QUERY_OPTIONS,
});
// Real-time query for dashboard stats
const { data: stats } = useQuery({
queryKey: queryKeys.dashboardStats(),
queryFn: fetchDashboardStats,
...REALTIME_QUERY_OPTIONS,
});
// Critical mutation for payment processing
const paymentMutation = useMutation({
mutationFn: processPayment,
...CRITICAL_MUTATION_OPTIONS,
});
```
--------------------------------
### Netlify SPA Routing Configuration (_redirects)
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/DEPLOYMENT.md
Configures Netlify to serve index.html for all routes, enabling SPA client-side routing. This file should be placed in the public directory.
```netlify
/* /index.html 200
```
--------------------------------
### Install TanStack Query with pnpm
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/DEPENDENCIES.md
Illustrates the process of installing TanStack Query and its devtools with pnpm. This caters to projects which utilize pnpm for package management.
```bash
pnpm add @tanstack/react-query
pnpm add -D @tanstack/react-query-devtools
```
--------------------------------
### Create focused renderers (TypeScript)
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/docs/COMPONENT_DECOUPLING_GUIDE.md
Shows the difference between overly complex render factories and focused, single-purpose renderers. Illustrates better architecture for maintainable code.
```typescript
// ❌ Too complex
const createUberRenderer = (config: ComplexConfig): RenderFunction => {
// Too much logic in one renderer
}
// ✅ Better - focused, single-purpose renderers
export const InvoiceRenderers = {
status: (status, row) => { /* focused logic */ },
amount: (amount, row) => { /* focused logic */ }
};
```
--------------------------------
### Dashboard Page Usage Example (TypeScript)
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/docs/PRODUCTS_TAB_DECOMPOSITION.md
Demonstrates how to use the ProductsTab component within a larger application, such as a dashboard page. This example shows the standard import and rendering, highlighting that its integration requires no changes for the end-user.
```typescript
// Standard usage - no changes required
import { ProductsTab } from './components/dashboard/ProductsTab';
function DashboardPage() {
return (
);
}
```
--------------------------------
### Invoice Status Migration - TypeScript
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/docs/ENUM_MIGRATION_GUIDE.md
Migration example showing transformation from error-prone magic strings to type-safe enum usage for invoice status management. The before/after comparison demonstrates autocomplete support, compile-time checking, and consistent status handling with predefined options array.
```typescript
// Before (Magic Strings)
// ❌ Prone to typos and inconsistency
const invoice = {
status: 'paid' // Could be 'payed', 'Paid', 'PAID', etc.
};
if (invoice.status === 'paid') {
// No compile-time checking
}
// No autocomplete support
const statusOptions = ['paid', 'pending', 'overdue', 'draft'];
```
```typescript
// After (Enums)
// ✅ Type-safe and consistent
import { InvoiceStatus, INVOICE_STATUS_OPTIONS } from '../utils/constants';
const invoice = {
status: InvoiceStatus.Paid // Autocomplete and type checking
};
if (invoice.status === InvoiceStatus.Paid) {
// Compile-time type safety
}
// Pre-defined options array
const statusOptions = INVOICE_STATUS_OPTIONS;
```
--------------------------------
### ReactTSX: Table Configuration Example
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/docs/EXPLICIT_ROW_CLICK_PATTERN.md
An example of how to integrate the new ProductInfoCell into a table configuration, using the `render` property to customize cell content.
```tsx
const DEFAULT_COLUMNS: TableColumn[] = [
{
key: 'name',
label: 'Product Name',
visible: true,
sortable: true,
width: 200,
type: 'text',
render: (product, handlers) => (
)
},
// Other columns...
];
```
--------------------------------
### Real-World Example: useInvoiceTable Hook
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/docs/CUSTOM_HOOK_STATE_MANAGEMENT.md
This hook provides a scalable and maintainable pattern for managing complex state and data fetching, similar to `useCustomerTable`. It includes state management for pagination, sorting, and selections, alongside data fetching and business logic for bulk actions, returning relevant data and handlers.
```typescript
// Similar pattern can be applied to invoices
export function useInvoiceTable() {
// State management
const [currentPage, setCurrentPage] = useState(1);
const [sortConfig, setSortConfig] = useState(defaultSort);
const [selectedInvoices, setSelectedInvoices] = useState([]);
// Data fetching
const { data, isLoading } = useInvoicesQuery({
page: currentPage,
sort: sortConfig,
});
// Business logic
const handleBulkAction = useCallback((action: BulkAction) => {
// Bulk action logic
setSelectedInvoices([]); // Clear after action
}, []);
return {
// State
invoices: data?.invoices || [],
selectedInvoices,
isLoading,
// Actions
handleBulkAction,
handleSort,
handlePageChange,
};
}
```
--------------------------------
### TypeScript Import Migration for Export Services
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/docs/DRY_MIGRATION_GUIDE.md
This code demonstrates how to migrate from old direct imports of export services to the new unified structure. It requires TypeScript environment with the new export directory setup. Inputs are the entity types like Customer, outputs are the migrated import statements with same API. No limitations as the API remains unchanged.
```typescript
// OLD
import { CustomerExportService } from '../utils/customerExportUtils';
// NEW
import { CustomerExportService } from '../utils/export/customerExportService';
```
--------------------------------
### TypeScript: Setting Warning Thresholds
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/docs/ENHANCED_DEBUG_LOGGING.md
Explains how to set appropriate warning thresholds for different types of effects. It provides examples for high-frequency, normal, critical, and one-time initialization effects.
```typescript
// High-frequency effects (animations, polling)
{ debugName: 'animation-frame', warningThreshold: 100 }
// Normal business logic
{ debugName: 'data-sync', warningThreshold: 10 }
// Critical or expensive operations
{ debugName: 'payment-processing', warningThreshold: 2 }
// One-time initialization
{ debugName: 'app-init', warningThreshold: 1 }
```
--------------------------------
### Basic Clipboard Usage (TypeScript)
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/docs/CLIPBOARD_IMPLEMENTATION.md
Shows how to use the `copyToClipboard` and `getClipboardResultMessage` functions to copy text and display user feedback via toast notifications.
```typescript
import { copyToClipboard, getClipboardResultMessage } from '../utils/clipboardUtils';
const handleCopy = async (text: string, type: string) => {
const result = await copyToClipboard(text);
const message = getClipboardResultMessage(result, type);
// Show appropriate toast notification
if (message.type === 'success') {
toast.success(message.title, { description: message.description });
} else if (message.type === 'info') {
toast.info(message.title, { description: message.description });
} else {
toast.error(message.title, { description: message.description });
}
};
```
--------------------------------
### Security Headers Configuration
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/DEPLOYMENT.md
A set of recommended security headers to be added to the hosting platform configuration to enhance the security of the Invoice Generator SaaS application.
```text
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Strict-Transport-Security: max-age=31536000; includeSubDomains
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline';
```
--------------------------------
### Define Directory Names
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/docs/NAMING_CONVENTIONS.md
Guidelines for directory naming using camelCase or kebab-case for primary and subdirectories. This ensures consistent folder organization throughout the project structure.
```typescript
✅ Correct:
- components/
- hooks/
- utils/
- types/
- contexts/
- services/
- pages/
❌ Incorrect:
- Components/
- Hooks/
- Utils/
- TYPES/
- contexts_/
```
--------------------------------
### Optimize configuration object usage (TypeScript)
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/docs/COMPONENT_DECOUPLING_GUIDE.md
Illustrates performance optimization by moving configuration objects out of render functions to prevent unnecessary recreations.
```typescript
// ❌ Performance issue - object recreated on every render
const renderer = (status) => {
const statusConfig = { // This object is created 100 times for 100 rows!
draft: { label: 'Draft', className: '...' },
pending: { label: 'Pending', className: '...' }
};
return ...
};
// ✅ Better - define configuration once at module level
const STATUS_CONFIG = {
draft: { label: 'Draft', className: '...' },
pending: { label: 'Pending', className: '...' }
} as const;
const renderer = (status) => {
const config = STATUS_CONFIG[status];
return ...
};
```
--------------------------------
### Apache SPA Routing Configuration (.htaccess)
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/DEPLOYMENT.md
Configures Apache server to serve index.html for SPA routes when a file is not found. This file should be placed in the public directory.
```apache
Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.html [QSA,L]
```
--------------------------------
### Avoid unnecessary factory wrappers (TypeScript)
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/docs/COMPONENT_DECOUPLING_GUIDE.md
Demonstrates how to simplify renderer creation by removing unnecessary factory functions when they don't provide value.
```typescript
// ❌ Unnecessary complexity - factory that doesn't take parameters
const createStatusRenderer = () => {
return (status: InvoiceStatus) => ;
};
// ✅ Better - direct function definition
export const InvoiceRenderers = {
status: (status: InvoiceStatus, row: InvoiceData) => (
)
};
```
--------------------------------
### Nginx SPA Routing Configuration
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/DEPLOYMENT.md
Configures Nginx to serve index.html for SPA routes, ensuring client-side routing works correctly. This configuration should be added to your nginx.conf.
```nginx
location / {
try_files $uri $uri/ /index.html;
}
```
--------------------------------
### TypeScript const assertions (TypeScript)
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/docs/COMPONENT_DECOUPLING_GUIDE.md
Demonstrates the benefits of using TypeScript's 'as const' assertion for configuration objects to ensure proper type inference and immutability.
```typescript
// ✅ Use 'as const' for better type inference and immutability
const CONFIG = {
key: 'value'
} as const;
// ❌ Without 'as const', TypeScript infers mutable types
const CONFIG = {
key: 'value' // TypeScript thinks this could be any string
};
```
--------------------------------
### Client Environment Variables Configuration
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/docs/SERVER_PROXY_EXAMPLE.md
Specifies client-side environment variables that can be safely committed to version control. These typically include base URLs for APIs and application URLs, enabling frontend to communicate with backend services.
```bash
# .env (can be committed, no sensitive data)
VITE_API_BASE_URL=https://yourdomain.com/api
VITE_APP_URL=https://yourdomain.com
VITE_NODE_ENV=production
```
--------------------------------
### Enhanced Testability with Custom Hooks
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/docs/CUSTOM_HOOK_STATE_MANAGEMENT.md
Demonstrates testing the business logic of a custom hook (`useCustomerTable`) in isolation using `renderHook`, contrasting it with separate component presentation testing.
```typescript
// Test business logic in isolation
describe('useCustomerTable', () => {
it('clears selections when page changes', () => {
const { result } = renderHook(() => useCustomerTable());
// Set up initial state
act(() => {
result.current.handleSelectCustomer('customer-1', true);
});
expect(result.current.selectedCustomers).toContain('customer-1');
// Test page change behavior
act(() => {
result.current.handlePageChange(2);
});
expect(result.current.selectedCustomers).toEqual([]);
expect(result.current.currentPage).toBe(2);
});
});
// Test component presentation separately
describe('CustomersTab', () => {
it('renders customer table correctly', () => {
render();
expect(screen.getByRole('table')).toBeInTheDocument();
});
});
```
--------------------------------
### Server Environment Variables Configuration
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/docs/SERVER_PROXY_EXAMPLE.md
Defines essential server-side environment variables for the application, including URLs for logging services, frontend, database connections, and security secrets. These should be managed securely and not committed to version control.
```bash
# .env.local (server-side only, never commit)
LOGGING_SERVICE_URL=https://api.logging-service.com/v1/logs
LOGGING_API_KEY=your-secret-api-key-here
FRONTEND_URL=https://yourdomain.com
NODE_ENV=production
# Database and other sensitive configs
DATABASE_URL=postgresql://...
REDIS_URL=redis://...
JWT_SECRET=your-jwt-secret
```
--------------------------------
### InvoicesTab.tsx Migration to UnifiedInvoiceTable
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/INVOICE_CONSOLIDATION_GUIDE.md
Illustrates the migration of the InvoicesTab component from using multiple table implementations to a single UnifiedInvoiceTable. It shows the simplification of props and the adoption of the unified component.
```tsx
// Before: Multiple table implementations
{
currentView === 'table' ? (
) : (
)
}
// After: Single unified component
{
currentView === 'table' ? (
) : (
)
}
```
--------------------------------
### Vercel SPA Routing Configuration (vercel.json)
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/DEPLOYMENT.md
Configures Vercel to handle SPA routing by rewriting all non-file requests to the index.html. This ensures client-side routing is functional after deployment.
```json
{
"routes": [
{
"src": "/[^.]+",
"dest": "/",
"status": 200
}
]
}
```
--------------------------------
### Initialize Supabase Client and Query Invoices (TypeScript)
Source: https://context7.com/novalauliady/invoicegeneratorai/llms.txt
Sets up the Supabase client using environment variables for URL and anonymous key. Includes an example of querying invoices, joining with customer and invoice item data, and handling potential errors. Requires VITE_SUPABASE_URL and VITE_SUPABASE_ANON_KEY to be set.
```typescript
import {
createClient
} from '@supabase/supabase-js';
const supabaseUrl = import.meta.env.VITE_SUPABASE_URL;
const supabaseAnonKey = import.meta.env.VITE_SUPABASE_ANON_KEY;
if (!supabaseUrl || !supabaseAnonKey) {
throw new Error('Missing Supabase environment variables');
}
export const supabase = createClient(supabaseUrl, supabaseAnonKey);
// Example usage: Query invoices
const { data: invoices, error } = await supabase
.from('invoices')
.select('*, customers(*), invoice_items(*)')
.eq('company_id', companyId)
.order('created_at', {
ascending: false
})
.range(0, 19);
if (error) {
console.error('Error fetching invoices:', error);
throw error;
}
console.log('Retrieved invoices:', invoices);
```
--------------------------------
### React Clipboard Copy Handler (TypeScript)
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/docs/CLIPBOARD_IMPLEMENTATION.md
An example of handling a click event in a React component to copy customer email to the clipboard and display the result using a toast notification.
```typescript
const handleEmailClick = async (e: React.MouseEvent) => {
e.preventDefault();
e.stopPropagation();
const result = await copyToClipboard(customer.email);
const message = getClipboardResultMessage(result, 'Email');
// Handle the result with appropriate user feedback
showToast(message);
};
```
--------------------------------
### Data Validation with Generics (TypeScript)
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/docs/TYPESCRIPT_GENERICS_MIGRATION.md
This example showcases data validation using a generic `validateData` function. It defines validation rules for Invoice objects, ensuring data integrity and preventing errors.
```typescript
import { validateData, ValidationRule } from '../types/generics';
const invoiceValidation: ValidationRule[] = [
{ field: 'customer', required: true, minLength: 2 },
{ field: 'amount', required: true, type: 'number', min: 0 },
{ field: 'status', required: true }
];
const { isValid, errors } = validateData(invoiceData, invoiceValidation);
```
--------------------------------
### Production Deployment Verification Commands
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/SECURITY.md
Essential commands to verify production builds before deployment, including security checks, environment validation, and local preview testing. Ensures builds meet security standards before going live.
```bash
# Run Security Verification
npm run ci:build
# Test Production Build Locally
npm run build:production
npm run preview
```
--------------------------------
### Dashboard Query Hooks Import (TypeScript)
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/QUERY_MIGRATION_GUIDE.md
Illustrates the import statements for TanStack Query hooks specifically designed for fetching dashboard-related data. This includes aggregate data, statistics, and chart information.
```typescript
import {
useDashboardData, // Get comprehensive dashboard data
useDashboardStatsQuery, // Get dashboard statistics
useDashboardChartsQuery // Get dashboard charts data
} from '../hooks/queries/useDashboardQuery';
```
--------------------------------
### Bundle Size Comparison: Custom vs. External Library
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/docs/DEEP_EQUAL_ANALYSIS.md
This bash command output illustrates the difference in minified bundle size between a custom deep equality implementation and the `fast-deep-equal` external library, highlighting the size savings of the custom solution.
```bash
fast-deep-equal: ~2.3KB minified
Our custom implementation: ~0.8KB minified
Difference: +1.5KB
```
--------------------------------
### Custom Column Renderer (TypeScript)
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/docs/TYPESCRIPT_GENERICS_MIGRATION.md
This example demonstrates a custom column renderer for displaying invoice status with different colors based on the status value. It leverages type safety to ensure the 'status' property is correctly typed and handled.
```typescript
const statusColumn: TableColumn = {
key: 'status',
label: 'Status',
render: (status: Invoice['status'], invoice: Invoice) => {
// Both parameters are properly typed
const colorMap = {
pending: 'yellow',
paid: 'green',
overdue: 'red'
};
return (
{status.toUpperCase()}
);
}
};
```
--------------------------------
### Troubleshooting DevTools and Build Issues
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/SECURITY.md
Commands for resolving common development issues including DevTools not loading, security verification failures, and bundle size problems. Helps maintain secure development and production environments.
```bash
# DevTools Not Loading in Development
npm run clean
npm install
npm run dev
# Security Verification Fails
npm run build:production
node scripts/verify-production-build.js
# Bundle Size Issues
npm run build
npx vite-bundle-analyzer dist
```
--------------------------------
### Test Logging Proxy (JavaScript)
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/docs/SERVER_PROXY_EXAMPLE.md
This snippet demonstrates how to test the logging proxy endpoint using JavaScript and a testing framework. It verifies successful log requests and rejects requests without an API key to ensure secure logging.
```javascript
describe('Logging Proxy', () => {
test('should accept valid log requests', async () => {
const response = await request(app)
.post('/api/logs')
.send({
level: 'info',
message: 'Test message',
timestamp: new Date().toISOString()
});
expect(response.status).toBe(200);
expect(response.body.success).toBe(true);
});
test('should reject requests without API key in environment', async () => {
delete process.env.LOGGING_API_KEY;
const response = await request(app)
.post('/api/logs')
.send({
level: 'info',
message: 'Test message'
});
expect(response.status).toBe(500);
});
});
```
--------------------------------
### Testing Custom Table Hooks in Isolation (TypeScript)
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/docs/TABLE_HOOKS_CONSOLIDATION.md
Illustrates how to test custom table hooks independently of the UI. This example uses Jest and React Testing Library's `renderHook` to test filtering and selection logic within the `useCustomerTable` hook.
```typescript
// Test business logic without UI
describe('useCustomerTable', () => {
it('filters customers by search query', () => {
const { result } = renderHook(() => useCustomerTable());
act(() => {
result.current.setLocalSearchQuery('john');
});
expect(result.current.filteredCustomers).toHaveLength(2);
});
it('clears selections when changing pages', () => {
const { result } = renderHook(() => useCustomerTable());
act(() => {
result.current.handleSelectCustomer('customer-1', true);
result.current.handlePageChange(2);
});
expect(result.current.selectedCustomers).toEqual([]);
});
});
```
--------------------------------
### Direct TanStack Query Usage (After Migration)
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/QUERY_MIGRATION_GUIDE.md
Demonstrates the new pattern using TanStack Query directly. It leverages automatic caching, background refetching, and optimistic updates, reducing boilerplate and improving UI responsiveness.
```tsx
// ✅ New Pattern - Direct query usage
import { useInvoicesQuery, useUpdateInvoiceMutation } from '../hooks/queries/useInvoicesQuery';
function InvoicesComponent() {
const {
data: invoicesData,
isLoading,
error,
refetch
} = useInvoicesQuery();
const updateMutation = useUpdateInvoiceMutation();
// Automatic error handling, smart caching, background updates
const invoices = invoicesData?.invoices || [];
const handleUpdate = async (id: string, data: any) => {
await updateMutation.mutateAsync({ id, data });
// Cache automatically updated, UI stays in sync
};
if (error) return
Error: {error.message}
;
if (isLoading) return
Loading...
;
return ;
}
```
--------------------------------
### Product Query and Mutation Hooks Import (TypeScript)
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/QUERY_MIGRATION_GUIDE.md
Shows the import statement for TanStack Query hooks related to product management. It covers fetching product data and performing mutations for creation, updates, and deletions.
```typescript
import {
useProductsQuery, // Get paginated products
useProductQuery, // Get single product by ID
useCreateProductMutation, // Create new product
useUpdateProductMutation, // Update existing product
useDeleteProductMutation // Delete product
} from '../hooks/queries/useProductsQuery';
```
--------------------------------
### Analytics Period Migration - TypeScript
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/docs/ENUM_MIGRATION_GUIDE.md
Migration example demonstrating the transition from inconsistent string parameters to type-safe enum usage for analytics time periods. The enum approach provides exhaustive switch statement checking, consistent API usage, and eliminates string-based errors.
```typescript
// Before (Magic Strings)
// ❌ Magic strings scattered throughout
const calculateAnalytics = (period: string) => {
switch (period) {
case '7days':
case '30days':
case '3months':
// Implementation
break;
default:
// Easy to miss cases
}
};
// Used inconsistently
fetchAnalytics('7days');
fetchAnalytics('7Days'); // Different casing
fetchAnalytics('week'); // Different format
```
```typescript
// After (Enums)
// ✅ Type-safe and exhaustive
import { AnalyticsPeriod, EnumUtils } from '../utils/constants';
const calculateAnalytics = (period: AnalyticsPeriod) => {
switch (period) {
case AnalyticsPeriod.SevenDays:
case AnalyticsPeriod.ThirtyDays:
case AnalyticsPeriod.ThreeMonths:
// Implementation
break;
default:
// TypeScript ensures exhaustiveness
const exhaustive: never = period;
throw new Error(`Unhandled period: ${exhaustive}`);
}
};
// Consistent usage
fetchAnalytics(AnalyticsPeriod.SevenDays);
```
--------------------------------
### Naming Conventions for Custom Hooks in TypeScript
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/docs/CUSTOM_HOOK_STATE_MANAGEMENT.md
Provides examples of descriptive naming for custom hooks to indicate specific functionality. No runtime dependencies, purely for code organization. Inputs are hook purposes; outputs are suggested names. Limitation: Enforcing conventions requires team discipline.
```typescript
// ✅ Good: Descriptive and specific
useCustomerTable() // For customer table logic
useInvoiceForm() // For invoice form logic
useShoppingCart() // For cart state management
// ❌ Bad: Too generic or unclear
useData() // What kind of data?
useStuff() // Too vague
useCustomer() // Unclear what aspect of customer
```
--------------------------------
### Default configuration constants for table columns and filters
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/docs/TABLE_HOOKS_CONSOLIDATION.md
Smart default values for column configuration and filter states to prevent component prop bloat. Defines required and visible columns with labels. Provides complete default filter setup including status arrays and date ranges.
```TypeScript
const DEFAULT_COLUMN_CONFIG = [
{ id: 'customer', label: 'Customer', visible: true, required: true },
{ id: 'contact', label: 'Contact', visible: true },
];
const DEFAULT_FILTERS = {
status: [],
dateRange: { from: null, to: null },
};
```
--------------------------------
### React Select Component Migration - TypeScript
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/docs/ENUM_MIGRATION_GUIDE.md
Migration example for React Select components showing the transformation from manual string arrays to enum-based solutions with utility functions. The new approach provides type-safe value handling, automatic display label generation, and reduced boilerplate code.
```typescript
// Before
// ❌ Manual string arrays
const statusOptions = ['draft', 'sent', 'pending', 'paid', 'overdue'];
```
```typescript
// After
// ✅ Using enum arrays and utilities
import { INVOICE_STATUS_OPTIONS, EnumUtils, InvoiceStatus } from '../utils/constants';
```
--------------------------------
### Component Props Migration - TypeScript
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/docs/ENUM_MIGRATION_GUIDE.md
Migration example showing the transformation from inline string union types to centralized enum types for component props. This approach eliminates code duplication, provides better type safety, and enables reusable type definitions across multiple components.
```typescript
// Before (String Union Types)
// ❌ Inline union types
interface StatusBadgeProps {
status: 'draft' | 'sent' | 'pending' | 'paid' | 'overdue';
variant?: 'default' | 'outline';
}
// Duplicated across components
interface InvoiceTableProps {
statuses: ('draft' | 'sent' | 'pending' | 'paid' | 'overdue')[];
}
```
```typescript
// After (Enum Types)
// ✅ Centralized enum types
import { InvoiceStatus } from '../utils/constants';
interface StatusBadgeProps {
status: InvoiceStatus;
variant?: 'default' | 'outline';
}
// Reusable across components
interface InvoiceTableProps {
statuses: InvoiceStatus[];
}
```
--------------------------------
### Customer Query and Mutation Hooks Import (TypeScript)
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/QUERY_MIGRATION_GUIDE.md
Demonstrates the import statement for TanStack Query hooks used for managing customer data. This includes fetching lists and individual customers, as well as performing create, update, and delete operations.
```typescript
import {
useCustomersQuery, // Get paginated customers
useCustomerQuery, // Get single customer by ID
useCustomerStatsQuery, // Get customer statistics
useCreateCustomerMutation, // Create new customer
useUpdateCustomerMutation, // Update existing customer
useDeleteCustomerMutation // Delete customer
} from '../hooks/queries/useCustomersQuery';
```
--------------------------------
### CI Build Script with Naming Validation
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/docs/NAMING_CONVENTIONS.md
This command initiates the CI build process, which includes automated validation of naming conventions. Running this script ensures that all code pushed adheres to the project's standards as part of the continuous integration pipeline.
```bash
npm run ci:build # Includes naming convention validation
```
--------------------------------
### TypeScript Generic Migration Step 3: Update Component Usage
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/docs/TYPESCRIPT_GENERICS_MIGRATION.md
Migrating component usage involves replacing raw array types like `any[]` with the specific generic type argument. For example, using `>` ensures that the `data` prop and callbacks receive correctly typed data, enhancing type safety throughout the application.
```typescript
// Replace any[] with proper generic type
data={yourData}
columns={columns}
// All callbacks now receive properly typed data
/>
```
--------------------------------
### Rate Limiting Implementation
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/docs/SERVER_PROXY_EXAMPLE.md
A JavaScript function `checkRateLimit` that implements a basic rate limiting mechanism using a `Map` to track request counts per identifier. It enforces limits over a specified time window to prevent abuse.
```javascript
// Implement rate limiting per user/IP
const userRateLimits = new Map();
function checkRateLimit(identifier, limit = 100, window = 900000) { // 15 minutes
const now = Date.now();
const userRecord = userRateLimits.get(identifier) || { count: 0, resetTime: now + window };
if (now > userRecord.resetTime) {
userRecord.count = 1;
userRecord.resetTime = now + window;
} else {
userRecord.count++;
}
userRateLimits.set(identifier, userRecord);
return userRecord.count <= limit;
}
```
--------------------------------
### Setting Virtualization Options in TSX
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/INVOICE_CONSOLIDATION_GUIDE.md
This TSX example configures virtualization settings for the UnifiedInvoiceTable to handle large datasets efficiently. It uses a JavaScript object to set properties like enabled status, height estimates, and overscan values, improving performance in React applications. Requires a scrollable container and may have limitations with very dynamic content heights.
```tsx
virtualization={{
enabled: true, // Enable/disable virtualization
threshold: 50, // Item count threshold for enabling
estimateRowHeight: 64, // Estimated height per row (pixels)
containerHeight: 500, // Height of scrollable area
overscan: 10, // Extra items to render for smoothness
enableJumpToRow: true, // Show jump-to-row controls
showPerformanceStats: false // Show performance metrics
}}
```
--------------------------------
### Filter Invoice Arrays Using Type-Safe Enum Comparisons in TypeScript
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/docs/ENUM_MIGRATION_GUIDE.md
These examples filter invoice arrays based on status enums, ensuring type safety. They require an array of invoices with enum statuses, taking no additional inputs, and outputting filtered arrays. Limitations include reliance on correct enum typing and no handling for non-array inputs.
```typescript
const paidInvoices = invoices.filter(
invoice => invoice.status === InvoiceStatus.Paid
);
const activeStatuses = [InvoiceStatus.Sent, InvoiceStatus.Pending];
const activeInvoices = invoices.filter(
invoice => activeStatuses.includes(invoice.status)
);
```
--------------------------------
### Basic useQueries Consolidation in TypeScript
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/docs/useQueries-consolidation-guide.md
Demonstrates consolidating multiple independent data fetching queries (e.g., invoices, customers) into a single `useQueries` hook for unified loading and error state management. It returns individual query data along with consolidated states and a unified refetch function. Dependencies include a query client (like TanStack Query).
```tsx
export const useBasicConsolidatedQueries = () => {
const queries = useQueries({
queries: [
{
queryKey: ['invoices'],
queryFn: fetchInvoices,
staleTime: 5 * 60 * 1000,
},
{
queryKey: ['customers'],
queryFn: fetchCustomers,
staleTime: 10 * 60 * 1000,
},
],
});
const [invoicesQuery, customersQuery] = queries;
// Unified state management
const isLoading = queries.some(q => q.isLoading);
const error = queries.find(q => q.error)?.error || null;
const refetch = useCallback(() => {
queries.forEach(q => q.refetch());
}, [queries]);
return {
invoices: {
data: invoicesQuery.data,
isLoading: invoicesQuery.isLoading,
error: invoicesQuery.error,
},
customers: {
data: customersQuery.data,
isLoading: customersQuery.isLoading,
error: customersQuery.error,
},
isLoading,
error,
refetch,
};
};
```
--------------------------------
### TypeScript Adding New Exportable Entity
Source: https://github.com/novalauliady/invoicegeneratorai/blob/main/src/docs/DRY_MIGRATION_GUIDE.md
This example shows how to add a new entity like Invoice to the unified export system. Dependencies include UnifiedExportService and ExportConfig type. Inputs are the entity data array and options, outputs are exported data in specified format. It assumes type safety with generics and proper implementation of getAnalytics function.
```typescript
// 1. Create configuration
export const invoiceExportConfig: ExportConfig = {
entityName: 'Invoice',
entityNamePlural: 'Invoices',
brandColor: '#ABC270',
columns: [...],
getAnalytics: (invoices) => {...},
// ... other config
};
// 2. Create wrapper service
export class InvoiceExportService {
static async exportData(invoices, format, options) {
return UnifiedExportService.exportData(invoices, invoiceExportConfig, format, options);
}
}
```