src/App.tsx
Ready
localhost:5173
Ant Design 6ReadyTSXLn 1, Col 1
Online Ant Design playground with React, TypeScript, editable components, theme tokens, enterprise tables, and instant live preview.
Online Ant Design playground with React, TypeScript, editable components, theme tokens, enterprise tables, and instant live preview.
Runtime: v6.5.2
Press Enter to evaluate, ↑ and ↓ to browse command history, and Ctrl/⌘ + L to clear the console.
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>,
)
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>
)
}