share route itens
This commit is contained in:
@@ -24,8 +24,7 @@ import {
|
||||
import { Progress } from '@repo/ui/components/ui/progress'
|
||||
import { Spinner } from '@repo/ui/components/ui/spinner'
|
||||
import { cn, initials } from '@repo/ui/lib/utils'
|
||||
|
||||
import { labels, statuses } from './data'
|
||||
import { labels, statuses } from '@repo/ui/routes/enrollments/data'
|
||||
|
||||
// This type is used to define the shape of our data.
|
||||
// You can use a Zod schema here if you want.
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
import {
|
||||
CircleCheckIcon,
|
||||
CircleIcon,
|
||||
CircleOffIcon,
|
||||
CircleXIcon,
|
||||
TimerIcon,
|
||||
type LucideIcon
|
||||
} from 'lucide-react'
|
||||
|
||||
export const statuses: Record<
|
||||
string,
|
||||
{ icon: LucideIcon; color?: string; label: string }
|
||||
> = {
|
||||
PENDING: {
|
||||
icon: CircleIcon,
|
||||
label: 'Não iniciado'
|
||||
},
|
||||
IN_PROGRESS: {
|
||||
icon: TimerIcon,
|
||||
color: 'text-blue-400 [&_svg]:text-blue-500',
|
||||
label: 'Em andamento'
|
||||
},
|
||||
COMPLETED: {
|
||||
icon: CircleCheckIcon,
|
||||
color: 'text-green-400 [&_svg]:text-background [&_svg]:fill-green-500',
|
||||
label: 'Concluído'
|
||||
},
|
||||
FAILED: {
|
||||
icon: CircleXIcon,
|
||||
color: 'text-red-400 [&_svg]:text-red-500',
|
||||
label: 'Reprovado'
|
||||
},
|
||||
CANCELED: {
|
||||
icon: CircleOffIcon,
|
||||
color: 'text-orange-400 [&_svg]:text-orange-500',
|
||||
label: 'Cancelado'
|
||||
}
|
||||
}
|
||||
|
||||
export const labels: Record<string, string> = {
|
||||
PENDING: 'Não iniciado',
|
||||
IN_PROGRESS: 'Em andamento',
|
||||
COMPLETED: 'Concluído',
|
||||
FAILED: 'Reprovado',
|
||||
CANCELED: 'Cancelado'
|
||||
}
|
||||
|
||||
export const sortings: Record<string, string> = {
|
||||
created_at: 'Cadastrado em',
|
||||
started_at: 'Iniciado em',
|
||||
completed_at: 'Concluído em',
|
||||
failed_at: 'Reprovado em',
|
||||
canceled_at: 'Cancelado em'
|
||||
}
|
||||
|
||||
export const headers = {
|
||||
id: 'ID',
|
||||
'user.name': 'Nome',
|
||||
'user.email': 'Email',
|
||||
'user.cpf': 'CPF',
|
||||
'course.name': 'Curso',
|
||||
status: 'Status',
|
||||
progress: 'Progresso',
|
||||
created_at: 'Cadastrado em',
|
||||
started_at: 'Iniciado em',
|
||||
completed_at: 'Concluído em',
|
||||
failed_at: 'Reprovado em',
|
||||
canceled_at: 'Cancelado em'
|
||||
}
|
||||
@@ -31,8 +31,8 @@ import {
|
||||
import { Kbd } from '@repo/ui/components/ui/kbd'
|
||||
import { createSearch } from '@repo/util/meili'
|
||||
|
||||
import { headers, sortings, statuses } from '@repo/ui/routes/enrollments/data'
|
||||
import { columns, type Enrollment } from './columns'
|
||||
import { headers, sortings, statuses } from './data'
|
||||
|
||||
export function meta({}: Route.MetaArgs) {
|
||||
return [{ title: 'Matrículas' }]
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
'use client'
|
||||
|
||||
import { columns as columns_, type Order } from '@repo/ui/routes/orders/columns'
|
||||
|
||||
import { formatCNPJ, formatCPF } from '@brazilian-utils/brazilian-utils'
|
||||
import { type ColumnDef } from '@tanstack/react-table'
|
||||
|
||||
@@ -7,23 +9,7 @@ import { Abbr } from '@repo/ui/components/abbr'
|
||||
import { Avatar, AvatarFallback } from '@repo/ui/components/ui/avatar'
|
||||
import { initials } from '@repo/ui/lib/utils'
|
||||
|
||||
// This type is used to define the shape of our data.
|
||||
// You can use a Zod schema here if you want.
|
||||
export type Order = {
|
||||
id: string
|
||||
total: number
|
||||
status: 'pending' | 'processing' | 'success' | 'failed'
|
||||
payment_method: 'PIX' | 'CREDIT_CARD' | 'MANUAL' | 'failed'
|
||||
name: string
|
||||
}
|
||||
|
||||
const formatted = new Intl.DateTimeFormat('pt-BR', {
|
||||
day: '2-digit',
|
||||
month: '2-digit',
|
||||
year: 'numeric',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit'
|
||||
})
|
||||
export type { Order }
|
||||
|
||||
export const columns: ColumnDef<Order>[] = [
|
||||
{
|
||||
@@ -65,54 +51,5 @@ export const columns: ColumnDef<Order>[] = [
|
||||
return <></>
|
||||
}
|
||||
},
|
||||
{
|
||||
accessorKey: 'payment_method',
|
||||
header: 'Forma de pag.'
|
||||
},
|
||||
{
|
||||
accessorKey: 'status',
|
||||
header: 'Status'
|
||||
},
|
||||
{
|
||||
accessorKey: 'total',
|
||||
header: 'Valor total',
|
||||
cell: ({ row }) => {
|
||||
const amount = parseFloat(row.getValue('total'))
|
||||
const formatted = new Intl.NumberFormat('pt-BR', {
|
||||
style: 'currency',
|
||||
currency: 'BRL'
|
||||
}).format(amount)
|
||||
|
||||
return <div className="font-medium">{formatted}</div>
|
||||
}
|
||||
},
|
||||
{
|
||||
header: 'Comprado em',
|
||||
cell: ({ row }) => {
|
||||
const createdAt = new Date(row.original.create_date)
|
||||
return formatted.format(createdAt)
|
||||
}
|
||||
},
|
||||
{
|
||||
header: 'Vencimento em',
|
||||
cell: ({ row }) => {
|
||||
try {
|
||||
const dueDate = new Date(row.original.due_date)
|
||||
return formatted.format(dueDate)
|
||||
} catch {
|
||||
return 'N/A'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
header: 'Pago em',
|
||||
cell: ({ row }) => {
|
||||
if (row.original.payment_date) {
|
||||
const createdAt = new Date(row.original.payment_date)
|
||||
return formatted.format(createdAt)
|
||||
}
|
||||
|
||||
return <></>
|
||||
}
|
||||
}
|
||||
...columns_
|
||||
]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { Route } from './+types'
|
||||
import type { Route } from './+types/route'
|
||||
|
||||
import { Suspense } from 'react'
|
||||
import { Await } from 'react-router'
|
||||
@@ -16,12 +16,13 @@ export function meta({}: Route.MetaArgs) {
|
||||
export async function loader({ context, request }: Route.LoaderArgs) {
|
||||
const { searchParams } = new URL(request.url)
|
||||
const page = Number(searchParams.get('p')) + 1
|
||||
const sort = searchParams.get('sort') || 'create_date:desc'
|
||||
const hitsPerPage = Number(searchParams.get('perPage')) || 25
|
||||
|
||||
return {
|
||||
data: createSearch({
|
||||
index: 'betaeducacao-prod-orders',
|
||||
sort: ['create_date:desc'],
|
||||
sort: [sort],
|
||||
page,
|
||||
hitsPerPage,
|
||||
env: context.cloudflare.env
|
||||
|
||||
@@ -40,7 +40,7 @@ export default function Route({ loaderData }: Route.ComponentProps) {
|
||||
px-4 py-2 lg:py-4 sticky top-0 z-5
|
||||
md:rounded-t-2xl"
|
||||
>
|
||||
<div className="container mx-auto flex items-center">
|
||||
<div className="container mx-auto flex items-center max-w-7xl">
|
||||
<SidebarTrigger className="md:hidden" />
|
||||
<ThemedImage className="max-md:hidden flex gap-1">
|
||||
<span className="text-muted-foreground text-xs">Insights</span>
|
||||
@@ -54,7 +54,7 @@ export default function Route({ loaderData }: Route.ComponentProps) {
|
||||
</header>
|
||||
|
||||
<div className="p-4">
|
||||
<div className="container mx-auto relative">
|
||||
<div className="container mx-auto relative max-w-7xl">
|
||||
<Outlet />
|
||||
<Toaster
|
||||
position="top-center"
|
||||
|
||||
Reference in New Issue
Block a user