Add inline priority editing on account detail page

- Clickable priority badge with dropdown to change High/Medium/Low
- New account.priority API action for lightweight single-field update
- Larger priority badges on account cards (text-[10px] font-bold)
- Add FedEx Freight Inc. to database, remove TechFarce
- Update 17 AD assignments from FY26 team mapping spreadsheet

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-09-03 09:24:58 -04:00
parent d79794b164
commit d946a1b9d4
3 changed files with 45 additions and 2 deletions

View File

@@ -158,6 +158,7 @@ export default function AccountExplorer() {
const [showCreateOpp, setShowCreateOpp] = useState(false);
const [showAddActivity, setShowAddActivity] = useState(false);
const [saving, setSaving] = useState(false);
const [editingPriority, setEditingPriority] = useState(false);
const searchParams = useSearchParams();
useEffect(() => {
@@ -371,7 +372,40 @@ export default function AccountExplorer() {
<div className="flex flex-wrap items-center gap-2 mt-2">
<span className="px-2 py-0.5 rounded-full text-[10px] text-white font-semibold" style={{ backgroundColor: TIER_COLORS[selectedAccount.Tier] || '#94A3B8' }}>{selectedAccount.Tier || 'N/A'}</span>
<span className="px-2 py-0.5 rounded-full text-[10px] text-white font-semibold" style={{ backgroundColor: STATUS_COLORS[selectedAccount.AgentMinder_Status] || '#94A3B8' }}>{selectedAccount.AgentMinder_Status}</span>
<span className="px-2 py-0.5 rounded-full text-[10px] text-white font-semibold" style={{ backgroundColor: PRIORITY_COLORS[selectedAccount.Priority] || '#94A3B8' }}>{selectedAccount.Priority} Priority</span>
<span className="relative">
<button
onClick={() => setEditingPriority(!editingPriority)}
className="px-2 py-0.5 rounded-full text-[10px] text-white font-semibold cursor-pointer hover:ring-2 hover:ring-offset-1 hover:ring-brand-azure transition"
style={{ backgroundColor: PRIORITY_COLORS[selectedAccount.Priority] || '#94A3B8' }}
title="Click to change priority"
>
{selectedAccount.Priority} Priority
</button>
{editingPriority && (
<div className="absolute top-full left-0 mt-1 bg-card-bg border border-card-border rounded-lg shadow-lg z-50 py-1 min-w-[120px]">
{['High', 'Medium', 'Low'].map(p => (
<button
key={p}
onClick={async () => {
await fetch('/api/phase2', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ action: 'account.priority', Account_Name: selectedAccount.Account_Name, Priority: p }),
});
setEditingPriority(false);
setSelectedAccount({ ...selectedAccount, Priority: p });
refresh();
}}
className={`w-full text-left px-3 py-1.5 text-xs font-medium flex items-center gap-2 hover:bg-gray-100 transition ${selectedAccount.Priority === p ? 'font-bold' : ''}`}
>
<span className="w-2.5 h-2.5 rounded-full flex-shrink-0" style={{ backgroundColor: PRIORITY_COLORS[p] }} />
{p}
{selectedAccount.Priority === p && <span className="ml-auto text-brand-azure"></span>}
</button>
))}
</div>
)}
</span>
<span className="px-2 py-0.5 rounded-full text-[10px] font-bold" style={{ color: HEALTH_LEVEL_COLORS[detailHealth.health_level], backgroundColor: `${HEALTH_LEVEL_COLORS[detailHealth.health_level]}15` }}>
Health: {detailHealth.health_level} ({detailHealth.health_score})
</span>
@@ -1015,7 +1049,7 @@ export default function AccountExplorer() {
</div>
</div>
<div className="flex items-center gap-1.5 mb-2">
<span className="px-1.5 py-0.5 rounded text-[9px] font-medium text-white" style={{ backgroundColor: PRIORITY_COLORS[account.Priority] || '#94A3B8' }}>{account.Priority}</span>
<span className="px-2 py-0.5 rounded text-[10px] font-bold text-white" style={{ backgroundColor: PRIORITY_COLORS[account.Priority] || '#94A3B8' }}>{account.Priority}</span>
<span className="px-1.5 py-0.5 rounded text-[9px] font-medium text-white" style={{ backgroundColor: STATUS_COLORS[account.AgentMinder_Status] || '#94A3B8' }}>{account.AgentMinder_Status}</span>
<span className="text-[10px] text-muted">{DISTRICT_SHORT[account.District_Name]}</span>
{account.AD && <span className="text-[10px] text-muted">| {account.AD}</span>}

View File

@@ -11,6 +11,7 @@ import {
getForecastLocks, lockForecast, getForecastOverrides, upsertForecastOverride, deleteForecastOverride,
getPipelineMovement, getSnapshotDates,
updateLossReason,
updateAccountPriority,
} from '@/lib/db';
export async function POST(req: NextRequest) {
@@ -96,6 +97,10 @@ export async function POST(req: NextRequest) {
updateLossReason(body.Opportunity_ID, body.Loss_Reason);
return NextResponse.json({ success: true });
case 'account.priority':
updateAccountPriority(body.Account_Name, body.Priority);
return NextResponse.json({ success: true });
// Export
case 'export': {
const data = getDashboardData();

View File

@@ -995,6 +995,10 @@ export function getSnapshotDates(): string[] {
return (db.prepare('SELECT DISTINCT snapshot_date FROM pipeline_snapshots ORDER BY snapshot_date DESC').all() as { snapshot_date: string }[]).map(r => r.snapshot_date);
}
export function updateAccountPriority(accountName: string, priority: string) {
getDb().prepare('UPDATE accounts SET Priority = ? WHERE Account_Name = ?').run(priority, accountName);
}
// --- Win/Loss helpers ---
export function updateLossReason(opportunityId: string, lossReason: string) {
getDb().prepare('UPDATE pipeline SET Loss_Reason = ? WHERE Opportunity_ID = ?').run(lossReason, opportunityId);