restore: old src/ components, subscriptions, audit-log, client detail pages; fix tsconfig @/* paths; merge api.ts

This commit is contained in:
Forge
2026-03-25 16:15:17 +08:00
parent 6565590eb3
commit 2b385ba866
19 changed files with 1423 additions and 48 deletions

View File

@@ -0,0 +1,71 @@
"use client";
import React, { createContext, useContext, useState, useEffect, useCallback } from "react";
import api from "@/lib/api";
import type { AuthState, User } from "@/types";
const AuthContext = createContext<AuthState | null>(null);
export function AuthProvider({ children }: { children: React.ReactNode }) {
const [user, setUser] = useState<User | null>(null);
const [accessToken, setAccessToken] = useState<string | null>(null);
const [tenantSlug, setTenantSlug] = useState<string | null>(null);
useEffect(() => {
const token = localStorage.getItem("accessToken");
const slug = localStorage.getItem("tenantSlug");
const storedUser = localStorage.getItem("user");
if (token && slug && storedUser) {
setAccessToken(token);
setTenantSlug(slug);
try {
setUser(JSON.parse(storedUser) as User);
} catch {
// ignore parse error
}
}
}, []);
const login = useCallback(async (slug: string, email: string, password: string) => {
const res = await api.post<{ accessToken: string; refreshToken: string; user: User }>(
"/api/v1/auth/login",
{ tenantSlug: slug, email, password }
);
const { accessToken: token, user: userData } = res.data;
localStorage.setItem("accessToken", token);
localStorage.setItem("tenantSlug", slug);
localStorage.setItem("user", JSON.stringify(userData));
setAccessToken(token);
setTenantSlug(slug);
setUser(userData);
}, []);
const logout = useCallback(() => {
localStorage.clear();
setAccessToken(null);
setTenantSlug(null);
setUser(null);
window.location.href = "/login";
}, []);
return (
<AuthContext.Provider
value={{
user,
accessToken,
tenantSlug,
isAuthenticated: !!accessToken,
login,
logout,
}}
>
{children}
</AuthContext.Provider>
);
}
export function useAuth(): AuthState {
const ctx = useContext(AuthContext);
if (!ctx) throw new Error("useAuth must be used within AuthProvider");
return ctx;
}