import type { Route } from './+types' import { CalendarIcon, PlusCircleIcon } from 'lucide-react' import { MeiliSearchFilterBuilder } from 'meilisearch-helper' import { Suspense, useState } from 'react' import { Await, Outlet, useSearchParams } from 'react-router' import { DataTable, DataTableViewOptions } from '@repo/ui/components/data-table' import { FacetedFilter } from '@repo/ui/components/faceted-filter' import { RangeCalendarFilter } from '@repo/ui/components/range-calendar-filter' import { SearchForm } from '@repo/ui/components/search-form' import { Skeleton } from '@repo/ui/components/skeleton' import { Kbd } from '@repo/ui/components/ui/kbd' import { ExportMenu } from '@repo/ui/components/export-menu' import { createSearch } from '@repo/util/meili' import { headers, sortings, statuses } from '@repo/ui/routes/enrollments/data' import { columns, type Enrollment } from './columns' export function meta({}: Route.MetaArgs) { return [{ title: 'Matrículas' }] } export async function loader({ context, request }: Route.LoaderArgs) { const { searchParams } = new URL(request.url) const query = searchParams.get('q') || '' const from = searchParams.get('from') const to = searchParams.get('to') const sort = searchParams.get('sort') || 'created_at:desc' const status = searchParams.get('status') const page = Number(searchParams.get('p')) + 1 const hitsPerPage = Number(searchParams.get('perPage')) || 25 let builder = new MeiliSearchFilterBuilder() if (status) { builder = builder.where('status', 'in', status.split(',')) } if (from && to) { const [field, from_] = from.split(':') builder = builder.where(field, 'between', [from_, to]) } return { data: createSearch({ index: 'betaeducacao-prod-enrollments', filter: builder.build(), sort: [sort], query, page, hitsPerPage, env: context.cloudflare.env }) } } const formatted = new Intl.DateTimeFormat('en-CA', { year: 'numeric', month: '2-digit', day: '2-digit' }) export default function Route({ loaderData: { data } }) { const [searchParams, setSearchParams] = useSearchParams() const [selectedRows, setSelectedRows] = useState([]) const status = searchParams.get('status') const rangeParams = useRangeParams() return ( }>

Matrículas

{({ hits, page, hitsPerPage, totalHits }) => (
{selectedRows.length ? ( <>
) : ( <>
Digite / para pesquisar } onChange={(value) => setSearchParams((searchParams) => { searchParams.set('q', String(value)) searchParams.delete('p') return searchParams }) } />
{ setSearchParams((searchParams) => { searchParams.delete('status') searchParams.delete('p') if (statuses.length) { searchParams.set('status', statuses.join(',')) } return searchParams }) }} options={Object.entries(statuses).map( ([key, value]) => ({ value: key, ...value }) )} /> ({ value, label }) )} onChange={(props) => { setSearchParams((searchParams) => { if (!props) { searchParams.delete('from') searchParams.delete('to') return searchParams } const { rangeField, dateRange } = props searchParams.set( 'from', `${rangeField}:${formatted.format(dateRange?.from)}` ) searchParams.set( 'to', formatted.format(dateRange?.to) ) return searchParams }) }} />
)}
)}
) } function useRangeParams() { const [searchParams] = useSearchParams() const [from, to] = [searchParams.get('from'), searchParams.get('to')] if (!from || !to) { return {} } const [rangeField, from_] = from.split(':') return { rangeField, dateRange: { from: new Date(from_), to: new Date(to) } } }