update on timeline on portfolio view + some corrections

This commit is contained in:
fahed
2026-02-10 13:20:49 +03:00
parent d15e54044e
commit 334727b232
37 changed files with 5119 additions and 1440 deletions
+37 -15
View File
@@ -1,6 +1,6 @@
const API = '/api';
// Map SQLite fields to frontend-friendly format
// Map NocoDB / snake_case fields to frontend-friendly format
const toCamel = (s) => s.replace(/_([a-z])/g, (_, c) => c.toUpperCase());
const normalize = (data) => {
@@ -12,12 +12,23 @@ const normalize = (data) => {
out[camelKey] = v;
if (camelKey !== k) out[k] = v;
}
// NocoDB uses Id (capital I) — map to id
if (out.Id !== undefined && out.id === undefined) out.id = out.Id;
// Add _id alias
if (out.id !== undefined && out._id === undefined) out._id = out.id;
// NocoDB timestamp fields
if (out.CreatedAt && !out.created_at) { out.created_at = out.CreatedAt; out.createdAt = out.CreatedAt; }
if (out.UpdatedAt && !out.updated_at) { out.updated_at = out.UpdatedAt; out.updatedAt = out.UpdatedAt; }
// Map brand_name → brand (frontend expects post.brand as string)
if (out.brandName && !out.brand) out.brand = out.brandName;
// Map assigned_name for display
if (out.assignedName && !out.assignedToName) out.assignedToName = out.assignedName;
// Parse JSON text fields from NocoDB (stored as LongText)
for (const jsonField of ['platforms', 'brands', 'tags', 'publicationLinks', 'publication_links', 'goals']) {
if (out[jsonField] && typeof out[jsonField] === 'string') {
try { out[jsonField] = JSON.parse(out[jsonField]); } catch {}
}
}
return out;
}
return data;
@@ -73,21 +84,32 @@ export const api = {
}).then(r => handleResponse(r, `UPLOAD ${path}`)),
};
// Brand colors map — matches Samaya brands from backend
export const BRAND_COLORS = {
'Samaya Investment': { bg: 'bg-indigo-100', text: 'text-indigo-700', dot: 'bg-indigo-500' },
'Hira Cultural District': { bg: 'bg-amber-100', text: 'text-amber-700', dot: 'bg-amber-500' },
'Holy Quran Museum': { bg: 'bg-emerald-100', text: 'text-emerald-700', dot: 'bg-emerald-500' },
'Al-Safiya Museum': { bg: 'bg-purple-100', text: 'text-purple-700', dot: 'bg-purple-500' },
'Hayhala': { bg: 'bg-red-100', text: 'text-red-700', dot: 'bg-red-500' },
'Jabal Thawr': { bg: 'bg-stone-100', text: 'text-stone-700', dot: 'bg-stone-500' },
'Coffee Chain': { bg: 'bg-orange-100', text: 'text-orange-700', dot: 'bg-orange-500' },
'Taibah Gifts': { bg: 'bg-pink-100', text: 'text-pink-700', dot: 'bg-pink-500' },
'Google Maps': { bg: 'bg-blue-100', text: 'text-blue-700', dot: 'bg-blue-500' },
'default': { bg: 'bg-gray-100', text: 'text-gray-700', dot: 'bg-gray-500' },
};
// Brand color palette — dynamically assigned from a rotating palette
const BRAND_COLOR_PALETTE = [
{ bg: 'bg-indigo-100', text: 'text-indigo-700', dot: 'bg-indigo-500' },
{ bg: 'bg-amber-100', text: 'text-amber-700', dot: 'bg-amber-500' },
{ bg: 'bg-emerald-100', text: 'text-emerald-700', dot: 'bg-emerald-500' },
{ bg: 'bg-purple-100', text: 'text-purple-700', dot: 'bg-purple-500' },
{ bg: 'bg-red-100', text: 'text-red-700', dot: 'bg-red-500' },
{ bg: 'bg-stone-100', text: 'text-stone-700', dot: 'bg-stone-500' },
{ bg: 'bg-orange-100', text: 'text-orange-700', dot: 'bg-orange-500' },
{ bg: 'bg-pink-100', text: 'text-pink-700', dot: 'bg-pink-500' },
{ bg: 'bg-blue-100', text: 'text-blue-700', dot: 'bg-blue-500' },
{ bg: 'bg-cyan-100', text: 'text-cyan-700', dot: 'bg-cyan-500' },
{ bg: 'bg-teal-100', text: 'text-teal-700', dot: 'bg-teal-500' },
{ bg: 'bg-rose-100', text: 'text-rose-700', dot: 'bg-rose-500' },
];
export const getBrandColor = (brand) => BRAND_COLORS[brand] || BRAND_COLORS['default'];
const DEFAULT_BRAND_COLOR = { bg: 'bg-gray-100', text: 'text-gray-700', dot: 'bg-gray-500' };
const brandColorCache = {};
export const getBrandColor = (brand) => {
if (!brand) return DEFAULT_BRAND_COLOR;
if (brandColorCache[brand]) return brandColorCache[brand];
const idx = Object.keys(brandColorCache).length % BRAND_COLOR_PALETTE.length;
brandColorCache[brand] = BRAND_COLOR_PALETTE[idx];
return brandColorCache[brand];
};
// Platform icons helper — svg paths for inline icons
export const PLATFORMS = {