Files
GMW/services/frontend/src/lib/navigation.ts
T
asepharyana f999be4fa0 feat(dashboard): add moderation log page + message edit history
- Backend moderation module: GET /api/moderation/stats (per-status + failed rate)
  + GET /api/moderation/actions (filter by status/actionType, cursor paging),
  joins messages for target username + content
- Message GET /api/messages/detail/:id now returns edit_count + edit_history
  (old_content snapshots from message_edits, newest first)
- FE: new /moderation page — summary cards (total/executed/failed/pending +
  failed-rate), status+type filter chips, timeline rows with action icon,
  target user, reason, status badge, timestamps, error text
- FE: message detail shows 'Riwayat edit' panel with previous versions
2026-08-05 11:11:10 +07:00

81 lines
1.6 KiB
TypeScript

import {
Headphones,
LayoutDashboard,
type LucideIcon,
MessageSquare,
Mic,
Music,
Search,
Shield,
} from "lucide-react";
export interface NavItem {
href: string;
label: string;
icon: LucideIcon;
/** The pathname prefix that indicates this item is active */
matchPrefix: string;
}
/**
* Primary navigation items shown in the sidebar.
*/
export const navItems: NavItem[] = [
{
href: "/dashboard",
label: "Dashboard",
icon: LayoutDashboard,
matchPrefix: "/dashboard",
},
{
href: "/messages",
label: "Messages",
icon: MessageSquare,
matchPrefix: "/messages",
},
{
href: "/voice",
label: "Voice",
icon: Mic,
matchPrefix: "/voice",
},
{
href: "/media",
label: "Media",
icon: Music,
matchPrefix: "/media",
},
{
href: "/recordings",
label: "Recordings",
icon: Headphones,
matchPrefix: "/recordings",
},
{
href: "/moderation",
label: "Moderation",
icon: Shield,
matchPrefix: "/moderation",
},
{
href: "/analysis",
label: "Search",
icon: Search,
matchPrefix: "/analysis",
},
];
/**
* Mobile bottom bar items (subset of primary nav).
*/
export const mobileNavItems: NavItem[] = navItems.filter((item) =>
["/dashboard", "/messages", "/voice", "/media"].includes(item.href),
);
export type NavItemId = (typeof navItems)[number]["href"];
export function isActivePath(pathname: string, matchPrefix: string): boolean {
if (matchPrefix === "/dashboard") return pathname === "/dashboard";
return pathname.startsWith(matchPrefix);
}