add report submission

This commit is contained in:
2025-12-11 20:46:34 -03:00
parent 3fb8488074
commit 1e1a0ae24c
10 changed files with 281 additions and 54 deletions

View File

@@ -0,0 +1,160 @@
import type { Route } from './+types/route'
import { AlertCircleIcon, CheckCircle2Icon, ClockIcon } from 'lucide-react'
import { Link } from 'react-router'
import { Suspense } from 'react'
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle
} from '@repo/ui/components/ui/card'
import {
Breadcrumb,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbList,
BreadcrumbPage,
BreadcrumbSeparator
} from '@repo/ui/components/ui/breadcrumb'
import {
Alert,
AlertDescription,
AlertTitle
} from '@repo/ui/components/ui/alert'
import { request as req } from '@repo/util/request'
import { Skeleton } from '@repo/ui/components/skeleton'
import { Await } from 'react-router'
import { Abbr } from '@repo/ui/components/abbr'
export function meta({}: Route.MetaArgs) {
return [{ title: 'Relatório de matrículas' }]
}
export async function loader({ context, request, params }: Route.LoaderArgs) {
const { orgid, id } = params
const submission = req({
url: `/orgs/${orgid}/enrollments/${id}/submitted`,
context,
request
}).then((r) => r.json())
return {
data: submission
}
}
export default function Route({ loaderData: { data } }: Route.ComponentProps) {
return (
<Suspense fallback={<Skeleton />}>
<div className="space-y-2.5">
<Breadcrumb>
<BreadcrumbList>
<BreadcrumbItem>
<BreadcrumbLink asChild>
<Link to="../enrollments">Matrículas</Link>
</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbLink asChild>
<Link to="../enrollments/add">Adicionar matrículas</Link>
</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbPage>Relatório de matrículas</BreadcrumbPage>
</BreadcrumbItem>
</BreadcrumbList>
</Breadcrumb>
<div className="lg:max-w-4xl mx-auto space-y-2.5">
<Card>
<CardHeader>
<CardTitle className="text-2xl">
Relatório de matrículas
</CardTitle>
<CardDescription>
Resumo detalhado do processamento das matrículas enviadas.
</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
<Await resolve={data}>
{({ enrolled, scheduled }) => {
const succeed = enrolled.filter(
({ status }) => status === 'success'
)
const failed = enrolled.filter(
({ status }) => status === 'fail'
)
// console.log(succeed)
return (
<>
{succeed?.length > 0 && (
<Alert className="text-green-500 *:data-[slot=alert-description]:text-green-500/90">
<CheckCircle2Icon />
<AlertTitle>
Matrículas adicionadas com sucesso.
</AlertTitle>
<AlertDescription>
<ul className="list-decimal list-inside">
{succeed.map(({ output }) => (
<li className="space-x-1">
<Abbr>{output.user.name}</Abbr>
<span>&mdash;</span>
<Abbr>{output.course.name}</Abbr>
</li>
))}
</ul>
</AlertDescription>
</Alert>
)}
{failed?.length > 0 && (
<Alert variant="destructive">
<AlertCircleIcon />
<AlertTitle>Matrículas não processadas.</AlertTitle>
<AlertDescription>
<ul className="list-decimal list-inside">
{failed.map(({ input_record }) => (
<li className="space-x-1">
<Abbr>{input_record.user.name}</Abbr>
<span>&mdash;</span>
<Abbr>{input_record.course.name}</Abbr>
</li>
))}
</ul>
</AlertDescription>
</Alert>
)}
{scheduled?.length && (
<Alert>
<ClockIcon />
<AlertTitle>
Matrículas agendadas. Serão processadas na data
definida.
</AlertTitle>
<AlertDescription>
<ul className="list-decimal list-inside">
<li>...</li>
<li>...</li>
</ul>
</AlertDescription>
</Alert>
)}
</>
)
}}
</Await>
</CardContent>
</Card>
</div>
</div>
</Suspense>
)
}