blob: 253b44f121364aca11a9e087a42820149bd161c7 (
plain) (
tree)
|
|
import React, { useEffect, useState, useCallback } from 'react'
import { Link } from 'react-router-dom'
import { ContractCreateModal } from './ContractCreateModal'
interface ContractSummary {
id: string
name: string
description?: string
contract_type: string
phase: string
status: string
file_count: number
task_count: number
repository_count: number
created_at: string
// Red team fields
red_team_enabled?: boolean
}
export function ContractList() {
const [contracts, setContracts] = useState<ContractSummary[]>([])
const [loading, setLoading] = useState(true)
const [error, setError] = useState<string | null>(null)
const [showCreateModal, setShowCreateModal] = useState(false)
const fetchContracts = useCallback(async () => {
try {
setLoading(true)
const response = await fetch('/api/v1/contracts')
if (!response.ok) {
throw new Error(`Failed to fetch contracts: ${response.statusText}`)
}
const data = await response.json()
setContracts(data.contracts || [])
} catch (err) {
setError(err instanceof Error ? err.message : 'Unknown error')
} finally {
setLoading(false)
}
}, [])
useEffect(() => {
fetchContracts()
}, [fetchContracts])
if (loading) {
return (
<div className="contract-list-container">
<div className="loading">Loading contracts...</div>
</div>
)
}
if (error) {
return (
<div className="contract-list-container">
<div className="error">Error: {error}</div>
</div>
)
}
return (
<div className="contract-list-container">
<div className="contract-list-header">
<h1>Contracts</h1>
<button
className="create-contract-btn"
onClick={() => setShowCreateModal(true)}
>
+ New Contract
</button>
</div>
{contracts.length === 0 ? (
<p>No contracts found</p>
) : (
<ul className="contract-list">
{contracts.map((contract) => (
<li key={contract.id} className="contract-item">
<Link to={`/contracts/${contract.id}`}>
<h2>
{contract.name}
{contract.red_team_enabled && (
<span className="red-team-badge" title="Red Team monitoring enabled">
🔍
</span>
)}
</h2>
{contract.description && <p>{contract.description}</p>}
<div className="contract-meta">
<span>Phase: {contract.phase}</span>
<span>Status: {contract.status}</span>
<span>Files: {contract.file_count}</span>
<span>Tasks: {contract.task_count}</span>
</div>
</Link>
</li>
))}
</ul>
)}
<ContractCreateModal
isOpen={showCreateModal}
onClose={() => setShowCreateModal(false)}
onCreated={fetchContracts}
/>
</div>
)
}
|