feat(ui): Update Industries settings to display Notion-synced fields read-only

This commit is contained in:
2026-01-19 11:51:07 +00:00
parent 7c2ae08c74
commit bbefb36f47

View File

@@ -118,49 +118,72 @@ export function RoboticsSettings({ isOpen, onClose, apiBase }: RoboticsSettingsP
{activeTab === 'industries' && (
<div className="space-y-4">
<div className="flex justify-between items-center">
<h3 className="text-sm font-bold text-slate-700 dark:text-slate-300">Industry Verticals</h3>
<h3 className="text-sm font-bold text-slate-700 dark:text-slate-300">Industry Verticals (Synced from Notion)</h3>
{/* Notion SSoT: Creation disabled here
<button onClick={handleAddIndustry} className="flex items-center gap-1 px-3 py-1.5 bg-blue-600 hover:bg-blue-500 text-white text-xs font-bold rounded">
<Plus className="h-3 w-3" /> ADD NEW
</button>
*/}
</div>
<div className="grid grid-cols-1 gap-3">
{industries.map(ind => (
<div key={ind.id} className="bg-slate-50 dark:bg-slate-950 border border-slate-200 dark:border-slate-800 rounded-lg p-4 flex gap-4 items-start group">
<div className="flex-1 space-y-2">
<div className="flex gap-2">
<input
className="bg-transparent border-b border-transparent focus:border-blue-500 outline-none font-bold text-slate-900 dark:text-white text-sm w-full"
defaultValue={ind.name}
onBlur={(e) => handleUpdateIndustry(ind.id, { name: e.target.value })}
/>
<div className="flex items-center gap-2">
<input
type="checkbox"
checked={ind.is_focus}
onChange={(e) => handleUpdateIndustry(ind.id, { is_focus: e.target.checked })}
className="rounded border-slate-300 dark:border-slate-700"
/>
<span className="text-xs text-slate-500">Focus?</span>
<div key={ind.id} className="bg-slate-50 dark:bg-slate-950 border border-slate-200 dark:border-slate-800 rounded-lg p-4 flex flex-col gap-3 group relative overflow-hidden">
{/* Sync Indicator */}
{ind.notion_id && (
<div className="absolute top-0 right-0 bg-blue-100 dark:bg-blue-900/30 text-blue-600 dark:text-blue-400 text-[9px] font-bold px-2 py-0.5 rounded-bl">
SYNCED
</div>
)}
{/* Top Row: Name, Status, Group */}
<div className="flex gap-4 items-start pr-12">
<div className="flex-1">
<h4 className="font-bold text-slate-900 dark:text-white text-sm">{ind.name}</h4>
<div className="flex flex-wrap gap-2 mt-1">
{ind.industry_group && <span className="text-[10px] bg-slate-200 dark:bg-slate-800 px-1.5 rounded text-slate-600 dark:text-slate-400">{ind.industry_group}</span>}
{ind.status_notion && <span className="text-[10px] border border-slate-300 dark:border-slate-700 px-1.5 rounded text-slate-500">{ind.status_notion}</span>}
</div>
</div>
<div className="text-right">
<div className="flex items-center gap-1.5 justify-end">
<span className={clsx("w-2 h-2 rounded-full", ind.is_focus ? "bg-green-500" : "bg-slate-300 dark:bg-slate-700")} />
<span className="text-xs text-slate-500">{ind.is_focus ? "Focus" : "Standard"}</span>
</div>
</div>
<textarea
className="w-full bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded p-2 text-xs text-slate-600 dark:text-slate-300 focus:ring-1 focus:ring-blue-500 outline-none h-16 resize-none"
defaultValue={ind.description}
placeholder="Description / Abgrenzung..."
onBlur={(e) => handleUpdateIndustry(ind.id, { description: e.target.value })}
/>
<select
className="w-full bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded p-1.5 text-xs text-slate-600 dark:text-slate-300 outline-none"
value={ind.primary_category_id || ""}
onChange={(e) => handleUpdateIndustry(ind.id, { primary_category_id: e.target.value ? parseInt(e.target.value) : null })}
>
<option value="">-- No Primary Product --</option>
{roboticsCategories.map(c => <option key={c.id} value={c.id}>{c.name}</option>)}
</select>
</div>
<button onClick={() => handleDeleteIndustry(ind.id)} className="p-2 text-slate-400 hover:text-red-500 opacity-0 group-hover:opacity-100 transition-opacity">
<Trash2 className="h-4 w-4" />
</button>
{/* Description */}
<p className="text-xs text-slate-600 dark:text-slate-300 italic whitespace-pre-wrap">{ind.description || "No definition"}</p>
{/* Metrics Grid */}
<div className="grid grid-cols-2 sm:grid-cols-4 gap-2 text-[10px] bg-white dark:bg-slate-900 p-2 rounded border border-slate-200 dark:border-slate-800">
<div>
<span className="block text-slate-400 font-bold uppercase">Whale ></span>
<span className="text-slate-700 dark:text-slate-200">{ind.whale_threshold || "-"}</span>
</div>
<div>
<span className="block text-slate-400 font-bold uppercase">Min Req</span>
<span className="text-slate-700 dark:text-slate-200">{ind.min_requirement || "-"}</span>
</div>
<div>
<span className="block text-slate-400 font-bold uppercase">Unit</span>
<span className="text-slate-700 dark:text-slate-200 truncate">{ind.core_unit || "-"}</span>
</div>
<div>
<span className="block text-slate-400 font-bold uppercase">Product</span>
<span className="text-slate-700 dark:text-slate-200 truncate">
{roboticsCategories.find(c => c.id === ind.primary_category_id)?.name || "-"}
</span>
</div>
</div>
{/* Keywords */}
{ind.scraper_keywords && (
<div className="text-[10px]">
<span className="text-slate-400 font-bold uppercase mr-2">Keywords:</span>
<span className="text-slate-600 dark:text-slate-400 font-mono">{ind.scraper_keywords}</span>
</div>
)}
</div>
))}
</div>