refactor: Extract reusable UI components and add TDD documentation

- Add comprehensive TDD documentation to CLAUDE.md with coverage requirements and examples
- Extract reusable UI components to frontend/src/components/ui/ (Modal, FormInput, Button, Alert, etc.)
- Add shared constants (schedulePresets) and utility hooks (useCrudMutation, useFormValidation)
- Update frontend/CLAUDE.md with component documentation and usage examples
- Refactor CreateTaskModal to use shared components and constants
- Fix test assertions to be more robust and accurate across all test files

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
poduck
2025-12-10 15:27:27 -05:00
parent 18c9a69d75
commit 8c52d6a275
48 changed files with 2780 additions and 444 deletions

View File

@@ -139,7 +139,7 @@ describe('CodeBlock', () => {
expect(checkIcon).toBeInTheDocument();
});
it('reverts to copy icon after 2 seconds', () => {
it('reverts to copy icon after 2 seconds', async () => {
const code = 'test code';
mockWriteText.mockResolvedValue(undefined);
@@ -148,14 +148,18 @@ describe('CodeBlock', () => {
const copyButton = screen.getByRole('button', { name: /copy code/i });
// Click to copy
fireEvent.click(copyButton);
await act(async () => {
fireEvent.click(copyButton);
});
// Should show Check icon
let checkIcon = container.querySelector('.text-green-400');
expect(checkIcon).toBeInTheDocument();
// Fast-forward 2 seconds using act to wrap state updates
vi.advanceTimersByTime(2000);
await act(async () => {
vi.advanceTimersByTime(2000);
});
// Should revert to Copy icon (check icon should be gone)
checkIcon = container.querySelector('.text-green-400');

View File

@@ -435,7 +435,9 @@ describe('Navbar', () => {
});
it('should close mobile menu on route change', () => {
// Test that mobile menu state resets when component receives new location
// Test that clicking a navigation link closes the mobile menu
// In production, clicking a link triggers a route change which closes the menu via useEffect
// In tests with MemoryRouter, the route change happens and the useEffect fires
render(<Navbar darkMode={false} toggleTheme={mockToggleTheme} />, {
wrapper: createWrapper('/'),
});
@@ -447,14 +449,12 @@ describe('Navbar', () => {
let mobileMenuContainer = menuButton.closest('nav')?.querySelector('.lg\\:hidden.overflow-hidden');
expect(mobileMenuContainer).toHaveClass('max-h-96');
// Click a navigation link (simulates route change behavior)
// Click a navigation link - this triggers navigation to /features
// The useEffect with location.pathname dependency should close the menu
const featuresLink = screen.getAllByRole('link', { name: 'Features' })[1]; // Mobile menu link
fireEvent.click(featuresLink);
// The useEffect with location.pathname dependency should close the menu
// In actual usage, clicking a link triggers navigation which changes location.pathname
// For this test, we verify the menu can be manually closed
fireEvent.click(menuButton);
// After navigation, menu should be closed
mobileMenuContainer = menuButton.closest('nav')?.querySelector('.lg\\:hidden.overflow-hidden');
expect(mobileMenuContainer).toHaveClass('max-h-0');
});