120 lines
2.7 KiB
TypeScript
120 lines
2.7 KiB
TypeScript
// app/(app)/devices/DeviceHistorySidebar.tsx
|
|
'use client';
|
|
|
|
import { useEffect, useState } from 'react';
|
|
import Feed, { FeedItem } from '@/components/ui/Feed';
|
|
|
|
type DeviceHistoryEntry = {
|
|
id: string;
|
|
changeType: 'CREATED' | 'UPDATED' | 'DELETED';
|
|
changedAt: string;
|
|
changedBy?: string | null;
|
|
};
|
|
|
|
function formatDateTime(iso: string) {
|
|
return new Intl.DateTimeFormat('de-DE', {
|
|
dateStyle: 'short',
|
|
timeStyle: 'short',
|
|
}).format(new Date(iso));
|
|
}
|
|
|
|
function changeTypeLabel(type: DeviceHistoryEntry['changeType']) {
|
|
switch (type) {
|
|
case 'CREATED':
|
|
return 'Gerät angelegt';
|
|
case 'UPDATED':
|
|
return 'Gerät aktualisiert';
|
|
case 'DELETED':
|
|
return 'Gerät gelöscht';
|
|
default:
|
|
return type;
|
|
}
|
|
}
|
|
|
|
interface DeviceHistorySidebarProps {
|
|
inventoryNumber: string;
|
|
}
|
|
|
|
export default function DeviceHistorySidebar({
|
|
inventoryNumber,
|
|
}: DeviceHistorySidebarProps) {
|
|
const [entries, setEntries] = useState<DeviceHistoryEntry[]>([]);
|
|
const [loading, setLoading] = useState(false);
|
|
const [error, setError] = useState<string | null>(null);
|
|
|
|
useEffect(() => {
|
|
if (!inventoryNumber) return;
|
|
|
|
const loadHistory = async () => {
|
|
setLoading(true);
|
|
setError(null);
|
|
|
|
try {
|
|
const res = await fetch(
|
|
`/api/devices/${encodeURIComponent(inventoryNumber)}/history`,
|
|
{ cache: 'no-store' },
|
|
);
|
|
|
|
if (!res.ok) {
|
|
setError('Historie konnte nicht geladen werden.');
|
|
return;
|
|
}
|
|
|
|
const data = (await res.json()) as DeviceHistoryEntry[];
|
|
setEntries(data);
|
|
} catch (err) {
|
|
console.error('Error loading device history', err);
|
|
setError('Netzwerkfehler beim Laden der Historie.');
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
loadHistory();
|
|
}, [inventoryNumber]);
|
|
|
|
if (loading) {
|
|
return (
|
|
<p className="text-sm text-gray-500 dark:text-gray-400">
|
|
Historie wird geladen …
|
|
</p>
|
|
);
|
|
}
|
|
|
|
if (error) {
|
|
return (
|
|
<p className="text-sm text-red-600 dark:text-red-400">
|
|
{error}
|
|
</p>
|
|
);
|
|
}
|
|
|
|
if (!entries.length) {
|
|
return (
|
|
<p className="text-sm text-gray-500 dark:text-gray-400">
|
|
Noch keine Historie vorhanden.
|
|
</p>
|
|
);
|
|
}
|
|
|
|
const feedItems: FeedItem[] = entries.map((entry) => ({
|
|
id: entry.id,
|
|
type: 'comment',
|
|
person: {
|
|
name: entry.changedBy ?? 'System',
|
|
href: '#',
|
|
},
|
|
comment: changeTypeLabel(entry.changeType),
|
|
date: formatDateTime(entry.changedAt),
|
|
}));
|
|
|
|
return (
|
|
<div className="space-y-3">
|
|
<h4 className="text-xs font-semibold uppercase tracking-wide text-gray-500 dark:text-gray-400">
|
|
Historie
|
|
</h4>
|
|
<Feed items={feedItems} />
|
|
</div>
|
|
);
|
|
}
|