feat: include article details (DE/EN) in completeness check and make them editable

This commit is contained in:
Christian Vidal Wolf
2026-04-07 13:38:21 +02:00
parent 32c392d470
commit ec1b506341
3 changed files with 59 additions and 15 deletions
+28 -10
View File
@@ -8,7 +8,7 @@ interface ProductDescriptionsProps {
onEdit: (index: number) => void;
}
type TabType = 'all' | 'missingDeLong' | 'missingEnLong' | 'missingDeShort' | 'missingEnShort' | 'complete' | 'incomplete';
type TabType = 'all' | 'missingDeLong' | 'missingEnLong' | 'missingDeShort' | 'missingEnShort' | 'missingDeDetails' | 'missingEnDetails' | 'complete' | 'incomplete';
export function ProductDescriptions({ data, onEdit }: ProductDescriptionsProps) {
const [activeTab, setActiveTab] = useState<TabType>('all');
@@ -31,8 +31,18 @@ export function ProductDescriptions({ data, onEdit }: ProductDescriptionsProps)
if (activeTab === 'missingEnLong') result = result.filter(r => !r.row[COLUMNS.LONG_EN]);
if (activeTab === 'missingDeShort') result = result.filter(r => !r.row[COLUMNS.SHORT_DE]);
if (activeTab === 'missingEnShort') result = result.filter(r => !r.row[COLUMNS.SHORT_EN]);
if (activeTab === 'complete') result = result.filter(r => r.row[COLUMNS.LONG_DE] && r.row[COLUMNS.LONG_EN] && r.row[COLUMNS.SHORT_DE] && r.row[COLUMNS.SHORT_EN]);
if (activeTab === 'incomplete') result = result.filter(r => !r.row[COLUMNS.LONG_DE] || !r.row[COLUMNS.LONG_EN] || !r.row[COLUMNS.SHORT_DE] || !r.row[COLUMNS.SHORT_EN]);
if (activeTab === 'missingDeDetails') result = result.filter(r => !r.row[COLUMNS.DETAILS_DE]);
if (activeTab === 'missingEnDetails') result = result.filter(r => !r.row[COLUMNS.DETAILS_EN]);
if (activeTab === 'complete') result = result.filter(r =>
r.row[COLUMNS.LONG_DE] && r.row[COLUMNS.LONG_EN] &&
r.row[COLUMNS.SHORT_DE] && r.row[COLUMNS.SHORT_EN] &&
r.row[COLUMNS.DETAILS_DE] && r.row[COLUMNS.DETAILS_EN]
);
if (activeTab === 'incomplete') result = result.filter(r =>
!r.row[COLUMNS.LONG_DE] || !r.row[COLUMNS.LONG_EN] ||
!r.row[COLUMNS.SHORT_DE] || !r.row[COLUMNS.SHORT_EN] ||
!r.row[COLUMNS.DETAILS_DE] || !r.row[COLUMNS.DETAILS_EN]
);
// Search filter
if (search) {
@@ -84,9 +94,13 @@ export function ProductDescriptions({ data, onEdit }: ProductDescriptionsProps)
return 'bg-yellow-500/10 hover:bg-yellow-500/20'; // EOL Highlight
}
const fields = [row[COLUMNS.LONG_DE], row[COLUMNS.LONG_EN], row[COLUMNS.SHORT_DE], row[COLUMNS.SHORT_EN]];
const fields = [
row[COLUMNS.LONG_DE], row[COLUMNS.LONG_EN],
row[COLUMNS.SHORT_DE], row[COLUMNS.SHORT_EN],
row[COLUMNS.DETAILS_DE], row[COLUMNS.DETAILS_EN]
];
const filled = fields.filter(Boolean).length;
if (filled === 4) return 'bg-green-900/10 hover:bg-green-900/20';
if (filled === 6) return 'bg-green-900/10 hover:bg-green-900/20';
if (filled === 0) return 'bg-red-900/10 hover:bg-red-900/20';
return 'bg-yellow-900/10 hover:bg-yellow-900/20';
};
@@ -111,6 +125,8 @@ export function ProductDescriptions({ data, onEdit }: ProductDescriptionsProps)
{ id: 'missingEnLong', label: 'Missing EN Long' },
{ id: 'missingDeShort', label: 'Missing DE Short' },
{ id: 'missingEnShort', label: 'Missing EN Short' },
{ id: 'missingDeDetails', label: 'Missing DE Details' },
{ id: 'missingEnDetails', label: 'Missing EN Details' },
{ id: 'complete', label: 'Complete' },
{ id: 'incomplete', label: 'Incomplete' },
];
@@ -172,7 +188,8 @@ export function ProductDescriptions({ data, onEdit }: ProductDescriptionsProps)
{ col: COLUMNS.ARTICLE_NO, label: 'Article No.' },
{ col: COLUMNS.ARTICLE_NAME, label: 'Article Name' },
{ col: COLUMNS.LINE, label: 'Line' },
{ col: COLUMNS.LICENSE, label: 'License' },
{ col: COLUMNS.DETAILS_DE, label: 'Details DE' },
{ col: COLUMNS.DETAILS_EN, label: 'Details EN' },
{ col: COLUMNS.LONG_DE, label: 'Long DE' },
{ col: COLUMNS.LONG_EN, label: 'Long EN' },
{ col: COLUMNS.SHORT_DE, label: 'Short DE' },
@@ -197,10 +214,11 @@ export function ProductDescriptions({ data, onEdit }: ProductDescriptionsProps)
<tbody className="divide-y divide-slate-700/50">
{paginatedData.map(({ row, index }) => (
<tr key={index} className={cn("transition-colors", getRowColor(row))}>
<td className="px-4 py-3 font-mono text-slate-300">{row[COLUMNS.ARTICLE_NO]}</td>
<td className="px-4 py-3 font-medium text-white max-w-[300px] truncate" title={row[COLUMNS.ARTICLE_NAME]}>{row[COLUMNS.ARTICLE_NAME]}</td>
<td className="px-4 py-3 text-slate-300">{row[COLUMNS.LINE]}</td>
<td className="px-4 py-3 text-slate-300">{row[COLUMNS.LICENSE]}</td>
<td className="px-4 py-3 font-mono text-slate-300 text-xs">{row[COLUMNS.ARTICLE_NO]}</td>
<td className="px-4 py-3 font-medium text-white max-w-[200px] truncate" title={row[COLUMNS.ARTICLE_NAME]}>{row[COLUMNS.ARTICLE_NAME]}</td>
<td className="px-4 py-3 text-slate-300 text-xs">{row[COLUMNS.LINE]}</td>
<td className="px-4 py-3"><Badge content={row[COLUMNS.DETAILS_DE]} row={row} /></td>
<td className="px-4 py-3"><Badge content={row[COLUMNS.DETAILS_EN]} row={row} /></td>
<td className="px-4 py-3"><Badge content={row[COLUMNS.LONG_DE]} row={row} /></td>
<td className="px-4 py-3"><Badge content={row[COLUMNS.LONG_EN]} row={row} /></td>
<td className="px-4 py-3"><Badge content={row[COLUMNS.SHORT_DE]} row={row} /></td>