Files
Craze-Data-check/src/types.ts
T
Christian Vidal Wolfandclaude-flow 1556aea081 feat: add Cosmetic Items tab with inline CPNP No. editing
New sidebar tab for cosmetic product lines (INKEE, BATH FUN, TOP FASHION,
SENSES, BODYNESS) filtered to items with empty CPNP No. Column filters on
Item Available allow toggling zero/non-zero stock. CPNP_NO added as virtual
column (index 107) stored in Supabase.

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-05-08 13:28:39 +02:00

104 lines
2.7 KiB
TypeScript

export type ExcelRow = any[];
export interface AppState {
headers: string[];
data: ExcelRow[];
fileName: string;
fileDate: Date | null;
hasUnsavedChanges: boolean;
asinColumnIndex: number | null;
}
// Canonical column indices (defaults)
export const COLUMNS = {
ARTICLE_NO: 0,
ARTICLE_NAME: 2,
LINE: 7,
LICENSE: 8,
DETAILS_EN: 9,
DETAILS_DE: 10,
BARCODE: 29,
TARIFF_CODE: 60,
COUNTRY_ORIGIN: 62,
LONG_DE: 64,
LONG_EN: 65,
SHORT_DE: 66,
SHORT_EN: 67,
RECOMMENDED_AGE: 70,
CLASSIFICATION: 11,
ITEM_AVAILABLE: 16,
MOQ: 28,
UNITS_INNER: 32,
UNITS_OUTER: 33,
ASIN: 76,
INNER_W: 43,
INNER_L: 44,
INNER_H: 45,
OUTER_W: 48,
OUTER_L: 49,
OUTER_H: 50,
VERIFIED_DIMS: 100,
VALIDATED_CHECK: 101,
VALIDATED_NOTE: 102,
PRODUCT_TYPE: 103,
ITEM_TO_LOGISTIC: 104,
ANNA_CHECK: 105,
ANNA_NOTE: 106,
CPNP_NO: 107
};
// Search patterns for dynamic detection
export const COLUMN_PATTERNS: Record<keyof typeof COLUMNS, string[]> = {
ARTICLE_NO: ['article', 'no'],
ARTICLE_NAME: ['article', 'name'],
LINE: ['line'],
LICENSE: ['license'],
DETAILS_EN: ['details', 'english'],
DETAILS_DE: ['details', 'german'],
BARCODE: ['article', 'barcode'],
TARIFF_CODE: ['tariff', 'code'],
COUNTRY_ORIGIN: ['country', 'origin'],
LONG_DE: ['long', 'description', 'german'],
LONG_EN: ['long', 'description', 'english'],
SHORT_DE: ['short', 'description', 'german'],
SHORT_EN: ['short', 'description', 'english'],
RECOMMENDED_AGE: ['recommended', 'age'],
CLASSIFICATION: ['classification'],
ITEM_AVAILABLE: ['item', 'available'],
MOQ: ['moq'],
UNITS_INNER: ['units', 'inner'],
UNITS_OUTER: ['units', 'outer'],
ASIN: ['asin'],
INNER_W: ['inner', 'w'],
INNER_L: ['inner', 'l'],
INNER_H: ['inner', 'h'],
OUTER_W: ['outer', 'w'],
OUTER_L: ['outer', 'l'],
OUTER_H: ['outer', 'h'],
VERIFIED_DIMS: ['verified', 'dims'],
VALIDATED_CHECK: ['validated', 'check'],
VALIDATED_NOTE: ['validated', 'note'],
PRODUCT_TYPE: ['product', 'type'],
ITEM_TO_LOGISTIC: ['item', 'logistic'],
ANNA_CHECK: ['anna', 'check'],
ANNA_NOTE: ['anna', 'note'],
CPNP_NO: ['cpnp'],
// Virtual/Extra columns stay hardcoded and are NOT auto-detected from headers
// to prevent internal data from being shifted or overwritten by Excel column shifts.
};
export function resolveColumnIndices(headers: string[]): typeof COLUMNS {
const resolved = { ...COLUMNS };
const h = headers.map(val => String(val || '').toLowerCase());
Object.entries(COLUMN_PATTERNS).forEach(([key, patterns]) => {
const idx = h.findIndex(headerText =>
patterns.every(p => headerText.includes(p.toLowerCase()))
);
if (idx >= 0) {
resolved[key as keyof typeof COLUMNS] = idx;
}
});
return resolved;
}