Files
kanban/frontend/src/auth.tsx
T
egutierrez 7ce227ddea feat(kanban): deadlines en cards (context menu, badges, calendario, history)
- migration 009 + columna deadline TEXT en cards
- backend: CardPatch.HasDeadline, eventos deadline_set/deadline_cleared
- KanbanCard: menu derecho con DatePicker, badge countdown con colores por ratio (azul>=50%, amarillo<50%, rojo<10%, red.9 overdue)
- App.tsx: filtro "Con deadline", handleSetCardDeadline optimista, jump-to-card + highlight
- CalendarView: popover por dia con seq_num + titulo, click navega a card en tablero
- HistoryModal: render eventos deadline_set/deadline_cleared
- .gitignore: *.log

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 03:45:36 +02:00

57 lines
1.7 KiB
TypeScript

import { createContext, ReactNode, useCallback, useContext, useEffect, useState } from "react";
import * as api from "./api";
import { HTTPError } from "./api";
import type { User } from "./types";
interface AuthCtx {
user: User | null;
loading: boolean;
login: (username: string, password: string) => Promise<void>;
register: (username: string, password: string, displayName: string) => Promise<void>;
logout: () => Promise<void>;
setUser: (u: User | null) => void;
}
const Ctx = createContext<AuthCtx | null>(null);
export function AuthProvider({ children }: { children: ReactNode }) {
const [user, setUser] = useState<User | null>(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
api
.getMe()
.then(setUser)
.catch((e) => {
if (!(e instanceof HTTPError) || e.status !== 401) {
console.warn("getMe failed", e);
}
})
.finally(() => setLoading(false));
}, []);
const login = useCallback(async (username: string, password: string) => {
const u = await api.login(username, password);
setUser(u);
}, []);
const register = useCallback(async (username: string, password: string, displayName: string) => {
await api.register(username, password, displayName);
const u = await api.login(username, password);
setUser(u);
}, []);
const logout = useCallback(async () => {
await api.logout();
setUser(null);
}, []);
return <Ctx.Provider value={{ user, loading, login, register, logout, setUser }}>{children}</Ctx.Provider>;
}
export function useAuth(): AuthCtx {
const v = useContext(Ctx);
if (!v) throw new Error("useAuth: missing AuthProvider");
return v;
}