동의 게이트와 런타임 안정화

This commit is contained in:
Yun Chan 2026-06-27 17:22:38 +09:00
parent 0eb7d925ed
commit 0ec266a761
34 changed files with 1186 additions and 158 deletions

View file

@ -7,7 +7,7 @@ import {
useState,
type ReactNode,
} from "react";
import { api, type MeResponse } from "./api";
import { api, authApi, type MeResponse } from "./api";
export type Role = "learner" | "teacher" | "admin";
export type DesignRole = "learner" | "instructor" | "admin";
@ -18,6 +18,7 @@ export interface AuthUser {
name: string;
role: Role;
cohortIds: string[];
consentAt: number | null;
}
export interface AuthContextValue {
@ -26,6 +27,8 @@ export interface AuthContextValue {
loading: boolean;
login: (role: Role, opts?: { email?: string; displayName?: string }) => Promise<AuthUser>;
logout: () => Promise<void>;
acceptConsent: () => Promise<void>;
withdrawConsent: () => Promise<void>;
}
export function designRoleOf(role: Role): DesignRole {
@ -75,6 +78,7 @@ function userFromMe(me: MeResponse): AuthUser {
name: me.display_name || me.email || me.user_id,
role: (me.role as Role) ?? "learner",
cohortIds: me.cohort_ids ?? [],
consentAt: me.consent_at ?? null,
};
}
@ -124,9 +128,21 @@ export function AuthProvider({ children }: { children: ReactNode }) {
}
}, []);
const acceptConsent = useCallback<AuthContextValue["acceptConsent"]>(async () => {
const response = await authApi.acceptConsent();
setUser((current) =>
current ? { ...current, consentAt: response.consent_at ?? null } : current,
);
}, []);
const withdrawConsent = useCallback<AuthContextValue["withdrawConsent"]>(async () => {
await authApi.withdrawConsent();
setUser((current) => (current ? { ...current, consentAt: null } : current));
}, []);
const value = useMemo<AuthContextValue>(
() => ({ user, role: user?.role ?? null, loading, login, logout }),
[user, loading, login, logout],
() => ({ user, role: user?.role ?? null, loading, login, logout, acceptConsent, withdrawConsent }),
[user, loading, login, logout, acceptConsent, withdrawConsent],
);
return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;