src/main.tsx
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import { ConfigProvider } from 'antd'
import App from './App'
import { appTheme } from './theme'
import './styles.css'
createRoot(document.getElementById('root')!).render(
<StrictMode>
<ConfigProvider theme={appTheme}>
<App />
</ConfigProvider>
</StrictMode>,
)
src/App.tsx
import { useMemo, useState } from 'react'
import {
Avatar,
Button,
Card,
Col,
Flex,
Layout,
Progress,
Row,
Segmented,
Space,
Statistic,
Tag,
Typography,
} from 'antd'
import { ProjectTable, projects } from './components/ProjectTable'
const { Header, Content } = Layout
const { Title, Text } = Typography
export default function App() {
const [filter, setFilter] = useState('All')
const [syncLabel, setSyncLabel] = useState('Sync data')
const visibleProjects = useMemo(
() =>
filter === 'All'
? projects
: projects.filter((project) => project.status === filter),
[filter],
)
const syncData = () => {
setSyncLabel('Synced just now')
}
return (
<Layout className="app-shell">
<Header className="app-header">
<Flex align="center" justify="space-between" gap={16}>
<Flex align="center" gap={12}>
<Avatar className="brand-mark" shape="square">
A
</Avatar>
<div>
<Text className="eyebrow">OPERATIONS</Text>
<Title level={4}>Atlas workspace</Title>
</div>
</Flex>
<Space>
<Tag color="processing">Live</Tag>
<Avatar>DM</Avatar>
</Space>
</Flex>
</Header>
<Content className="app-content">
<Flex
className="page-heading"
align="flex-end"
justify="space-between"
gap={20}
wrap
>
<div>
<Text type="secondary">Monday, 29 July</Text>
<Title>Portfolio overview</Title>
<Text type="secondary">
Track delivery health across your active initiatives.
</Text>
</div>
<Button type="primary" size="large" onClick={syncData}>
{syncLabel}
</Button>
</Flex>
<Row gutter={[16, 16]}>
<Col xs={24} sm={12} xl={8}>
<Card>
<Statistic title="Active projects" value={12} suffix="/ 16" />
<Text type="success">↑ 8.2% this month</Text>
</Card>
</Col>
<Col xs={24} sm={12} xl={8}>
<Card>
<Statistic title="Tasks completed" value={248} />
<Text type="secondary">36 completed this week</Text>
</Card>
</Col>
<Col xs={24} sm={12} xl={8}>
<Card>
<Flex align="center" justify="space-between">
<Statistic title="Delivery score" value={86} suffix="%" />
<Progress type="circle" percent={86} size={64} />
</Flex>
</Card>
</Col>
</Row>
<Card
className="projects-card"
title={
<Space orientation="vertical" size={0}>
<Text strong>Project health</Text>
<Text type="secondary" className="card-subtitle">
Current delivery status and team progress
</Text>
</Space>
}
extra={
<Segmented
options={['All', 'On track', 'At risk']}
value={filter}
onChange={(value) => setFilter(String(value))}
/>
}
>
<ProjectTable projects={visibleProjects} />
</Card>
</Content>
</Layout>
)
}