upd: fitur tampilan update

This commit is contained in:
2026-04-02 17:37:35 +08:00
parent 5a4128a157
commit 0957a4d271
5 changed files with 42 additions and 59 deletions

View File

@@ -15,6 +15,7 @@ import {
} from '@mantine/core' } from '@mantine/core'
import { useDisclosure } from '@mantine/hooks' import { useDisclosure } from '@mantine/hooks'
import { useState } from 'react' import { useState } from 'react'
import { Link } from '@tanstack/react-router'
import { TbMessageReport, TbHistory, TbExternalLink, TbBug } from 'react-icons/tb' import { TbMessageReport, TbHistory, TbExternalLink, TbBug } from 'react-icons/tb'
const mockErrors = [ const mockErrors = [
@@ -85,7 +86,7 @@ export function ErrorDataTable() {
</ThemeIcon> </ThemeIcon>
<Text fw={700}>LATEST ERROR REPORTS</Text> <Text fw={700}>LATEST ERROR REPORTS</Text>
</Group> </Group>
<Button variant="subtle" size="compact-xs" color="blue" rightSection={<TbExternalLink size={14} />}> <Button component={Link} to='/apps/desa-plus/errors' variant="subtle" size="compact-xs" color="blue" rightSection={<TbExternalLink size={14} />}>
View All Reports View All Reports
</Button> </Button>
</Group> </Group>

View File

@@ -1,5 +1,5 @@
import { IconType } from 'react-icons' import { IconType } from 'react-icons'
import { TbChartBar, TbHistory, TbAlertTriangle, TbSettings, TbShoppingCart, TbPackage, TbCreditCard } from 'react-icons/tb' import { TbChartBar, TbHistory, TbAlertTriangle, TbSettings, TbShoppingCart, TbPackage, TbCreditCard, TbBuilding } from 'react-icons/tb'
export interface MenuItem { export interface MenuItem {
value: string value: string
@@ -22,7 +22,7 @@ export const APP_CONFIGS: Record<string, AppConfig> = {
{ value: 'overview', label: 'Overview', icon: TbChartBar, to: '/apps/desa-plus' }, { value: 'overview', label: 'Overview', icon: TbChartBar, to: '/apps/desa-plus' },
{ value: 'logs', label: 'Log Activity', icon: TbHistory, to: '/apps/desa-plus/logs' }, { value: 'logs', label: 'Log Activity', icon: TbHistory, to: '/apps/desa-plus/logs' },
{ value: 'errors', label: 'Error Reports', icon: TbAlertTriangle, to: '/apps/desa-plus/errors' }, { value: 'errors', label: 'Error Reports', icon: TbAlertTriangle, to: '/apps/desa-plus/errors' },
{ value: 'manage', label: 'Manage', icon: TbSettings, to: '/apps/desa-plus/manage' }, { value: 'villages', label: 'Villages', icon: TbBuilding, to: '/apps/desa-plus/villages' },
], ],
}, },
'e-commerce': { 'e-commerce': {

View File

@@ -1,36 +1,22 @@
import { VillageActivityLineChart, VillageComparisonBarChart } from '@/frontend/components/DashboardCharts'
import { ErrorDataTable } from '@/frontend/components/ErrorDataTable'
import { SummaryCard } from '@/frontend/components/SummaryCard'
import { import {
Badge, ActionIcon,
Button,
Card,
Group, Group,
SimpleGrid, SimpleGrid,
Stack, Stack,
Text, Text,
Title, Title
Paper,
Box,
ThemeIcon,
Select,
ActionIcon,
Container,
Divider,
} from '@mantine/core' } from '@mantine/core'
import { createFileRoute, Link, useParams } from '@tanstack/react-router' import { createFileRoute, useParams } from '@tanstack/react-router'
import { import {
TbUsers, TbActivity,
TbActivity, TbAlertTriangle,
TbRefresh,
TbAlertTriangle,
TbCalendar,
TbFilter,
TbChevronRight,
TbArrowUpRight,
TbBuildingCommunity, TbBuildingCommunity,
TbRefresh,
TbVersions TbVersions
} from 'react-icons/tb' } from 'react-icons/tb'
import { SummaryCard } from '@/frontend/components/SummaryCard'
import { VillageActivityLineChart, VillageComparisonBarChart } from '@/frontend/components/DashboardCharts'
import { ErrorDataTable } from '@/frontend/components/ErrorDataTable'
export const Route = createFileRoute('/apps/$appId/')({ export const Route = createFileRoute('/apps/$appId/')({
component: AppOverviewPage, component: AppOverviewPage,
@@ -43,66 +29,59 @@ function AppOverviewPage() {
return ( return (
<Stack gap="xl"> <Stack gap="xl">
{/* 🔝 HEADER SECTION */} {/* 🔝 HEADER SECTION */}
<Paper withBorder p="lg" radius="2xl" className="glass"> {/* <Paper withBorder p="lg" radius="2xl" className="glass"> */}
<Group justify="space-between"> <Group justify="space-between">
<Stack gap={0}> <Stack gap={0}>
<Title order={2} className="gradient-text" style={{ fontSize: '1.8rem' }}>Overview</Title> <Title order={3}>Overview</Title>
<Group gap="xs" mt={4}> <Text size="sm" c="dimmed">Last updated: Just now</Text>
<Badge variant="light" size="lg" radius="sm" color="brand-blue" leftSection={<TbBuildingCommunity size={14} />}> </Stack>
APP: {isDesaPlus ? 'DESA+' : appId.toUpperCase()}
</Badge>
<Text size="xs" c="dimmed" fw={600}>LAST UPDATED: JUST NOW</Text>
</Group>
</Stack>
<Group gap="md"> <Group gap="md">
<Select {/* <Select
placeholder="Date Range" placeholder="Date Range"
data={['Today', '7 Days', '30 Days']} data={['Today', '7 Days', '30 Days']}
defaultValue="Today" defaultValue="Today"
leftSection={<TbCalendar size={16} />} leftSection={<TbCalendar size={16} />}
radius="md" radius="md"
w={140} w={140}
/> /> */}
<ActionIcon variant="light" color="brand-blue" size="lg" radius="md"> <ActionIcon variant="light" color="brand-blue" size="lg" radius="md">
<TbRefresh size={20} /> <TbRefresh size={20} />
</ActionIcon> </ActionIcon>
<Button {/* <Button
variant="gradient" variant="gradient"
gradient={{ from: '#2563EB', to: '#7C3AED' }} gradient={{ from: '#2563EB', to: '#7C3AED' }}
radius="md" radius="md"
leftSection={<TbFilter size={18} />} leftSection={<TbFilter size={18} />}
> >
Add Filter Add Filter
</Button> </Button> */}
</Group>
</Group> </Group>
</Paper> </Group>
{/* </Paper> */}
{/* 📊 1. SUMMARY CARDS */} {/* 📊 1. SUMMARY CARDS */}
<SimpleGrid cols={{ base: 1, sm: 2, lg: 4 }} spacing="lg"> <SimpleGrid cols={{ base: 1, sm: 2, lg: 4 }} spacing="lg">
<SummaryCard <SummaryCard
title="Active Version" title="Active Version"
value="v1.2.0" value="v1.2.0"
icon={TbVersions} icon={TbVersions}
color="brand-blue" color="brand-blue"
progress={{ value: 92, label: 'User Adoption' }}
/> />
<SummaryCard <SummaryCard
title="Total Activity Today" title="Total Activity Today"
value="3,842" value="3,842"
icon={TbActivity} icon={TbActivity}
color="teal" color="teal"
trend={{ value: '14.2%', positive: true }} trend={{ value: '14.2%', positive: true }}
/> />
<SummaryCard <SummaryCard
title="Total Villages Active" title="Total Villages Active"
value="138" value="138"
icon={TbBuildingCommunity} icon={TbBuildingCommunity}
color="indigo" color="indigo"
progress={{ value: 98, label: 'Integration Health' }}
/> />
<SummaryCard <SummaryCard
title="Errors Today" title="Errors Today"
value="12" value="12"
icon={TbAlertTriangle} icon={TbAlertTriangle}

View File

@@ -2,6 +2,7 @@ import { DashboardLayout } from '@/frontend/components/DashboardLayout'
import { import {
Box, Box,
Container, Container,
Divider,
Group, Group,
Stack, Stack,
Text, Text,
@@ -27,7 +28,7 @@ function AppDetailLayout() {
return ( return (
<DashboardLayout> <DashboardLayout>
<Container size="xl" py="lg"> <Container size="xl" py="lg">
<Stack gap="xl"> <Stack gap="md">
<Group justify="space-between" align="flex-end"> <Group justify="space-between" align="flex-end">
<Stack gap={4}> <Stack gap={4}>
<Title order={1} className="gradient-text" style={{ fontSize: '2.5rem' }}>{appName}</Title> <Title order={1} className="gradient-text" style={{ fontSize: '2.5rem' }}>{appName}</Title>
@@ -35,7 +36,9 @@ function AppDetailLayout() {
</Stack> </Stack>
</Group> </Group>
<Box mt="md"> <Divider />
<Box>
<Outlet /> <Outlet />
</Box> </Box>
</Stack> </Stack>

View File

@@ -34,8 +34,8 @@ import {
} from 'react-icons/tb' } from 'react-icons/tb'
import { StatsCard } from '@/frontend/components/StatsCard' import { StatsCard } from '@/frontend/components/StatsCard'
export const Route = createFileRoute('/apps/$appId/manage')({ export const Route = createFileRoute('/apps/$appId/villages')({
component: AppManagePage, component: AppVillagesPage,
}) })
const mockDevelopers = [ const mockDevelopers = [
@@ -45,7 +45,7 @@ const mockDevelopers = [
{ value: 'rahmat', label: 'Rahmat Hidayat', avatar: null }, { value: 'rahmat', label: 'Rahmat Hidayat', avatar: null },
] ]
function AppManagePage() { function AppVillagesPage() {
const { appId } = useParams({ from: '/apps/$appId' }) const { appId } = useParams({ from: '/apps/$appId' })
const [initModalOpened, { open: openInit, close: closeInit }] = useDisclosure(false) const [initModalOpened, { open: openInit, close: closeInit }] = useDisclosure(false)
const [assignModalOpened, { open: openAssign, close: closeAssign }] = useDisclosure(false) const [assignModalOpened, { open: openAssign, close: closeAssign }] = useDisclosure(false)