feat(campaigns): audit timeline UI and manager role in role pickers
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
import { Clock, Loader2 } from "lucide-react";
|
||||
import type { CampaignTimelineEntry } from "../api/campaigns";
|
||||
|
||||
interface Props {
|
||||
entries: CampaignTimelineEntry[];
|
||||
isLoading: boolean;
|
||||
}
|
||||
|
||||
const ACTION_LABELS: Record<string, string> = {
|
||||
create_campaign: "Campaign created",
|
||||
update_campaign: "Campaign updated",
|
||||
submit_campaign_for_approval: "Submitted for approval",
|
||||
approve_campaign: "Approved by manager",
|
||||
reject_campaign: "Rejected by manager",
|
||||
activate_campaign: "Activated",
|
||||
complete_campaign: "Marked completed",
|
||||
request_campaign_modification: "Modification requested",
|
||||
approve_campaign_modification: "Modification approved",
|
||||
reject_campaign_modification: "Modification rejected",
|
||||
};
|
||||
|
||||
export default function CampaignAuditTimeline({ entries, isLoading }: Props) {
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div className="flex items-center justify-center py-12">
|
||||
<Loader2 className="h-6 w-6 animate-spin text-gray-500" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (entries.length === 0) {
|
||||
return (
|
||||
<div className="py-8 text-center">
|
||||
<Clock className="mx-auto h-8 w-8 text-gray-600" />
|
||||
<p className="mt-2 text-sm text-gray-400">No timeline events yet</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const formatDate = (d: string) =>
|
||||
new Date(d).toLocaleString("en-US", {
|
||||
month: "short",
|
||||
day: "numeric",
|
||||
hour: "2-digit",
|
||||
minute: "2-digit",
|
||||
second: "2-digit",
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="relative space-y-0">
|
||||
<div className="absolute left-4 top-2 bottom-2 w-px bg-gray-700" />
|
||||
{entries.map((entry, idx) => (
|
||||
<div key={entry.id || idx} className="relative flex gap-4 py-3">
|
||||
<div className="z-10 flex h-8 w-8 shrink-0 items-center justify-center rounded-full border border-gray-700 bg-gray-800">
|
||||
<Clock className="h-3.5 w-3.5 text-gray-400" />
|
||||
</div>
|
||||
<div className="flex-1 pt-0.5">
|
||||
<p className="text-sm font-medium text-gray-200">
|
||||
{ACTION_LABELS[entry.action] || entry.action}
|
||||
</p>
|
||||
<p className="text-xs text-gray-500">{formatDate(entry.timestamp)}</p>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user