diff --git a/src/app/[slug]/submit/page.tsx b/src/app/[slug]/submit/page.tsx index 03d297b..846c297 100644 --- a/src/app/[slug]/submit/page.tsx +++ b/src/app/[slug]/submit/page.tsx @@ -2,7 +2,7 @@ import { ProfileForm } from "@/components/Form" import { db } from "@/lib/db" import { getAuthSession } from "@/lib/auth" import { notFound } from "next/navigation" -import { GCED_START } from "@/config" +import { GCED_START, LAST_SEMESTER } from "@/config" interface PageProps { params: { @@ -33,11 +33,13 @@ const page = async ({ params }: PageProps) => { {subject.name} diff --git a/src/app/api/semester/route.ts b/src/app/api/semester/route.ts new file mode 100644 index 0000000..604ab83 --- /dev/null +++ b/src/app/api/semester/route.ts @@ -0,0 +1,21 @@ +import { LAST_SEMESTER } from "@/config" +import { db } from "@/lib/db" + +export async function GET(req: Request) { + const url = new URL(req.url) + const acronym = url.searchParams.get("acronym") + + if (!acronym) return new Response("Invalid query", { status: 400 }) + + const semester = ( + await db.subject.findFirst({ + where: { acronym }, + select: { semester: true }, + }) + )?.semester + if (!semester) return new Response("Subject not found", { status: 404 }) + + const results = semester[0] === "Q" ? parseInt(semester[1]) : LAST_SEMESTER + + return new Response(JSON.stringify(results)) +} diff --git a/src/components/Combobox.tsx b/src/components/Combobox.tsx index b7258ed..2c02287 100644 --- a/src/components/Combobox.tsx +++ b/src/components/Combobox.tsx @@ -1,5 +1,5 @@ import * as React from "react" -import { Check, ChevronsUpDown } from "lucide-react" +import { Check, ChevronsUpDown, Loader2 } from "lucide-react" import { cn } from "@/lib/utils" import { Button } from "@/components/ui/Button" @@ -24,10 +24,12 @@ export function Combobox({ options, value, setValue, + isLoading = false, }: { options: Option[] value: string setValue: Function + isLoading?: boolean }) { const [open, setOpen] = React.useState(false) return ( @@ -43,7 +45,11 @@ export function Combobox({ {value ? options.find((option) => option.value === value)?.label : "Select..."} - + {isLoading ? ( + + ) : ( + + )} diff --git a/src/components/Form.tsx b/src/components/Form.tsx index 3810275..bb5fd16 100644 --- a/src/components/Form.tsx +++ b/src/components/Form.tsx @@ -22,8 +22,8 @@ import { Combobox } from "@/components/Combobox" import { Checkbox } from "@/components/ui/checkbox" import { ApuntsPostCreationRequest } from "@/lib/validators/post" import { uploadFiles } from "@/lib/uploadthing" -import { GCED_START } from "@/config" import Fireworks from "react-canvas-confetti/dist/presets/fireworks" +import useSemesterHook from "@/hooks/use-semester-hook" const formSchema = z.object({ pdf: z.any(), @@ -113,6 +113,7 @@ export function ProfileForm({ const form = useForm({ resolver: zodResolver(formSchema), }) + const { data, isLoading } = useSemesterHook(form.watch("assignatura")) useEffect(() => { if (PreselectedSubject !== "AllSubjects") { form.setValue("assignatura", PreselectedSubject) @@ -296,6 +297,24 @@ export function ProfileForm({ ? (generacio + Math.floor((semester - 1) / 2)).toString() : undefined + useEffect(() => { + if (!isLoading) { + if ( + data === -1 || + data === undefined || + data === null || + !form.watch("assignatura") + ) { + form.setValue("year", "") + } else { + form.setValue( + "year", + (generacio + Math.floor((data - 1) / 2)).toString(), + ) + } + } + }, [data, isLoading]) + // ------------------------------ return (
@@ -320,6 +339,7 @@ export function ProfileForm({ options={tipus_any} value={field.value} setValue={field.onChange} + isLoading={isLoading} /> diff --git a/src/config.ts b/src/config.ts index cd179dc..c86acef 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,2 +1,3 @@ export const INFINITE_SCROLL_PAGINATION_RESULTS = 4 export const GCED_START = 2017 +export const LAST_SEMESTER = 8 diff --git a/src/hooks/use-semester-hook.ts b/src/hooks/use-semester-hook.ts new file mode 100644 index 0000000..467d5d6 --- /dev/null +++ b/src/hooks/use-semester-hook.ts @@ -0,0 +1,32 @@ +import { useState, useEffect } from "react" +import axios from "axios" // You might need to install axios +import { LAST_SEMESTER } from "@/config" + +const useSemesterHook = (subjectAcronym: string) => { + const [data, setData] = useState(LAST_SEMESTER) + const [isLoading, setIsLoading] = useState(false) + + useEffect(() => { + const fetchData = async () => { + setIsLoading(true) + if (subjectAcronym === "") { + setData(-1) + } else { + const response = await axios.get( + `/api/semester?acronym=${subjectAcronym}`, + ) + setData(response.data) + } + setIsLoading(false) + } + + if (subjectAcronym !== null && subjectAcronym !== undefined) { + // Assuming subjectAcronym can be null or undefined initially + fetchData() + } + }, [subjectAcronym]) + + return { data, isLoading, setIsLoading } +} + +export default useSemesterHook diff --git a/src/lib/utils.ts b/src/lib/utils.ts index a199a3f..1a8cbf8 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -2,6 +2,8 @@ import { ClassValue, clsx } from "clsx" import { twMerge } from "tailwind-merge" import { formatDistanceToNowStrict } from "date-fns" import locale from "date-fns/locale/en-US" +import { db } from "./db" +import { LAST_SEMESTER } from "@/config" export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs))