fix: design
This commit is contained in:
@@ -37,53 +37,95 @@ export const adminCourseTemplates = [
|
||||
},
|
||||
]
|
||||
|
||||
// Offered courses carry both the spec keys (term_id/teacher_id/
|
||||
// description/capacity/is_active/cover_url) and the UI-only keys the
|
||||
// current frontend reads (image, template/templateId, term/teacher
|
||||
// nested objects, prerequisitesCount, startDate, endDate). See
|
||||
// docs/backend-api-todo.md.
|
||||
const makeTeacherSnapshot = (overrides) => ({
|
||||
id: overrides.id,
|
||||
// --- spec ---
|
||||
name: overrides.name ?? `${overrides.firstName ?? ''} ${overrides.lastName ?? ''}`.trim(),
|
||||
email: overrides.email ?? '',
|
||||
phone: overrides.phone ?? null,
|
||||
roles: overrides.roles ?? ['teacher'],
|
||||
avatarUrl: overrides.avatarUrl ?? null,
|
||||
avatarDownloadUrl: overrides.avatarDownloadUrl ?? null,
|
||||
createdAt: overrides.createdAt ?? '',
|
||||
// --- ui-only ---
|
||||
firstName: overrides.firstName ?? '',
|
||||
lastName: overrides.lastName ?? '',
|
||||
fullName:
|
||||
overrides.fullName ?? `${overrides.firstName ?? ''} ${overrides.lastName ?? ''}`.trim(),
|
||||
})
|
||||
|
||||
export const adminOfferedCourses = [
|
||||
{
|
||||
// --- spec ---
|
||||
id: 11,
|
||||
termId: 1,
|
||||
teacherId: 5,
|
||||
title: 'اصول اخلاق اسلامی - پاییز',
|
||||
description: 'دوره مقدماتی اخلاق اسلامی برای ترم پاییز.',
|
||||
capacity: 30,
|
||||
isActive: true,
|
||||
coverUrl: 'https://picsum.photos/seed/offered1/200/200',
|
||||
|
||||
// --- ui-only ---
|
||||
image: 'https://picsum.photos/seed/offered1/200/200',
|
||||
template: { id: 1, title: 'اصول اخلاق اسلامی' },
|
||||
templateId: 1,
|
||||
term: { id: 1, title: 'ترم پاییز ۱۴۰۴' },
|
||||
termId: 1,
|
||||
teacher: { id: 5, firstName: 'علی', lastName: 'حسنی', fullName: 'علی حسنی' },
|
||||
capacity: 30,
|
||||
isActive: true,
|
||||
teacher: makeTeacherSnapshot({ id: 5, firstName: 'علی', lastName: 'حسنی' }),
|
||||
prerequisitesCount: 0,
|
||||
startDate: '2025-09-23T00:00:00.000Z',
|
||||
endDate: '2025-11-20T00:00:00.000Z',
|
||||
createdAt: '2025-09-01T08:00:00.000Z',
|
||||
},
|
||||
{
|
||||
// --- spec ---
|
||||
id: 12,
|
||||
termId: 1,
|
||||
teacherId: 6,
|
||||
title: 'مفاهیم قرآنی - پاییز',
|
||||
description: 'مرور مفاهیم قرآنی به همراه تفسیر مختصر.',
|
||||
capacity: 25,
|
||||
isActive: true,
|
||||
coverUrl: 'https://picsum.photos/seed/offered2/200/200',
|
||||
|
||||
// --- ui-only ---
|
||||
image: 'https://picsum.photos/seed/offered2/200/200',
|
||||
template: { id: 2, title: 'مفاهیم قرآنی' },
|
||||
templateId: 2,
|
||||
term: { id: 1, title: 'ترم پاییز ۱۴۰۴' },
|
||||
termId: 1,
|
||||
teacher: { id: 6, firstName: 'حسین', lastName: 'مرادی', fullName: 'حسین مرادی' },
|
||||
capacity: 25,
|
||||
isActive: true,
|
||||
teacher: makeTeacherSnapshot({ id: 6, firstName: 'حسین', lastName: 'مرادی' }),
|
||||
prerequisitesCount: 1,
|
||||
startDate: '2025-10-01T00:00:00.000Z',
|
||||
endDate: '2025-12-15T00:00:00.000Z',
|
||||
createdAt: '2025-09-10T08:00:00.000Z',
|
||||
},
|
||||
{
|
||||
// --- spec ---
|
||||
id: 13,
|
||||
termId: 2,
|
||||
teacherId: 7,
|
||||
title: 'فقه عبادات - زمستان',
|
||||
description: 'مرور احکام عملی نماز و روزه برای ترم زمستان.',
|
||||
capacity: 20,
|
||||
isActive: false,
|
||||
coverUrl: '',
|
||||
|
||||
// --- ui-only ---
|
||||
image: '',
|
||||
template: { id: 3, title: 'فقه عبادات' },
|
||||
templateId: 3,
|
||||
term: { id: 2, title: 'ترم زمستان ۱۴۰۴' },
|
||||
termId: 2,
|
||||
teacher: { id: 7, firstName: 'مهدی', lastName: 'سهرابی', fullName: 'مهدی سهرابی' },
|
||||
capacity: 20,
|
||||
isActive: false,
|
||||
teacher: makeTeacherSnapshot({ id: 7, firstName: 'مهدی', lastName: 'سهرابی' }),
|
||||
prerequisitesCount: 0,
|
||||
startDate: '2026-01-22T00:00:00.000Z',
|
||||
endDate: '2026-03-15T00:00:00.000Z',
|
||||
createdAt: '2025-12-10T08:00:00.000Z',
|
||||
},
|
||||
]
|
||||
|
||||
export { makeTeacherSnapshot }
|
||||
|
||||
@@ -1,6 +1,50 @@
|
||||
// Maps the FE's 7-value `sessionType` to the spec's 3-value `type`.
|
||||
const SESSION_TYPE_TO_SPEC = {
|
||||
in_person: 'offline',
|
||||
online: 'online',
|
||||
video: 'content',
|
||||
audio: 'content',
|
||||
text: 'content',
|
||||
slide: 'content',
|
||||
pdf: 'content',
|
||||
}
|
||||
|
||||
const makeSession = (overrides) => {
|
||||
const sessionType = overrides.sessionType ?? ''
|
||||
const sessionConfig = overrides.sessionConfig ?? {}
|
||||
const startsAt = overrides.startsAt ?? sessionConfig.startTime ?? null
|
||||
const location = overrides.location ?? sessionConfig.location ?? null
|
||||
const link = overrides.link ?? sessionConfig.meetingLink ?? null
|
||||
return {
|
||||
// --- spec ---
|
||||
id: overrides.id,
|
||||
courseId: overrides.courseId ?? null,
|
||||
title: overrides.title ?? '',
|
||||
description: overrides.description ?? '',
|
||||
type: overrides.type ?? SESSION_TYPE_TO_SPEC[sessionType] ?? null,
|
||||
startsAt,
|
||||
location,
|
||||
link,
|
||||
media: overrides.media ?? [],
|
||||
|
||||
// --- ui-only ---
|
||||
image: overrides.image ?? '',
|
||||
courseTemplate: overrides.courseTemplate ?? null,
|
||||
sessionType,
|
||||
sessionTypeFa: overrides.sessionTypeFa ?? '',
|
||||
durationMinutes: overrides.durationMinutes ?? 0,
|
||||
order: overrides.order ?? 1,
|
||||
sessionConfig,
|
||||
materials: overrides.materials ?? [],
|
||||
usedInTerms: overrides.usedInTerms ?? [],
|
||||
createdAt: overrides.createdAt ?? '',
|
||||
}
|
||||
}
|
||||
|
||||
export const adminSessions = [
|
||||
{
|
||||
makeSession({
|
||||
id: 101,
|
||||
courseId: 11,
|
||||
title: 'مقدمهای بر اخلاق اسلامی',
|
||||
description: 'جلسه نخست؛ تعاریف و چارچوب دوره.',
|
||||
image: 'https://picsum.photos/seed/session1/200/200',
|
||||
@@ -13,15 +57,14 @@ export const adminSessions = [
|
||||
startTime: '2025-09-25T16:00:00.000Z',
|
||||
location: 'سالن آمفیتئاتر ۲ - مدرسه قم',
|
||||
},
|
||||
materials: [],
|
||||
usedInTerms: [{ termId: 1 }],
|
||||
createdAt: '2025-09-10T08:00:00.000Z',
|
||||
},
|
||||
{
|
||||
}),
|
||||
makeSession({
|
||||
id: 102,
|
||||
courseId: 12,
|
||||
title: 'تفسیر سوره حمد',
|
||||
description: 'تحلیل آیات سوره حمد.',
|
||||
image: '',
|
||||
courseTemplate: { id: 2, title: 'مفاهیم قرآنی' },
|
||||
sessionType: 'online',
|
||||
sessionTypeFa: 'آنلاین',
|
||||
@@ -32,15 +75,14 @@ export const adminSessions = [
|
||||
platform: 'google_meet',
|
||||
startTime: '2025-10-04T19:00:00.000Z',
|
||||
},
|
||||
materials: [],
|
||||
usedInTerms: [{ termId: 1 }],
|
||||
createdAt: '2025-09-25T08:00:00.000Z',
|
||||
},
|
||||
{
|
||||
}),
|
||||
makeSession({
|
||||
id: 103,
|
||||
courseId: 13,
|
||||
title: 'احکام نماز جماعت',
|
||||
description: 'مرور احکام و شرایط نماز جماعت.',
|
||||
image: '',
|
||||
courseTemplate: { id: 3, title: 'فقه عبادات' },
|
||||
sessionType: 'video',
|
||||
sessionTypeFa: 'ویدئو',
|
||||
@@ -50,12 +92,12 @@ export const adminSessions = [
|
||||
minWatchedPercent: 80,
|
||||
mustCompleteBeforeNext: true,
|
||||
},
|
||||
materials: [],
|
||||
usedInTerms: [],
|
||||
createdAt: '2026-01-12T08:00:00.000Z',
|
||||
},
|
||||
}),
|
||||
]
|
||||
|
||||
export { makeSession, SESSION_TYPE_TO_SPEC }
|
||||
|
||||
export const sessionAttendance = new Map([
|
||||
[
|
||||
101,
|
||||
|
||||
@@ -1,42 +1,72 @@
|
||||
// Each term carries both the spec keys (title/description/is_active/
|
||||
// starts_at/ends_at/cover_url/created_at — camelized) and the UI-only
|
||||
// keys the current frontend reads (image, startDate, endDate,
|
||||
// studentsCount, coursesCount). See docs/backend-api-todo.md.
|
||||
const makeTerm = (overrides) => {
|
||||
const startsAt = overrides.startsAt ?? overrides.startDate ?? ''
|
||||
const endsAt = overrides.endsAt ?? overrides.endDate ?? ''
|
||||
const coverUrl = overrides.coverUrl ?? overrides.image ?? ''
|
||||
return {
|
||||
// --- spec ---
|
||||
id: overrides.id,
|
||||
title: overrides.title ?? '',
|
||||
description: overrides.description ?? '',
|
||||
isActive: overrides.isActive ?? true,
|
||||
startsAt,
|
||||
endsAt,
|
||||
coverUrl,
|
||||
createdAt: overrides.createdAt ?? '',
|
||||
|
||||
// --- ui-only ---
|
||||
image: coverUrl,
|
||||
startDate: startsAt,
|
||||
endDate: endsAt,
|
||||
studentsCount: overrides.studentsCount ?? 0,
|
||||
coursesCount: overrides.coursesCount ?? 0,
|
||||
}
|
||||
}
|
||||
|
||||
export const adminTerms = [
|
||||
{
|
||||
makeTerm({
|
||||
id: 1,
|
||||
title: 'ترم پاییز ۱۴۰۴',
|
||||
description: 'ترم پاییز با محوریت آموزش معارف اسلامی.',
|
||||
image: 'https://picsum.photos/seed/term1/200/200',
|
||||
startDate: '2025-09-23T00:00:00.000Z',
|
||||
endDate: '2026-01-20T00:00:00.000Z',
|
||||
coverUrl: 'https://picsum.photos/seed/term1/200/200',
|
||||
startsAt: '2025-09-23T00:00:00.000Z',
|
||||
endsAt: '2026-01-20T00:00:00.000Z',
|
||||
isActive: true,
|
||||
studentsCount: 18,
|
||||
coursesCount: 4,
|
||||
createdAt: '2025-08-01T08:00:00.000Z',
|
||||
},
|
||||
{
|
||||
}),
|
||||
makeTerm({
|
||||
id: 2,
|
||||
title: 'ترم زمستان ۱۴۰۴',
|
||||
description: 'ترم زمستان با تمرکز بر فقه و اصول.',
|
||||
image: 'https://picsum.photos/seed/term2/200/200',
|
||||
startDate: '2026-01-21T00:00:00.000Z',
|
||||
endDate: '2026-04-20T00:00:00.000Z',
|
||||
coverUrl: 'https://picsum.photos/seed/term2/200/200',
|
||||
startsAt: '2026-01-21T00:00:00.000Z',
|
||||
endsAt: '2026-04-20T00:00:00.000Z',
|
||||
isActive: true,
|
||||
studentsCount: 12,
|
||||
coursesCount: 3,
|
||||
createdAt: '2025-11-10T08:00:00.000Z',
|
||||
},
|
||||
{
|
||||
}),
|
||||
makeTerm({
|
||||
id: 3,
|
||||
title: 'ترم بهار ۱۴۰۵',
|
||||
description: 'ترم بهار ویژه دورههای تخصصی.',
|
||||
image: '',
|
||||
startDate: '2026-04-21T00:00:00.000Z',
|
||||
endDate: '2026-08-21T00:00:00.000Z',
|
||||
coverUrl: '',
|
||||
startsAt: '2026-04-21T00:00:00.000Z',
|
||||
endsAt: '2026-08-21T00:00:00.000Z',
|
||||
isActive: false,
|
||||
studentsCount: 0,
|
||||
coursesCount: 2,
|
||||
createdAt: '2026-02-15T08:00:00.000Z',
|
||||
},
|
||||
}),
|
||||
]
|
||||
|
||||
export { makeTerm }
|
||||
|
||||
export const termStudentLinks = new Map([
|
||||
[
|
||||
1,
|
||||
|
||||
@@ -66,16 +66,26 @@ const makeUser = (i, overrides = {}) => {
|
||||
const province = provinceById((i % 4) + 1)
|
||||
const city = cityForProvince(province.id)
|
||||
const role = roles[(i % 4) + 1]?.name || 'student'
|
||||
const id = 100 + i
|
||||
const phoneNumber = `0912${String(1_000_000 + i).padStart(7, '0')}`
|
||||
return {
|
||||
id: 100 + i,
|
||||
// --- spec (GET /admin/users) ---
|
||||
id,
|
||||
name: `${firstName} ${lastName}`,
|
||||
email: `user${id}@example.com`,
|
||||
phone: phoneNumber.replace(/^0/, '+98'),
|
||||
roles: [role],
|
||||
avatarUrl: '',
|
||||
avatarDownloadUrl: '',
|
||||
createdAt: new Date(Date.now() - i * 86_400_000).toISOString(),
|
||||
|
||||
// --- ui-only (pending backend) ---
|
||||
firstName,
|
||||
lastName,
|
||||
fullName: `${firstName} ${lastName}`,
|
||||
phoneNumber: `0912${String(1_000_000 + i).padStart(7, '0')}`,
|
||||
phoneNumber,
|
||||
nationalCode: String(1_000_000_000 + i * 7).padStart(10, '0'),
|
||||
avatarUrl: '',
|
||||
status: i % 5 === 0 ? 'pending' : 'approved',
|
||||
roles: [role],
|
||||
roleId: roles.find((r) => r.name === role)?.id,
|
||||
address: {
|
||||
address: 'آدرس نمونه',
|
||||
@@ -88,7 +98,6 @@ const makeUser = (i, overrides = {}) => {
|
||||
maritalStatus: i % 2 ? 'single' : 'married',
|
||||
gender: i % 2 ? 'female' : 'male',
|
||||
},
|
||||
createdAt: new Date(Date.now() - i * 86_400_000).toISOString(),
|
||||
...overrides,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,25 @@
|
||||
export const currentProfile = {
|
||||
id: 1,
|
||||
// Backend `/auth/me` currently returns the keys marked "spec" below.
|
||||
// The "ui-only" keys are extras the UI already depends on (edit-profile form,
|
||||
// avatars, address, etc.) — they must be preserved in the mock until the
|
||||
// backend completes the response model. See docs/backend-api-todo.md.
|
||||
export const currentMe = {
|
||||
// --- spec (GET /auth/me) ---
|
||||
id: 5,
|
||||
name: 'سجاد محمدی',
|
||||
email: 'sajjad@example.com',
|
||||
phone: '+989121234567',
|
||||
roles: ['student'],
|
||||
avatarUrl: 'http://localhost:8080/storage/users/5/avatar.jpg',
|
||||
avatarDownloadUrl: 'http://localhost:8080/api/media/9/download',
|
||||
createdAt: '2026-02-01T10:00:00+00:00',
|
||||
|
||||
// --- ui-only (pending backend) ---
|
||||
firstName: 'سجاد',
|
||||
lastName: 'محمدی',
|
||||
fullName: 'سجاد محمدی',
|
||||
phoneNumber: '09123456789',
|
||||
nationalCode: '0079827498',
|
||||
avatarUrl: '',
|
||||
status: 'approved',
|
||||
roles: ['user'],
|
||||
address: {
|
||||
address: 'خیابان آزادی، پلاک ۱۲',
|
||||
province: { id: 1, name: 'تهران' },
|
||||
Reference in New Issue
Block a user