diff --git a/apps/admin.saladeaula.digital/app/routes/_.$orgid.enrollments.add/route.tsx b/apps/admin.saladeaula.digital/app/routes/_.$orgid.enrollments.add/route.tsx
index 3157767..0e939ba 100644
--- a/apps/admin.saladeaula.digital/app/routes/_.$orgid.enrollments.add/route.tsx
+++ b/apps/admin.saladeaula.digital/app/routes/_.$orgid.enrollments.add/route.tsx
@@ -7,14 +7,27 @@ import {
CopyIcon,
CopyPlusIcon,
Trash2Icon,
- PlusIcon
+ PlusIcon,
+ XIcon,
+ ChevronsUpDownIcon,
+ CheckIcon
} from 'lucide-react'
import { Link } from 'react-router'
import { Controller, useFieldArray, useForm } from 'react-hook-form'
-import { Fragment, useState } from 'react'
+import { Fragment, use, useMemo, useState } from 'react'
import { format } from 'date-fns'
import { ptBR } from 'react-day-picker/locale'
+import { z } from 'zod'
+import { zodResolver } from '@hookform/resolvers/zod'
+import {
+ Command,
+ CommandEmpty,
+ CommandGroup,
+ CommandInput,
+ CommandItem,
+ CommandList
+} from '@repo/ui/components/ui/command'
import {
Breadcrumb,
BreadcrumbItem,
@@ -47,25 +60,88 @@ import {
} from '@repo/ui/components/ui/popover'
import { Label } from '@repo/ui/components/ui/label'
import { Calendar } from '@repo/ui/components/ui/calendar'
-import { data } from 'react-router'
+import { createSearch } from '@repo/util/meili'
+import { Await } from 'react-router'
+import { cn } from '@repo/ui/lib/utils'
+import Fuse from 'fuse.js'
+
+const enrollment = z.object({
+ user: z
+ .object({
+ id: z.string(),
+ name: z.string(),
+ email: z.string(),
+ cpf: z.string()
+ })
+ .required(),
+ course: z
+ .object({
+ id: z.string(),
+ name: z.string(),
+ access_period: z.number(),
+ unit_price: z.number()
+ })
+ .required(),
+ deduplication_window: z
+ .object({
+ offset_days: z.number()
+ })
+ .optional(),
+ scheduled_for: z.date().optional().nullable()
+})
+
+const formSchema = z.object({
+ enrollments: z.array(enrollment).min(1).max(100)
+})
+
+type Schema = z.infer
+
+const MAX_ITEMS = 100
export function meta({}: Route.MetaArgs) {
return [{ title: 'Adicionar matrĂcula' }]
}
-export default function Route({}: Route.ComponentProps) {
- const form = useForm({ defaultValues: { enrollments: [{}] } })
+export async function loader({ context }: Route.LoaderArgs) {
+ const courses = createSearch({
+ index: 'saladeaula_courses',
+ sort: ['created_at:desc'],
+ filter: 'unlisted NOT EXISTS',
+ hitsPerPage: 100,
+ env: context.cloudflare.env
+ })
+
+ return { courses }
+}
+
+export async function action({}: Route.ActionArgs) {
+ return {}
+}
+
+export default function Route({
+ loaderData: { courses }
+}: Route.ComponentProps) {
+ const form = useForm({
+ resolver: zodResolver(formSchema),
+ defaultValues: {
+ enrollments: [{ user: undefined, course: undefined, scheduled_for: null }]
+ }
+ })
const { formState, control, handleSubmit, getValues } = form
const { fields, insert, remove, append } = useFieldArray({
control,
name: 'enrollments'
})
- const onSubmit = async (data) => {
+ const onSubmit = async (data: Schema) => {
console.log(data)
}
const duplicateRow = (index: number, times: number = 1) => {
+ if (fields.length + times > MAX_ITEMS) {
+ return
+ }
+
const values = getValues(`enrollments.${index}`)
Array.from({ length: times }, (_, i) => {
insert(index + 1 + i, values)
@@ -91,6 +167,9 @@ export default function Route({}: Route.ComponentProps) {
-
-
-
-
-
+
+
+
-
-
+
+
+
diff --git a/apps/saladeaula.digital/app/routes/index.tsx b/apps/saladeaula.digital/app/routes/index.tsx
index 6ffb339..c48b995 100644
--- a/apps/saladeaula.digital/app/routes/index.tsx
+++ b/apps/saladeaula.digital/app/routes/index.tsx
@@ -161,7 +161,7 @@ function List({ s, hits = [] }: { s: string; hits: Enrollment[] }) {
})
}, [hits])
- const hits_ = useMemo(() => {
+ const filtered = useMemo(() => {
if (!s) {
return hits
}
@@ -169,7 +169,7 @@ function List({ s, hits = [] }: { s: string; hits: Enrollment[] }) {
return fuse.search(s).map(({ item }) => item)
}, [s, fuse, hits])
- if (hits_.length === 0) {
+ if (filtered.length === 0) {
return (
@@ -199,7 +199,7 @@ function List({ s, hits = [] }: { s: string; hits: Enrollment[] }) {
return (
- {hits_.map((props: Enrollment, idx) => {
+ {filtered.map((props: Enrollment, idx) => {
return
})}