Test yechish platformasining frontend qismi. Next.js 15, TypeScript, shadcn/ui asosida qurilgan to'liq funksional web ilova.
| Texnologiya | Versiya | Maqsad |
|---|---|---|
| Next.js | 15 (App Router) | Frontend framework |
| TypeScript | 5+ | Type safety |
| Tailwind CSS | v4 | Styling |
| shadcn/ui | Radix + Nova preset | UI komponentlar |
| TanStack Query | v5 | Server state, caching, pagination |
| Zustand + persist | latest | Client state (auth user) |
| React Hook Form | latest | Form management |
| Zod | latest | Form validation |
| react-katex + katex | latest | LaTeX formula render |
| js-cookie | latest | Cookie management |
edu-test-frontend/
βββ app/ β Next.js routing (faqat page.tsx lar)
β βββ (auth)/ β Himoyasiz sahifalar (login bo'lsa redirect)
β β βββ login/
β β βββ register/
β β βββ forgot-password/
β β βββ reset-password/
β βββ admin/ β Admin panel (admin, super_admin)
β β βββ layout.tsx β Role-based sidebar (super_admin vs admin)
β β βββ dashboard/
β β βββ subjects/
β β βββ questions/
β β βββ students/
β β βββ sessions/
β β βββ users/ β Faqat super_admin
β β βββ teachers/ β Faqat admin
β βββ teacher/ β Teacher panel
β β βββ layout.tsx
β β βββ dashboard/
β β βββ subjects/
β β βββ questions/
β βββ student/ β Student interfeysi (login shart emas)
β β βββ test/
β β βββ result/
β β βββ results/
β βββ layout.tsx β Root layout (QueryClientProvider)
β βββ page.tsx β Landing page
β βββ providers.tsx β TanStack Query provider
βββ features/ β Business logic (feature-based)
β βββ auth/
β β βββ api/ β auth.api.ts
β β βββ components/ β LoginForm, RegisterForm, ForgotPasswordForm, ResetPasswordForm
β β βββ hooks/ β useLogin, useRegister, useForgotPassword, useResetPassword
β β βββ store/ β auth.store.ts (Zustand β user, role)
β β βββ types/ β auth.types.ts
β βββ students/
β β βββ api/ β students.api.ts
β β βββ components/ β StudentEntryForm, StudentTestPage, StudentResultPage, StudentMyResultsPage
β β βββ hooks/ β useStudentEntry, useStudentTest, useMyResults
β β βββ types/ β student.types.ts
β βββ subjects/
β β βββ api/ β subjects.api.ts
β β βββ hooks/ β useSubjects
β β βββ types/ β subject.types.ts
β βββ teacher/
β β βββ api/ β teacher.api.ts (subjects + questions CRUD + import)
β β βββ components/
β β β βββ dashboard/ β TeacherDashboardPage
β β β βββ subjects/ β TeacherSubjectsPage
β β β βββ questions/ β TeacherQuestionsPage
β β βββ hooks/ β teacher.hooks.ts
β β βββ types/ β teacher.types.ts
β βββ admin/
β β βββ api/ β admin.api.ts (users + students + sessions)
β β βββ components/
β β β βββ dashboard/ β AdminDashboardPage
β β β βββ subjects/ β AdminSubjectsPage
β β β βββ questions/ β AdminQuestionsPage
β β β βββ students/ β AdminStudentsPage
β β β βββ sessions/ β AdminSessionsPage
β β β βββ users/ β AdminUsersPage (super_admin only)
β β β βββ teachers/ β AdminTeachersPage (admin only)
β β βββ hooks/ β admin.hooks.ts
β β βββ types/ β admin.types.ts
β βββ landing/
β βββ components/ β LandingPage
βββ shared/
β βββ components/
β β βββ MathText.tsx β LaTeX formula render
β β βββ panel-layout/ β PanelSidebar, PanelHeader (shared)
β βββ hooks/ β global hooks
β βββ types/ β react-katex.d.ts, global types
βββ components/
β βββ ui/ β shadcn komponentlari (auto-generated)
βββ lib/
β βββ constants.ts β API_URL, ROUTES
β βββ fetcher.ts β Global fetch wrapper (401 β auto refresh)
β βββ query-client.ts β TanStack Query sozlamalari
βββ middleware.ts β Token tekshiruv + rol himoya + auto refresh
| Imkoniyat | super_admin | admin | teacher |
|---|---|---|---|
| Barcha fanlarni ko'rish | β | β | β |
| Fan yaratish/yangilash | β | β | β |
| Fanni inactive qilish | β | β | Faqat o'ziniki |
| Barcha savollarni ko'rish | β | β | Faqat o'ziniki |
| Savol yaratish/yangilash | β | β | β |
| Fayldan savol import | β | β | β |
| Studentlar ro'yxati | β | β | β |
| Studentni bloklash/faollashtirish | β | β | β |
| Sessiyalar statistikasi | β | β | β |
| Teacherlar ro'yxati | β | β | β |
| Foydalanuvchilar CRUD | β | β | β |
/ (landing page)
β
/student β telefon + ism + fan + savol soni + vaqt (daqiqada)
β
check-phone β mavjud user β ism avtomatik to'ldiriladi (readonly)
β
/student/test β savollar + timer + progress bar + javob variantlari
β β
Vaqt tugasa (auto submit) "Testni yakunlash" tugmasi
β
/student/result β natija (foiz, to'g'ri/noto'g'ri, vaqt) + savollar tahlili
β
/student/results β telefon orqali barcha testlar tarixi va statistika
Token saqlash:
access_tokenβhttpOnly cookieda (1 soat)refresh_tokenβhttpOnly cookieda (1 kun)- Frontend tokenlarni ko'rmaydi β barcha so'rovlarda
credentials: 'include'
Auto refresh mexanizmi:
1. middleware.ts β sahifaga kirishda:
access_token expire β GET /auth/refresh (Cookie header bilan)
β Yangi Set-Cookie response β Foydalanuvchi hech narsa sezmaydi
2. fetcher.ts β API so'rovda:
401 kelsa β GET /auth/refresh β Asl so'rovni qayta yuborish
Refresh muvaffaqiyatsiz β / ga redirect
Rol himoyasi (middleware.ts):
| Route | Ruxsat berilgan rollar | Ruxsatsiz bo'lsa |
|---|---|---|
/admin/users |
super_admin | /admin/dashboard |
/admin/* |
admin, super_admin | /teacher/dashboard |
/teacher/* |
teacher | /admin/dashboard |
/login, /register |
Token yo'q | Dashboard ga redirect |
/student/* |
Hamma | β |
Zustand persist:
user(role, fullName, email) localStorage da saqlanadi- Logout β
clearUser()β/ga redirect
Matematik formulalar $...$ formatida saqlanadi va react-katex orqali render qilinadi:
import { MathText } from '@/shared/components/MathText'
<MathText text="$\frac{3}{4}$ kg un kerak" />
// β ΒΎ kg un kerak
<MathText text="Tenglamani yeching: $x^2 - 5x + 6 = 0$" />
// β Tenglamani yeching: xΒ²-5x+6=0MathText komponenti $...$ qismlarini KaTeX orqali, qolganini oddiy matn sifatida render qiladi. Savol matni, javob variantlari va natija sahifasida ishlatiladi.
Savollar backend tomonidan paginate qilinadi:
useQuestions(page: number, limit: number, subjectId?: string)
// queryKey: ['questions', page, limit, subjectId]
// Response: {
// data: Question[],
// meta: { total, page, limit, totalPages, hasNext, hasPrev }
// }Filter o'zgarganda page avtomatik 1 ga reset bo'ladi. Pagination UI list pastida ko'rsatiladi.
Teacher va Admin panellar uchun umumiy layout:
// Har ikki panel bir xil komponentdan foydalanadi
<PanelSidebar title="Teacher Panel" navItems={navItems} />
<PanelHeader pageTitles={pageTitles} />
// Admin layoutda role ga qarab navItems o'zgaradi
const navItems = isSuperAdmin ? superAdminNavItems : adminNavItemsSidebar da: logo, nav links (active state bilan), user info, logout tugmasi.
Barcha API so'rovlar uchun markaziy wrapper:
credentials: 'include'β cookie avtomatik yuboriladi- 401 β auto refresh β retry
- Query params support
- FormData support (fayl yuklash uchun)
git clone https://github.com/username/edu-test-frontend.git
cd edu-test-frontendnpm installNEXT_PUBLIC_API_URL=http://localhost:4000/api# Development
npm run dev
# Production build
npm run build
npm run startDastur http://localhost:3000 da ishga tushadi.
β οΈ Backendhttp://localhost:4000da ishlab turishi kerak. Backend repo: edu-test-backend
| URL | Tavsif | Himoya |
|---|---|---|
/ |
Landing page | Ochiq |
/login |
Tizimga kirish | Ochiq (login bo'lsa redirect) |
/register |
Teacher ro'yxati | Ochiq (login bo'lsa redirect) |
/forgot-password |
Parolni tiklash emaili | Ochiq |
/reset-password?token=... |
Yangi parol kiritish | Ochiq |
/student |
Test boshlash | Ochiq |
/student/test |
Test yechish (timer bilan) | Ochiq |
/student/result |
Test natijasi + tahlil | Ochiq |
/student/results |
Barcha testlar tarixi | Ochiq |
/teacher/dashboard |
Statistika va tezkor harakatlar | teacher |
/teacher/subjects |
Fanlar CRUD | teacher |
/teacher/questions |
Savollar CRUD + import | teacher |
/admin/dashboard |
Kengaytirilgan statistika | admin, super_admin |
/admin/subjects |
Barcha fanlar boshqaruvi | admin, super_admin |
/admin/questions |
Barcha savollar boshqaruvi | admin, super_admin |
/admin/students |
Studentlar + bloklash/faollashtirish | admin, super_admin |
/admin/sessions |
Sessiyalar statistikasi + filter | admin, super_admin |
/admin/teachers |
Teacherlar ro'yxati (readonly) | admin |
/admin/users |
Foydalanuvchilar CRUD | super_admin |
Har bir feature quyidagi tuzilishda bo'ladi:
features/[feature-name]/
βββ api/ β fetcher orqali backend bilan muloqot
βββ components/ β UI komponentlar
βββ hooks/ β TanStack Query hooks (useQuery, useMutation)
βββ store/ β Zustand store (kerak bo'lsa)
βββ types/ β TypeScript interfeyslari
Asosiy qoida: app/ papkasidagi page.tsx faqat feature komponentni chaqiradi β hech qanday logic yo'q:
// app/teacher/subjects/page.tsx
import { TeacherSubjectsPage } from "@/features/teacher/components/subjects/TeacherSubjectsPage";
export default function SubjectsPage() {
return <TeacherSubjectsPage />;
}Import tartibi (dependency chain):
types β api β hooks β components β page.tsx
MIT