chore: auto-commit (28 archivos)

- app.md
- auth.go
- chat.go
- chat.log
- db.go
- frontend/package.json
- frontend/pnpm-lock.yaml
- frontend/src/App.tsx
- frontend/src/Root.tsx
- frontend/src/api.ts
- ...

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-08 00:27:18 +02:00
parent c915e721af
commit bee688e574
28 changed files with 3601 additions and 300 deletions
+55
View File
@@ -0,0 +1,55 @@
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>;
}
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 }}>{children}</Ctx.Provider>;
}
export function useAuth(): AuthCtx {
const v = useContext(Ctx);
if (!v) throw new Error("useAuth: missing AuthProvider");
return v;
}