121 lines
4.5 KiB
TypeScript
121 lines
4.5 KiB
TypeScript
import {
|
|
Badge,
|
|
Container,
|
|
Group,
|
|
Stack,
|
|
Text,
|
|
Title,
|
|
Paper,
|
|
Table,
|
|
TextInput,
|
|
Button,
|
|
ActionIcon,
|
|
Tooltip,
|
|
SimpleGrid
|
|
} from '@mantine/core'
|
|
import { createFileRoute } from '@tanstack/react-router'
|
|
import { TbSearch, TbFilter, TbEye, TbReceipt, TbTruckDelivery, TbCreditCard, TbTrendingUp } from 'react-icons/tb'
|
|
import { StatsCard } from '@/frontend/components/StatsCard'
|
|
|
|
export const Route = createFileRoute('/apps/$appId/orders')({
|
|
component: OrdersPage,
|
|
})
|
|
|
|
const mockOrders = [
|
|
{ id: 'ORD-9921', customer: 'John Doe', amount: 'Rp 1.250.000', status: 'PAID', time: '2 mins ago', method: 'BCA Virtual Account' },
|
|
{ id: 'ORD-9922', customer: 'Jane Smith', amount: 'Rp 450.000', status: 'PENDING', time: '15 mins ago', method: 'OVO' },
|
|
{ id: 'ORD-9923', customer: 'Rahmat', amount: 'Rp 2.100.000', status: 'SHIPPING', time: '1 hour ago', method: 'Mandiri Transfer' },
|
|
{ id: 'ORD-9924', customer: 'Amel', amount: 'Rp 750.000', status: 'REFUNDED', time: '2 hours ago', method: 'GoPay' },
|
|
{ id: 'ORD-9925', customer: 'Siti', amount: 'Rp 1.100.000', status: 'PAID', time: '4 hours ago', method: 'Credit Card' },
|
|
]
|
|
|
|
function OrdersPage() {
|
|
return (
|
|
<Stack gap="xl">
|
|
<SimpleGrid cols={{ base: 1, sm: 3 }} spacing="lg">
|
|
<StatsCard title="Daily Revenue" value="Rp 12.8M" icon={TbTrendingUp} color="teal" trend={{ value: '8.4%', positive: true }} />
|
|
<StatsCard title="Active Orders" value="142" icon={TbReceipt} color="brand-blue" />
|
|
<StatsCard title="On Delivery" value="48" icon={TbTruckDelivery} color="orange" />
|
|
</SimpleGrid>
|
|
|
|
<Group justify="space-between" align="center">
|
|
<Stack gap={0}>
|
|
<Title order={3}>Orders Tracking</Title>
|
|
<Text size="sm" c="dimmed">Detailed transaction and shipment tracking center.</Text>
|
|
</Stack>
|
|
</Group>
|
|
|
|
<Paper withBorder radius="2xl" className="glass" p="md">
|
|
<Group mb="md" grow>
|
|
<TextInput
|
|
placeholder="Search Order ID or Customer..."
|
|
leftSection={<TbSearch size={16} />}
|
|
radius="md"
|
|
/>
|
|
<Badge component="div" variant="light" size="xl" radius="md" style={{ display: 'flex', alignItems: 'center', height: '36px' }}>
|
|
<TbFilter size={16} style={{ marginRight: 8 }} /> Filter by Status
|
|
</Badge>
|
|
</Group>
|
|
|
|
<Table className="data-table" verticalSpacing="md" highlightOnHover>
|
|
<Table.Thead>
|
|
<Table.Tr>
|
|
<Table.Th>Order ID</Table.Th>
|
|
<Table.Th>Customer</Table.Th>
|
|
<Table.Th>Amount</Table.Th>
|
|
<Table.Th>Payment Method</Table.Th>
|
|
<Table.Th>Status</Table.Th>
|
|
<Table.Th>Actions</Table.Th>
|
|
</Table.Tr>
|
|
</Table.Thead>
|
|
<Table.Tbody>
|
|
{mockOrders.map((order) => (
|
|
<Table.Tr key={order.id}>
|
|
<Table.Td>
|
|
<Group gap="xs">
|
|
<TbReceipt size={14} color="gray" />
|
|
<Text fw={600} size="sm">{order.id}</Text>
|
|
</Group>
|
|
<Text size="xs" c="dimmed">{order.time}</Text>
|
|
</Table.Td>
|
|
<Table.Td>
|
|
<Text size="sm">{order.customer}</Text>
|
|
</Table.Td>
|
|
<Table.Td>
|
|
<Text fw={700} size="sm" color="brand-blue">{order.amount}</Text>
|
|
</Table.Td>
|
|
<Table.Td>
|
|
<Group gap={4}>
|
|
<TbCreditCard size={12} color="gray" />
|
|
<Text size="xs" c="dimmed">{order.method}</Text>
|
|
</Group>
|
|
</Table.Td>
|
|
<Table.Td>
|
|
<Badge
|
|
radius="sm"
|
|
color={
|
|
order.status === 'PAID' ? 'teal' :
|
|
order.status === 'PENDING' ? 'orange' :
|
|
order.status === 'SHIPPING' ? 'brand-blue' : 'red'
|
|
}
|
|
variant={order.status === 'PENDING' ? 'outline' : 'light'}
|
|
>
|
|
{order.status}
|
|
</Badge>
|
|
</Table.Td>
|
|
<Table.Td>
|
|
<Tooltip label="View Details">
|
|
<ActionIcon variant="light" size="sm" color="blue">
|
|
<TbEye size={14} />
|
|
</ActionIcon>
|
|
</Tooltip>
|
|
</Table.Td>
|
|
</Table.Tr>
|
|
))}
|
|
</Table.Tbody>
|
|
</Table>
|
|
</Paper>
|
|
</Stack>
|
|
)
|
|
}
|