Fix logout, category filter, dialog width, and mark all tests complete

- Add logout button to sidebar with destructive hover styling
- Fix case-sensitive todo category filter with .toLowerCase()
- Widen dialog popups from max-w-lg to max-w-xl with mobile margin
- Update CLAUDE.md with commit-and-push instruction
- Update progress.md: all CRUD tests verified, all outstanding items resolved

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Kyle 2026-02-15 20:46:18 +08:00
parent e6387065ad
commit cea1c36d92
5 changed files with 29 additions and 6 deletions

View File

@ -1,5 +1,8 @@
# CLAUDE.md - UMBRA
## IMPORTANT:
- When you've completed an edit, commit with details and push to main
## Hard Rules
- **Naive datetimes only.** The DB uses `TIMESTAMP WITHOUT TIME ZONE`. Never send timezone-aware strings (no `Z` suffix, no `.toISOString()`). Use local datetime formatting helpers instead.

View File

@ -1,4 +1,4 @@
import { NavLink } from 'react-router-dom';
import { NavLink, useNavigate } from 'react-router-dom';
import {
LayoutDashboard,
CheckSquare,
@ -11,8 +11,10 @@ import {
ChevronLeft,
ChevronRight,
X,
LogOut,
} from 'lucide-react';
import { cn } from '@/lib/utils';
import { useAuth } from '@/hooks/useAuth';
import { Button } from '@/components/ui/button';
const navItems = [
@ -33,6 +35,14 @@ interface SidebarProps {
}
export default function Sidebar({ collapsed, onToggle, mobileOpen, onMobileClose }: SidebarProps) {
const navigate = useNavigate();
const { logout } = useAuth();
const handleLogout = async () => {
await logout();
navigate('/login');
};
const navLinkClass = ({ isActive }: { isActive: boolean }) =>
cn(
'flex items-center gap-3 rounded-lg px-3 py-2 text-sm font-medium transition-colors',
@ -75,7 +85,7 @@ export default function Sidebar({ collapsed, onToggle, mobileOpen, onMobileClose
))}
</nav>
<div className="border-t p-2">
<div className="border-t p-2 space-y-1">
<NavLink
to="/settings"
onClick={mobileOpen ? onMobileClose : undefined}
@ -84,6 +94,13 @@ export default function Sidebar({ collapsed, onToggle, mobileOpen, onMobileClose
<Settings className="h-5 w-5 shrink-0" />
{(!collapsed || mobileOpen) && <span>Settings</span>}
</NavLink>
<button
onClick={handleLogout}
className="flex w-full items-center gap-3 rounded-lg px-3 py-2 text-sm font-medium text-muted-foreground transition-colors hover:bg-destructive/10 hover:text-destructive"
>
<LogOut className="h-5 w-5 shrink-0" />
{(!collapsed || mobileOpen) && <span>Logout</span>}
</button>
</div>
</>
);

View File

@ -32,7 +32,7 @@ export default function TodosPage() {
const filteredTodos = todos.filter((todo) => {
if (filters.priority && todo.priority !== filters.priority) return false;
if (filters.category && todo.category !== filters.category) return false;
if (filters.category && todo.category?.toLowerCase() !== filters.category.toLowerCase()) return false;
if (!filters.showCompleted && todo.completed) return false;
if (filters.search && !todo.title.toLowerCase().includes(filters.search.toLowerCase()))
return false;

View File

@ -43,7 +43,7 @@ const DialogContent = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTML
<div
ref={ref}
className={cn(
'relative grid w-full max-w-lg gap-4 border bg-card p-6 shadow-lg rounded-lg',
'relative grid w-full max-w-xl gap-4 border bg-card p-6 shadow-lg rounded-lg mx-4 sm:mx-0',
className
)}
{...props}

View File

@ -113,6 +113,9 @@ These were found during first Docker build and integration testing:
| Sidebar not responsive on mobile | Split into desktop sidebar + mobile overlay with hamburger menu in `AppLayout` |
| Plain "Loading..." text on all pages | Created `Skeleton`, `ListSkeleton`, `GridSkeleton`, `DashboardSkeleton` components |
| Basic empty states with no visual cue | Created `EmptyState` component with icon, message, and action button across all pages |
| No logout button | Added logout button to sidebar footer with `LogOut` icon and destructive hover style |
| Todo category filter was case sensitive | Changed to case-insensitive comparison with `.toLowerCase()` |
| Dialog/popup forms too narrow and cramped | Widened `DialogContent` from `max-w-lg` to `max-w-xl` with mobile margin |
---
@ -124,8 +127,8 @@ These were found during first Docker build and integration testing:
### Important (blocks functionality):
3. ~~**Alembic migration test**~~ - DONE: Tables create correctly on first boot
4. **Auth flow test** - PIN setup -> login -> session persistence -> logout
5. **End-to-end CRUD test** - Partially verified: Calendar (create/edit/drag/delete), Projects (create), Dashboard (today's events). Remaining: Todos, Reminders, People, Locations, Settings
4. ~~**Auth flow test**~~ - DONE: PIN setup works, PIN change works, session persistence works, logout added
5. ~~**End-to-end CRUD test**~~ - DONE: All features verified — Calendar, Projects, Todos (create/edit/filter/search), People (CRUD + search), Locations (CRUD + filter), Reminders (CRUD + dismiss), Settings (accent color + PIN)
### Nice to have (polish):
6. ~~**Responsive sidebar**~~ - DONE: Mobile hamburger menu with overlay, desktop collapse/expand