Replace entire Barclays colour palette (navy #1A2142, lime #C3FB5A, violet #7A0FF9) with Oliver brand tokens: black #1A1A1A, gold #FFCB05, orange #FF5C00, azure #0487B6, sky #5DF5EA, grey #EFEFEF, green #09821F. - Switch font from Inter/Barclays Effra to Arial (system font) - Add new Oliver logo asset (BAR-ModComms-logo-v4.png) - Sidebar: black background, new logo, azure active state - Hero: orange "Intelligent Review" text, hide AI-Powered tagline - Hide ChecksOverview on Home page per Oliver design - Toast notification: orange background with black text - All tables: sky headers, alternating white/grey rows - Campaign badges: gold "In Progress", green "Completed" - Analytics: grey KPI cards, sky accent on Key Insight, oliver trend colours - All buttons: azure fill, pill-shaped (rounded-full) - All tabs/toggles/dropdowns: azure accent colour - Update HTML title to "Mod Comms - Intelligent Review" - Default border radius set to 10px Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
113 lines
No EOL
5.3 KiB
TypeScript
Executable file
113 lines
No EOL
5.3 KiB
TypeScript
Executable file
import React, { useState, useEffect } from 'react';
|
|
import { TrashIcon } from './icons/TrashIcon';
|
|
import { ChevronDownIcon } from './icons/ChevronDownIcon';
|
|
|
|
interface ProofTypeManagerProps {
|
|
subChannels: string[];
|
|
proofTypesBySubChannel: Record<string, string[]>;
|
|
onAddProofType: (subChannel: string, value: string) => void;
|
|
onRemoveProofType: (subChannel: string, value: string) => void;
|
|
disabled: boolean;
|
|
}
|
|
|
|
export const ProofTypeManager: React.FC<ProofTypeManagerProps> = ({
|
|
subChannels,
|
|
proofTypesBySubChannel,
|
|
onAddProofType,
|
|
onRemoveProofType,
|
|
disabled
|
|
}) => {
|
|
const [selectedSubChannel, setSelectedSubChannel] = useState<string>('');
|
|
const [newItem, setNewItem] = useState('');
|
|
|
|
useEffect(() => {
|
|
// If subChannels are available, default to the first one.
|
|
if (subChannels.length > 0 && !selectedSubChannel) {
|
|
setSelectedSubChannel(subChannels[0]);
|
|
}
|
|
}, [subChannels, selectedSubChannel]);
|
|
|
|
const handleSubmit = (e: React.FormEvent) => {
|
|
e.preventDefault();
|
|
if (newItem.trim() && selectedSubChannel) {
|
|
onAddProofType(selectedSubChannel, newItem.trim());
|
|
setNewItem('');
|
|
}
|
|
};
|
|
|
|
const currentProofTypes = proofTypesBySubChannel[selectedSubChannel] || [];
|
|
|
|
return (
|
|
<div className="bg-white rounded-lg shadow-md p-6 border border-gray-200 flex flex-col h-full">
|
|
<h2 className="text-xl font-bold text-oliver-black mb-2">Proof Type Manager</h2>
|
|
<p className="text-sm text-gray-500 mb-4">Assign and manage specific proof types for each sub-channel.</p>
|
|
|
|
<div className="mb-4">
|
|
<label htmlFor="subchannel-select" className="block text-sm font-medium text-gray-700 mb-1">
|
|
Select a Sub-Channel to manage:
|
|
</label>
|
|
<div className="relative">
|
|
<select
|
|
id="subchannel-select"
|
|
value={selectedSubChannel}
|
|
onChange={(e) => setSelectedSubChannel(e.target.value)}
|
|
className="w-full bg-white border border-gray-300 rounded-md py-2 pl-3 pr-10 text-gray-900 focus:outline-none focus:ring-2 focus:ring-oliver-azure appearance-none disabled:bg-gray-100"
|
|
disabled={disabled}
|
|
>
|
|
{subChannels.map(sc => (
|
|
<option key={sc} value={sc}>{sc}</option>
|
|
))}
|
|
</select>
|
|
<div className="pointer-events-none absolute inset-y-0 right-0 flex items-center px-3 text-gray-400">
|
|
<ChevronDownIcon className="h-4 w-4" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<form onSubmit={handleSubmit} className="flex gap-2 mb-4">
|
|
<input
|
|
type="text"
|
|
value={newItem}
|
|
onChange={(e) => setNewItem(e.target.value)}
|
|
placeholder="New Proof Type..."
|
|
className="flex-grow p-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-oliver-azure focus:border-oliver-azure transition disabled:bg-gray-100 disabled:cursor-not-allowed"
|
|
disabled={disabled || !selectedSubChannel}
|
|
/>
|
|
<button
|
|
type="submit"
|
|
className="bg-oliver-azure text-white font-semibold py-2 px-4 rounded-md hover:bg-oliver-azure transition-colors duration-300 disabled:bg-gray-400 disabled:cursor-not-allowed"
|
|
disabled={!newItem.trim() || disabled || !selectedSubChannel}
|
|
>
|
|
Add
|
|
</button>
|
|
</form>
|
|
|
|
<div className="flex-1 overflow-y-auto pr-2 -mr-2">
|
|
{currentProofTypes.length > 0 ? (
|
|
<ul className="space-y-2">
|
|
{currentProofTypes.map((item) => (
|
|
<li
|
|
key={item}
|
|
className="flex items-center justify-between bg-gray-50 p-2.5 rounded-md border border-gray-200 group"
|
|
>
|
|
<span className="text-gray-800">{item}</span>
|
|
<button
|
|
onClick={() => onRemoveProofType(selectedSubChannel, item)}
|
|
className={`text-gray-400 hover:text-red-600 transition-opacity ${disabled ? 'opacity-0 cursor-not-allowed' : 'opacity-0 group-hover:opacity-100'}`}
|
|
title={`Remove ${item}`}
|
|
disabled={disabled}
|
|
>
|
|
<TrashIcon className="h-5 w-5" />
|
|
</button>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
) : (
|
|
<div className="text-center py-8 text-gray-500 bg-gray-50 rounded-md h-full flex items-center justify-center">
|
|
<p>No proof types configured for <br/> <strong className="text-gray-600">{selectedSubChannel}</strong>.</p>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
}; |