feat(frontend): add async admin form foundations
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||
import {
|
||||
AlertTriangle,
|
||||
ArrowRight,
|
||||
@@ -10,7 +9,7 @@ import {
|
||||
MessageSquareMore,
|
||||
Smartphone,
|
||||
} from "lucide-react";
|
||||
import SearchableCombobox from "@/components/SearchableCombobox";
|
||||
import AsyncSearchableCombobox from "@/components/AsyncSearchableCombobox";
|
||||
import OtpCodeField from "@/components/OtpCodeField";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
@@ -96,25 +95,23 @@ export default function Auth() {
|
||||
return () => window.clearInterval(timer);
|
||||
}, []);
|
||||
|
||||
const { data: majors = [], isLoading: majorsLoading } = useQuery({
|
||||
queryKey: ["majors"],
|
||||
queryFn: () => api.getMajors(),
|
||||
staleTime: 7 * 24 * 60 * 60 * 1000,
|
||||
});
|
||||
const { data: universities = [], isLoading: universitiesLoading } = useQuery({
|
||||
queryKey: ["universities"],
|
||||
queryFn: () => api.getUniversities(),
|
||||
staleTime: 7 * 24 * 60 * 60 * 1000,
|
||||
});
|
||||
const loadMajors = useCallback(async (params: { search: string; limit: number; offset: number }) => {
|
||||
const data = await api.getMajorsPaged(params);
|
||||
return {
|
||||
count: data.count,
|
||||
results: data.results.map((major) => ({ value: String(major.code), label: major.label })),
|
||||
};
|
||||
}, []);
|
||||
|
||||
const majorItems = useMemo(
|
||||
() => majors.map((major) => ({ value: String(major.code), label: major.label })),
|
||||
[majors],
|
||||
);
|
||||
const universityItems = useMemo(
|
||||
() => universities.map((university) => ({ value: String(university.code), label: university.label })),
|
||||
[universities],
|
||||
);
|
||||
const loadUniversities = useCallback(async (params: { search: string; limit: number; offset: number }) => {
|
||||
const data = await api.getUniversitiesPaged(params);
|
||||
return {
|
||||
count: data.count,
|
||||
results: data.results.map((university) => ({ value: String(university.code), label: university.label })),
|
||||
};
|
||||
}, []);
|
||||
const majorsLoading = false;
|
||||
const universitiesLoading = false;
|
||||
|
||||
const stepMeta = useMemo(() => {
|
||||
switch (step) {
|
||||
@@ -666,14 +663,14 @@ export default function Auth() {
|
||||
{universitiesLoading ? (
|
||||
<div className="h-12 animate-pulse rounded-2xl bg-muted" />
|
||||
) : (
|
||||
<SearchableCombobox
|
||||
items={universityItems}
|
||||
<AsyncSearchableCombobox
|
||||
loadOptions={loadUniversities}
|
||||
value={registerForm.university}
|
||||
onChange={(value) => updateRegisterForm("university", value)}
|
||||
placeholder="انتخاب دانشگاه"
|
||||
searchPlaceholder="نام دانشگاه را بنویسید..."
|
||||
emptyText="دانشگاهی پیدا نشد"
|
||||
dir="rtl"
|
||||
className="h-12 rounded-2xl"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
@@ -684,14 +681,14 @@ export default function Auth() {
|
||||
{majorsLoading ? (
|
||||
<div className="h-12 animate-pulse rounded-2xl bg-muted" />
|
||||
) : (
|
||||
<SearchableCombobox
|
||||
items={majorItems}
|
||||
<AsyncSearchableCombobox
|
||||
loadOptions={loadMajors}
|
||||
value={registerForm.major}
|
||||
onChange={(value) => updateRegisterForm("major", value)}
|
||||
placeholder="انتخاب رشته"
|
||||
searchPlaceholder="نام رشته را بنویسید..."
|
||||
emptyText="رشتهای پیدا نشد"
|
||||
dir="rtl"
|
||||
className="h-12 rounded-2xl"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user