/** * ContractManager — energy contract list UI. * * Features: * - Table of contracts: name, kind, active badge, currency, created date, actions. * - Actions per row: Activate (PATCH active=true), Add Version, View History. * - "New Contract" button at top. * - Version history modal showing all versions with effective dates and values. * - Loading / error / empty states. */ import { useState } from 'react' import { Table, Button, Group, Text, Loader, Center, Alert, Stack, Badge, ScrollArea, Modal, Accordion, Code, } from '@mantine/core' import { useContracts, useUpdateContract, type ContractResponse, type ContractDetailResponse, } from './hooks' import { ContractForm } from './ContractForm' import apiClient from '../api/client' import { formatLocalDate } from '../utils/datetime' // --------------------------------------------------------------------------- // Version history modal // --------------------------------------------------------------------------- interface VersionHistoryModalProps { contractId: number contractName: string onClose: () => void } function VersionHistoryModal({ contractId, contractName, onClose }: VersionHistoryModalProps) { const [loading, setLoading] = useState(true) const [detail, setDetail] = useState(null) const [fetchError, setFetchError] = useState(null) // Fetch detail on first render useState(() => { apiClient .GET('/api/energy/contracts/{contract_id}', { params: { path: { contract_id: contractId } }, }) .then((res) => { setDetail(res.data ?? null) setLoading(false) }) .catch(() => { setFetchError('Failed to load contract details.') setLoading(false) }) }) return ( {loading && (
)} {fetchError && ( {fetchError} )} {!loading && !fetchError && detail && ( <> {detail.versions.length === 0 ? ( No versions found. ) : ( {detail.versions.map((v) => ( From: {formatLocalDate(v.effective_from)} {v.effective_to ? ( To: {formatLocalDate(v.effective_to)} ) : ( current )} {JSON.stringify(v.values, null, 2)} ))} )} )}
) } // --------------------------------------------------------------------------- // Contract table // --------------------------------------------------------------------------- interface ContractTableProps { contracts: ContractResponse[] onActivate: (id: number) => void onAddVersion: (contract: ContractResponse) => void onViewHistory: (contract: ContractResponse) => void activatingId: number | null } function ContractTable({ contracts, onActivate, onAddVersion, onViewHistory, activatingId, }: ContractTableProps) { if (contracts.length === 0) { return ( No contracts configured yet. Click "New Contract" to add one. ) } return ( Name Kind Active Currency Created Actions {contracts.map((contract) => ( {contract.name} {contract.kind} {contract.active ? 'active' : 'inactive'} {contract.currency} {formatLocalDate(contract.created_at)} {!contract.active && ( )} ))}
) } // --------------------------------------------------------------------------- // ContractManager — top-level // --------------------------------------------------------------------------- export function ContractManager() { const contractsQuery = useContracts() const updateMutation = useUpdateContract() const [showCreateForm, setShowCreateForm] = useState(false) const [addVersionContract, setAddVersionContract] = useState(null) const [historyContract, setHistoryContract] = useState(null) const [activatingId, setActivatingId] = useState(null) async function handleActivate(id: number) { setActivatingId(id) try { await updateMutation.mutateAsync({ id, body: { active: true } }) } finally { setActivatingId(null) } } // --------------------------------------------------------------------------- // Render states // --------------------------------------------------------------------------- if (contractsQuery.isLoading) { return (
) } if (contractsQuery.isError || !contractsQuery.data) { return ( Failed to load contracts. Please refresh. ) } const contracts = contractsQuery.data.items return ( Energy Contracts setAddVersionContract(c)} onViewHistory={(c) => setHistoryContract(c)} activatingId={activatingId} /> {/* Create new contract */} {showCreateForm && ( setShowCreateForm(false)} onSaved={() => setShowCreateForm(false)} /> )} {/* Add version to existing contract */} {addVersionContract && ( setAddVersionContract(null)} onSaved={() => setAddVersionContract(null)} /> )} {/* Version history modal */} {historyContract && ( setHistoryContract(null)} /> )} ) }