update table

This commit is contained in:
2025-12-13 00:14:24 -03:00
parent 72f049babd
commit a1c0e3dcd5
6 changed files with 191 additions and 95 deletions

View File

@@ -2,12 +2,11 @@ import type { Route } from './+types/route'
import { DateTime } from 'luxon'
import { Suspense } from 'react'
import { ClockIcon } from 'lucide-react'
import { BanIcon } from 'lucide-react'
import { request as req } from '@repo/util/request'
import { Skeleton } from '@repo/ui/components/skeleton'
import { Await } from 'react-router'
import { billingPeriod, formatDate } from './util'
import { Card, CardContent } from '@repo/ui/components/ui/card'
import {
Table,
@@ -20,10 +19,18 @@ import {
} from '@repo/ui/components/ui/table'
import { Abbr } from '@repo/ui/components/abbr'
import { Button } from '@repo/ui/components/ui/button'
import { cn } from '@repo/ui/lib/utils'
import {
Empty,
EmptyDescription,
EmptyHeader,
EmptyMedia,
EmptyTitle
} from '@repo/ui/components/ui/empty'
import { billingPeriod, formatDate } from './util'
import { RangePeriod } from './range-period'
import { statuses } from './data'
import { cn } from '@repo/ui/lib/utils'
export function meta({}) {
return [{ title: 'Resumo de cobranças' }]
@@ -81,9 +88,16 @@ export default function Route({
label: status,
color
} = statuses?.[billing?.status || 'CLOSED']
const charges = items
?.filter((item) => 'course' in item && item?.unit_price > 0)
?.sort(sortBy('enrolled_at'))
const credits = items
?.filter((item) => 'course' in item && item?.unit_price < 0)
?.sort(sortBy('created_at'))
return (
<Card>
<CardContent className="space-y-2.5">
<CardContent className="space-y-4">
<div className="flex max-lg:flex-col gap-2.5">
<Button
className={cn('pointer-events-none', color)}
@@ -98,82 +112,148 @@ export default function Route({
<RangePeriod
startDate={startDate}
endDate={endDate}
billingDay={subscription.billing_day || 1}
billingDay={subscription?.billing_day || 1}
/>
</div>
<Table className="table-auto w-full">
<TableHeader>
<TableRow className="hover:bg-transparent">
<TableHead>Colaborador</TableHead>
<TableHead>Curso</TableHead>
<TableHead>Matriculado por</TableHead>
<TableHead>Matriculado em</TableHead>
<TableHead>Valor unit.</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{items
?.filter((item) => 'course' in item)
?.map(
(
{
user,
course,
author: created_by,
unit_price,
enrolled_at
},
index
) => (
<TableRow key={index}>
<TableCell>
<Abbr>{user.name}</Abbr>
</TableCell>
<TableCell>
<Abbr>{course.name}</Abbr>
</TableCell>
<TableCell>
<Abbr>
{created_by ? created_by.name : 'N/A'}
</Abbr>
</TableCell>
<TableCell>
{datetime.format(new Date(enrolled_at))}
</TableCell>
<TableCell>
{currency.format(unit_price)}
</TableCell>
</TableRow>
)
)}
{items.length ? (
<>
<Table className="table-auto w-full">
{charges.length ? (
<>
<TableHeader>
<TableRow className="bg-muted-foreground/15 pointer-events-none">
<TableHead>Colaborador</TableHead>
<TableHead>Curso</TableHead>
<TableHead>Matriculado por</TableHead>
<TableHead>Matriculado em</TableHead>
<TableHead>Valor unit.</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{charges?.map(
(
{
user,
course,
author: created_by,
unit_price,
enrolled_at
},
index
) => (
<TableRow key={index}>
<TableCell>
<Abbr>{user.name}</Abbr>
</TableCell>
<TableCell>
<Abbr>{course.name}</Abbr>
</TableCell>
<TableCell>
<Abbr>
{created_by ? created_by.name : 'N/A'}
</Abbr>
</TableCell>
<TableCell>
{datetime.format(new Date(enrolled_at))}
</TableCell>
<TableCell>
{currency.format(unit_price)}
</TableCell>
</TableRow>
)
)}
</TableBody>
</>
) : null}
{items.length === 0 && (
<TableRow className="hover:bg-transparent">
<TableCell colSpan={5} className="h-24 text-center">
Nenhum resultado.
</TableCell>
</TableRow>
)}
</TableBody>
<TableFooter>
<TableRow className="hover:bg-transparent">
<TableCell colSpan={4} className="text-right">
Total
</TableCell>
<TableCell>
{currency.format(
items
?.filter((item) => 'course' in item)
?.reduce(
(acc, { unit_price }) => acc + unit_price,
0
)
)}
</TableCell>
</TableRow>
</TableFooter>
</Table>
{credits.length ? (
<>
<TableRow className="pointer-events-none">
<TableCell colSpan={5}></TableCell>
</TableRow>
<TableHeader>
<TableRow className="bg-muted-foreground/15 pointer-events-none">
<TableHead>Colaborador</TableHead>
<TableHead>Curso</TableHead>
<TableHead>Cancelado por</TableHead>
<TableHead>Cancelado em</TableHead>
<TableHead>Valor unit.</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{credits?.map(
(
{
user,
course,
author: canceled_by,
unit_price,
created_at
},
index
) => (
<TableRow key={index}>
<TableCell>
<Abbr>{user.name}</Abbr>
</TableCell>
<TableCell>
<Abbr>{course.name}</Abbr>
</TableCell>
<TableCell>
<Abbr>
{canceled_by ? canceled_by.name : 'N/A'}
</Abbr>
</TableCell>
<TableCell>
{datetime.format(new Date(created_at))}
</TableCell>
<TableCell>
{currency.format(unit_price)}
</TableCell>
</TableRow>
)
)}
</TableBody>
</>
) : null}
<TableFooter>
<TableRow>
<TableCell
colSpan={4}
className="text-right pointer-events-none"
>
Total
</TableCell>
<TableCell>
{currency.format(
items
?.filter((x) => 'course' in x)
.reduce(
(acc, { unit_price }) => acc + unit_price,
0
)
)}
</TableCell>
</TableRow>
</TableFooter>
</Table>
</>
) : (
<Empty className="border border-dashed">
<EmptyHeader>
<EmptyMedia variant="icon">
<BanIcon />
</EmptyMedia>
<EmptyTitle>Nenhuma cobrança encontrada</EmptyTitle>
<EmptyDescription>
Não nenhuma cobrança para este período.
</EmptyDescription>
</EmptyHeader>
</Empty>
)}
</CardContent>
</Card>
)
@@ -195,3 +275,6 @@ const datetime = new Intl.DateTimeFormat('pt-BR', {
hour: '2-digit',
minute: '2-digit'
})
const sortBy = (field: 'enrolled_at' | 'created_at') => (a: any, b: any) =>
new Date(a[field]).getTime() - new Date(b[field]).getTime()