137 lines
3.0 KiB
TypeScript
137 lines
3.0 KiB
TypeScript
'use client';
|
|
|
|
import styled from 'styled-components';
|
|
import type { ApprovalItem, WorkflowEvent } from '@/lib/control/types';
|
|
|
|
const Panel = styled.aside`
|
|
display: grid;
|
|
gap: 14px;
|
|
`;
|
|
|
|
const Card = styled.section`
|
|
border: 1px solid var(--border-color);
|
|
border-radius: 22px;
|
|
padding: 18px;
|
|
background: linear-gradient(180deg, rgba(255,255,255,0.045), rgba(255,255,255,0.018));
|
|
`;
|
|
|
|
const Title = styled.h2`
|
|
margin: 0 0 12px;
|
|
font-size: 15px;
|
|
`;
|
|
|
|
const Eyebrow = styled.div`
|
|
font-family: var(--font-mono);
|
|
font-size: 10px;
|
|
color: var(--text-secondary);
|
|
text-transform: uppercase;
|
|
margin-bottom: 6px;
|
|
`;
|
|
|
|
const EventTitle = styled.h3`
|
|
margin: 0;
|
|
font-size: 20px;
|
|
line-height: 1.2;
|
|
`;
|
|
|
|
const Detail = styled.p`
|
|
margin: 12px 0 0;
|
|
color: var(--text-secondary);
|
|
font-size: 13px;
|
|
`;
|
|
|
|
const MetaGrid = styled.div`
|
|
display: grid;
|
|
grid-template-columns: 1fr 1fr;
|
|
gap: 8px;
|
|
margin-top: 16px;
|
|
`;
|
|
|
|
const Meta = styled.div`
|
|
border: 1px solid rgba(255,255,255,0.08);
|
|
border-radius: 14px;
|
|
padding: 10px;
|
|
background: rgba(0,0,0,0.18);
|
|
`;
|
|
|
|
const MetaValue = styled.div`
|
|
font-family: var(--font-mono);
|
|
font-size: 11px;
|
|
color: var(--text-primary);
|
|
overflow-wrap: anywhere;
|
|
`;
|
|
|
|
const ApprovalList = styled.div`
|
|
display: grid;
|
|
gap: 8px;
|
|
`;
|
|
|
|
const ApprovalRow = styled.div<{ $status: ApprovalItem['status'] }>`
|
|
display: grid;
|
|
grid-template-columns: 42px 1fr auto;
|
|
gap: 8px;
|
|
align-items: center;
|
|
border: 1px solid ${({ $status }) => {
|
|
if ($status === 'blocked') return 'rgba(255, 112, 112, 0.42)';
|
|
if ($status === 'waiting') return 'rgba(255, 204, 102, 0.38)';
|
|
return 'rgba(139, 211, 255, 0.28)';
|
|
}};
|
|
border-radius: 14px;
|
|
padding: 10px;
|
|
background: rgba(0,0,0,0.14);
|
|
font-size: 12px;
|
|
`;
|
|
|
|
const Risk = styled.span`
|
|
font-family: var(--font-mono);
|
|
color: var(--text-secondary);
|
|
`;
|
|
|
|
const Status = styled.span`
|
|
font-family: var(--font-mono);
|
|
font-size: 10px;
|
|
color: var(--text-secondary);
|
|
`;
|
|
|
|
export default function ActiveTaskFocus({
|
|
selectedEvent,
|
|
approvals,
|
|
}: {
|
|
selectedEvent: WorkflowEvent;
|
|
approvals: ApprovalItem[];
|
|
}) {
|
|
return (
|
|
<Panel>
|
|
<Card>
|
|
<Title>Active Task Focus</Title>
|
|
<Eyebrow>{selectedEvent.sister} · {selectedEvent.type}</Eyebrow>
|
|
<EventTitle>{selectedEvent.title}</EventTitle>
|
|
<Detail>{selectedEvent.detail}</Detail>
|
|
<MetaGrid>
|
|
<Meta>
|
|
<Eyebrow>workflow</Eyebrow>
|
|
<MetaValue>{selectedEvent.workflowId}</MetaValue>
|
|
</Meta>
|
|
<Meta>
|
|
<Eyebrow>source</Eyebrow>
|
|
<MetaValue>{selectedEvent.source}</MetaValue>
|
|
</Meta>
|
|
</MetaGrid>
|
|
</Card>
|
|
|
|
<Card>
|
|
<Title>Approval / Risk</Title>
|
|
<ApprovalList>
|
|
{approvals.map((item) => (
|
|
<ApprovalRow key={item.id} $status={item.status}>
|
|
<Risk>{item.risk}</Risk>
|
|
<span>{item.title}</span>
|
|
<Status>{item.status}</Status>
|
|
</ApprovalRow>
|
|
))}
|
|
</ApprovalList>
|
|
</Card>
|
|
</Panel>
|
|
);
|
|
}
|