Harden media health checks and duration extraction
فشلت بعض الفحوصات
Deploy To Ghaymah / deploy (push) Has been cancelled

هذا الالتزام موجود في:
boutmoun123
2026-05-31 18:53:07 +03:00
الأصل 1973b8b904
التزام 637782aed6
11 ملفات معدلة مع 587 إضافات و138 حذوفات

عرض الملف

@@ -2,7 +2,16 @@
import Link from "next/link";
import { useEffect, useMemo, useState } from "react";
import { Boxes, RefreshCcw, ShieldAlert, Store, Users2 } from "lucide-react";
import {
Boxes,
FileText,
MessageSquareText,
RefreshCcw,
ShieldAlert,
Store,
UserRound,
Users2,
} from "lucide-react";
import { NoPermissionState } from "@/components/auth/no-permission-state";
import { PostPreviewCard } from "@/components/dashboard/post-preview-card";
@@ -69,6 +78,34 @@ function ShortcutLink({
);
}
function getActivityIcon(type: string) {
const normalized = type.toLowerCase();
if (normalized.includes("user")) return UserRound;
if (normalized.includes("comment")) return MessageSquareText;
if (normalized.includes("listing") || normalized.includes("shop")) return Store;
if (normalized.includes("case") || normalized.includes("audit") || normalized.includes("report")) {
return ShieldAlert;
}
return FileText;
}
function ActivityTypeIcon({ type }: { type: string }) {
const Icon = getActivityIcon(type);
return <Icon className="h-4 w-4" />;
}
function getActivityLabel(type: string) {
const normalized = type.toLowerCase();
if (normalized === "post") return "New post";
if (normalized === "user") return "New user";
if (normalized === "comment") return "New comment";
if (normalized === "listing") return "Marketplace listing";
if (normalized === "repair_shop") return "Repair shop";
if (normalized === "case") return "Moderation case";
if (normalized === "audit") return "Audit event";
return type.replace(/_/g, " ");
}
export default function DashboardPage() {
const { permissions } = useSuperAdminSession();
const [snapshot, setSnapshot] = useState<DashboardSnapshot>({
@@ -417,26 +454,33 @@ export default function DashboardPage() {
}
>
<CardHeader className="flex flex-row items-center justify-between">
<CardTitle>Recent activity</CardTitle>
<CardTitle>Platform activity</CardTitle>
<Link href="/analytics" className="text-sm text-primary">
Activity feeds
View analytics
</Link>
</CardHeader>
<CardContent>
{!snapshot.recentActivity.length ? (
<EmptyState
title="No recent activity"
title="No platform activity"
description="Operational and moderation activity will appear here."
/>
) : (
<div className="space-y-3">
{snapshot.recentActivity.map((item, index) => (
{snapshot.recentActivity.slice(0, 5).map((item, index) => (
<div
key={`${item.type}-${index}`}
className="rounded-xl border border-border/70 bg-secondary/20 p-3"
className="rounded-lg border border-border/70 bg-secondary/20 p-3 transition hover:border-primary/40 hover:bg-secondary/30"
>
<div className="flex items-center justify-between gap-3">
<div className="text-sm font-medium text-foreground">{item.title}</div>
<div className="flex min-w-0 items-center gap-3">
<span className="flex h-9 w-9 shrink-0 items-center justify-center rounded-lg border border-border/70 bg-background/50 text-primary">
<ActivityTypeIcon type={item.type} />
</span>
<div dir="auto" className="truncate text-sm font-semibold text-foreground">
{item.title || "Untitled activity"}
</div>
</div>
<Badge
variant={
item.status === "flagged" || item.status === "disabled"
@@ -444,11 +488,11 @@ export default function DashboardPage() {
: "muted"
}
>
{item.type}
{getActivityLabel(item.type)}
</Badge>
</div>
<div className="mt-1 text-xs text-muted-foreground">
{item.subtitle} {formatDateTime(item.createdAt)}
<div dir="auto" className="mt-2 truncate text-xs text-muted-foreground">
{item.subtitle || "No additional details"} - {formatDateTime(item.createdAt)}
</div>
</div>
))}