some fixes and refactors
This commit is contained in:
parent
ead8a566d0
commit
75cfc6c928
16 changed files with 381 additions and 425 deletions
|
|
@ -20,6 +20,9 @@ const mockLogout = vi.fn();
|
|||
const mockHasPermission = vi.fn((permission: string) =>
|
||||
mockUser?.permissions.includes(permission) ?? false
|
||||
);
|
||||
const mockHasRole = vi.fn((role: string) =>
|
||||
mockUser?.roles.includes(role) ?? false
|
||||
);
|
||||
|
||||
vi.mock("../auth-context", () => ({
|
||||
useAuth: () => ({
|
||||
|
|
@ -27,6 +30,7 @@ vi.mock("../auth-context", () => ({
|
|||
isLoading: mockIsLoading,
|
||||
logout: mockLogout,
|
||||
hasPermission: mockHasPermission,
|
||||
hasRole: mockHasRole,
|
||||
}),
|
||||
Permission: {
|
||||
VIEW_COUNTER: "view_counter",
|
||||
|
|
@ -52,6 +56,9 @@ beforeEach(() => {
|
|||
mockHasPermission.mockImplementation((permission: string) =>
|
||||
mockUser?.permissions.includes(permission) ?? false
|
||||
);
|
||||
mockHasRole.mockImplementation((role: string) =>
|
||||
mockUser?.roles.includes(role) ?? false
|
||||
);
|
||||
// Default: successful empty response
|
||||
mockFetch.mockResolvedValue({
|
||||
ok: true,
|
||||
|
|
@ -114,7 +121,8 @@ describe("AuditPage", () => {
|
|||
render(<AuditPage />);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText("Failed to load counter records")).toBeTruthy();
|
||||
const errors = screen.getAllByText("Request failed: 500");
|
||||
expect(errors.length).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
"use client";
|
||||
|
||||
import { useEffect, useState, useCallback } from "react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useAuth, Permission } from "../auth-context";
|
||||
import { API_URL } from "../config";
|
||||
import { Permission } from "../auth-context";
|
||||
import { api } from "../api";
|
||||
import { sharedStyles } from "../styles/shared";
|
||||
import { Header } from "../components/Header";
|
||||
import { useRequireAuth } from "../hooks/useRequireAuth";
|
||||
|
||||
interface CounterRecord {
|
||||
id: number;
|
||||
|
|
@ -38,31 +39,17 @@ export default function AuditPage() {
|
|||
const [sumError, setSumError] = useState<string | null>(null);
|
||||
const [counterPage, setCounterPage] = useState(1);
|
||||
const [sumPage, setSumPage] = useState(1);
|
||||
const { user, isLoading, logout, hasPermission } = useAuth();
|
||||
const router = useRouter();
|
||||
|
||||
const canViewAudit = hasPermission(Permission.VIEW_AUDIT);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isLoading) {
|
||||
if (!user) {
|
||||
router.push("/login");
|
||||
} else if (!canViewAudit) {
|
||||
router.push("/");
|
||||
}
|
||||
}
|
||||
}, [isLoading, user, router, canViewAudit]);
|
||||
const { user, isLoading, isAuthorized } = useRequireAuth({
|
||||
requiredPermission: Permission.VIEW_AUDIT,
|
||||
fallbackRedirect: "/",
|
||||
});
|
||||
|
||||
const fetchCounterRecords = useCallback(async (page: number) => {
|
||||
setCounterError(null);
|
||||
try {
|
||||
const res = await fetch(`${API_URL}/api/audit/counter?page=${page}&per_page=10`, {
|
||||
credentials: "include",
|
||||
});
|
||||
if (!res.ok) {
|
||||
throw new Error("Failed to load counter records");
|
||||
}
|
||||
const data = await res.json();
|
||||
const data = await api.get<PaginatedResponse<CounterRecord>>(
|
||||
`/api/audit/counter?page=${page}&per_page=10`
|
||||
);
|
||||
setCounterData(data);
|
||||
} catch (err) {
|
||||
setCounterData(null);
|
||||
|
|
@ -73,13 +60,9 @@ export default function AuditPage() {
|
|||
const fetchSumRecords = useCallback(async (page: number) => {
|
||||
setSumError(null);
|
||||
try {
|
||||
const res = await fetch(`${API_URL}/api/audit/sum?page=${page}&per_page=10`, {
|
||||
credentials: "include",
|
||||
});
|
||||
if (!res.ok) {
|
||||
throw new Error("Failed to load sum records");
|
||||
}
|
||||
const data = await res.json();
|
||||
const data = await api.get<PaginatedResponse<SumRecord>>(
|
||||
`/api/audit/sum?page=${page}&per_page=10`
|
||||
);
|
||||
setSumData(data);
|
||||
} catch (err) {
|
||||
setSumData(null);
|
||||
|
|
@ -88,21 +71,16 @@ export default function AuditPage() {
|
|||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (user && canViewAudit) {
|
||||
if (user && isAuthorized) {
|
||||
fetchCounterRecords(counterPage);
|
||||
}
|
||||
}, [user, counterPage, canViewAudit, fetchCounterRecords]);
|
||||
}, [user, counterPage, isAuthorized, fetchCounterRecords]);
|
||||
|
||||
useEffect(() => {
|
||||
if (user && canViewAudit) {
|
||||
if (user && isAuthorized) {
|
||||
fetchSumRecords(sumPage);
|
||||
}
|
||||
}, [user, sumPage, canViewAudit, fetchSumRecords]);
|
||||
|
||||
const handleLogout = async () => {
|
||||
await logout();
|
||||
router.push("/login");
|
||||
};
|
||||
}, [user, sumPage, isAuthorized, fetchSumRecords]);
|
||||
|
||||
const formatDate = (dateStr: string) => {
|
||||
return new Date(dateStr).toLocaleString();
|
||||
|
|
@ -116,23 +94,13 @@ export default function AuditPage() {
|
|||
);
|
||||
}
|
||||
|
||||
if (!user || !canViewAudit) {
|
||||
if (!user || !isAuthorized) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<main style={styles.main}>
|
||||
<div style={styles.header}>
|
||||
<div style={styles.nav}>
|
||||
<span style={styles.navCurrent}>Audit</span>
|
||||
</div>
|
||||
<div style={styles.userInfo}>
|
||||
<span style={styles.userEmail}>{user.email}</span>
|
||||
<button onClick={handleLogout} style={styles.logoutBtn}>
|
||||
Sign out
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<Header currentPage="audit" />
|
||||
|
||||
<div style={styles.content}>
|
||||
<div style={styles.tablesContainer}>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue