finish add enrollment from seat:wqs

This commit is contained in:
2026-01-27 23:13:36 -03:00
parent ecd91dbc5e
commit 6d0d006bb0
9 changed files with 395 additions and 247 deletions

View File

@@ -7,13 +7,7 @@ import {
CheckIcon,
ChevronsUpDownIcon
} from 'lucide-react'
import {
forwardRef,
use,
useMemo,
useState,
type InputHTMLAttributes
} from 'react'
import { forwardRef, useMemo, useState, type InputHTMLAttributes } from 'react'
import { Button } from '@repo/ui/components/ui/button'
import {
@@ -45,7 +39,7 @@ interface CoursePickerProps extends Omit<
'value' | 'onChange'
> {
value?: Course
options: Promise<{ hits: any[] }>
options: any[]
onChange?: (value: any) => void
error?: any
}
@@ -59,12 +53,11 @@ const normalize = (value: string) =>
export const CoursePicker = forwardRef<HTMLInputElement, CoursePickerProps>(
({ value, onChange, options, error, ...props }, ref) => {
const { hits } = use(options)
const [search, setSearch] = useState<string>('')
const [open, { set }] = useToggle()
const [sort, { toggle }] = useToggle('a-z', 'z-a')
const fuse = useMemo(() => {
return new Fuse(hits, {
return new Fuse(options, {
keys: ['name'],
threshold: 0.3,
includeMatches: true,
@@ -73,11 +66,11 @@ export const CoursePicker = forwardRef<HTMLInputElement, CoursePickerProps>(
return typeof value === 'string' ? normalize(value) : value
}
})
}, [hits])
}, [options])
const filtered = useMemo(() => {
if (!search) {
return [...hits].sort((a, b) => {
return [...options].sort((a, b) => {
const comparison = a.name.localeCompare(b.name)
return sort === 'a-z' ? comparison : -comparison
})
@@ -87,7 +80,7 @@ export const CoursePicker = forwardRef<HTMLInputElement, CoursePickerProps>(
...item,
matches
}))
}, [search, fuse, hits, sort])
}, [search, fuse, options, sort])
return (
<Popover open={open} onOpenChange={set}>
@@ -149,13 +142,15 @@ export const CoursePicker = forwardRef<HTMLInputElement, CoursePickerProps>(
name,
access_period,
metadata__unit_price: unit_price,
quantity = null
quantity = null,
disabled = false
}) => {
return (
<CommandItem
key={id}
value={id}
className="cursor-pointer"
disabled={disabled}
onSelect={() => {
onChange?.({
id,

View File

@@ -4,6 +4,7 @@ import { z } from 'zod'
export const MAX_ITEMS = 50
export const enrollment = z.object({
id: z.uuidv4().optional(),
user: z
.object(
{
@@ -34,7 +35,8 @@ export const enrollment = z.object({
scheduled_for: z
.date()
.optional()
.transform((date) => (date ? format(date, 'yyyy-MM-dd') : undefined))
.transform((date) => (date ? format(date, 'yyyy-MM-dd') : undefined)),
seat: z.object({ order_id: z.uuidv4() }).optional()
})
export const formSchema = z.object({

View File

@@ -131,8 +131,9 @@ export async function action({ params, request, context }: Route.ActionArgs) {
}
export default function Route({
loaderData: { courses, submission }
loaderData: { courses: courses_, submission }
}: Route.ComponentProps) {
const { hits: courses } = use(courses_)
const { orgid } = useParams()
const { enrolled } = use(submission)
const fetcher = useFetcher()