first commit
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
import { register } from '@/services/mock/registry'
|
||||
import { endpoints } from '@/services/api/endpoints'
|
||||
import { adminAssignments, assignmentSubmissions } from '@/services/mock/fixtures/admin-assignments'
|
||||
import { adminCourseTemplates } from '@/services/mock/fixtures/admin-courses'
|
||||
import { adminSessions } from '@/services/mock/fixtures/admin-sessions'
|
||||
import {
|
||||
filterDateRange,
|
||||
filterItems,
|
||||
findOrThrow,
|
||||
isoNow,
|
||||
makeId,
|
||||
paginate,
|
||||
removeById,
|
||||
updateById,
|
||||
} from '@/services/mock/helpers'
|
||||
|
||||
const computeDurationDays = (start, end) => {
|
||||
if (!start || !end) return null
|
||||
const diff = Math.ceil((new Date(end).getTime() - new Date(start).getTime()) / 86_400_000)
|
||||
return diff >= 0 ? diff : null
|
||||
}
|
||||
|
||||
register('GET', endpoints.getAssignmentsList, ({ query }) => {
|
||||
let list = filterItems(adminAssignments, query, {
|
||||
title: 'includes',
|
||||
courseTemplateId: (item, v) => String(item.courseTemplate?.id) === String(v),
|
||||
sessionId: (item, v) => String(item.session?.id) === String(v),
|
||||
})
|
||||
list = filterDateRange(list, query)
|
||||
return paginate(list, query)
|
||||
})
|
||||
|
||||
register('GET', endpoints.showAssignment, ({ params }) => ({
|
||||
data: findOrThrow(adminAssignments, params.id),
|
||||
}))
|
||||
|
||||
register('POST', endpoints.addNewAssignment, ({ data }) => {
|
||||
const tpl = adminCourseTemplates.find((c) => c.id === Number(data.courseTemplateId))
|
||||
const sess = adminSessions.find((s) => s.id === Number(data.sessionId))
|
||||
const item = {
|
||||
id: makeId(),
|
||||
title: data.title || '',
|
||||
description: data.description || '',
|
||||
courseTemplate: tpl ? { id: tpl.id, title: tpl.title } : null,
|
||||
courseTemplateTitle: tpl?.title || '',
|
||||
session: sess ? { id: sess.id, title: sess.title } : null,
|
||||
sessionTitle: sess?.title || '',
|
||||
startDate: data.startDate || '',
|
||||
endDate: data.endDate || '',
|
||||
durationDays: computeDurationDays(data.startDate, data.endDate),
|
||||
priority: data.priority || 'mandatory',
|
||||
submissionsCount: 0,
|
||||
attachments: data.attachments || [],
|
||||
createdAt: isoNow(),
|
||||
}
|
||||
adminAssignments.unshift(item)
|
||||
return { data: item }
|
||||
})
|
||||
|
||||
register('PUT', endpoints.updateAssignment, ({ params, data }) => {
|
||||
const tpl = adminCourseTemplates.find((c) => c.id === Number(data.courseTemplateId))
|
||||
const sess = adminSessions.find((s) => s.id === Number(data.sessionId))
|
||||
return {
|
||||
data: updateById(adminAssignments, params.id, {
|
||||
title: data.title,
|
||||
description: data.description,
|
||||
courseTemplate: tpl ? { id: tpl.id, title: tpl.title } : undefined,
|
||||
courseTemplateTitle: tpl?.title,
|
||||
session: sess ? { id: sess.id, title: sess.title } : undefined,
|
||||
sessionTitle: sess?.title,
|
||||
startDate: data.startDate,
|
||||
endDate: data.endDate,
|
||||
durationDays: computeDurationDays(data.startDate, data.endDate),
|
||||
priority: data.priority,
|
||||
attachments: data.attachments || [],
|
||||
}),
|
||||
}
|
||||
})
|
||||
|
||||
register('DELETE', endpoints.deleteAssignment, ({ params }) => {
|
||||
removeById(adminAssignments, params.id)
|
||||
return { data: { message: 'حذف موفق' } }
|
||||
})
|
||||
|
||||
register('GET', endpoints.getAssignmentSubmissions, ({ params, query }) => {
|
||||
const list = assignmentSubmissions.get(Number(params.assignmentId)) || []
|
||||
return paginate(list, query)
|
||||
})
|
||||
|
||||
register('GET', endpoints.showAssignmentSubmission, ({ params }) => {
|
||||
const list = assignmentSubmissions.get(Number(params.assignmentId)) || []
|
||||
const found = list.find((s) => String(s.id) === String(params.submissionId))
|
||||
return { data: found || null }
|
||||
})
|
||||
|
||||
register('POST', endpoints.reviewAssignmentSubmission, ({ params, data }) => {
|
||||
const list = assignmentSubmissions.get(Number(params.assignmentId)) || []
|
||||
const sub = list.find((s) => String(s.id) === String(params.submissionId))
|
||||
if (sub) {
|
||||
Object.assign(sub, {
|
||||
score: data.score ?? sub.score,
|
||||
status: data.status ?? sub.status,
|
||||
reviewerNote: data.reviewerNote ?? sub.reviewerNote,
|
||||
})
|
||||
}
|
||||
return { data: sub || null }
|
||||
})
|
||||
@@ -0,0 +1,56 @@
|
||||
import { register } from '@/services/mock/registry'
|
||||
import { endpoints } from '@/services/api/endpoints'
|
||||
import { adminConsultations } from '@/services/mock/fixtures/admin-consultations'
|
||||
import {
|
||||
filterDateRange,
|
||||
filterItems,
|
||||
findOrThrow,
|
||||
isoNow,
|
||||
makeId,
|
||||
paginate,
|
||||
updateById,
|
||||
} from '@/services/mock/helpers'
|
||||
|
||||
const STATUS_LABELS = {
|
||||
in_progress: 'در حال گفتگو',
|
||||
answered: 'پاسخ داده شده',
|
||||
closed: 'بسته شده',
|
||||
}
|
||||
|
||||
register('GET', endpoints.getConsultationsList, ({ query }) => {
|
||||
let list = filterItems(adminConsultations, query, {
|
||||
status: 'eq',
|
||||
userName: (item, v) =>
|
||||
`${item.user?.firstName || ''} ${item.user?.lastName || ''}`
|
||||
.toLowerCase()
|
||||
.includes(String(v).toLowerCase()),
|
||||
})
|
||||
list = filterDateRange(list, query)
|
||||
return paginate(list, query)
|
||||
})
|
||||
|
||||
register('GET', endpoints.showConsultation, ({ params }) => ({
|
||||
data: findOrThrow(adminConsultations, params.id),
|
||||
}))
|
||||
|
||||
register('POST', endpoints.sendConsultationMessage, ({ params, data }) => {
|
||||
const consultation = findOrThrow(adminConsultations, params.id)
|
||||
const message = {
|
||||
id: makeId(),
|
||||
sender: 'admin',
|
||||
text: data.text || '',
|
||||
time: 'همین الان',
|
||||
sentAt: isoNow(),
|
||||
}
|
||||
consultation.messages = [...(consultation.messages || []), message]
|
||||
consultation.status = 'answered'
|
||||
consultation.statusLabel = STATUS_LABELS.answered
|
||||
return { data: consultation }
|
||||
})
|
||||
|
||||
register('POST', endpoints.changeConsultationStatus, ({ params, data }) => ({
|
||||
data: updateById(adminConsultations, params.id, {
|
||||
status: data.status,
|
||||
statusLabel: STATUS_LABELS[data.status] || data.status,
|
||||
}),
|
||||
}))
|
||||
@@ -0,0 +1,166 @@
|
||||
import { register } from '@/services/mock/registry'
|
||||
import { endpoints } from '@/services/api/endpoints'
|
||||
import { adminCourseTemplates, adminOfferedCourses } from '@/services/mock/fixtures/admin-courses'
|
||||
import { adminTerms } from '@/services/mock/fixtures/admin-terms'
|
||||
import { adminUsers } from '@/services/mock/fixtures/admin-users'
|
||||
import {
|
||||
filterDateRange,
|
||||
filterItems,
|
||||
findOrThrow,
|
||||
isoNow,
|
||||
makeId,
|
||||
paginate,
|
||||
removeById,
|
||||
updateById,
|
||||
} from '@/services/mock/helpers'
|
||||
|
||||
register('GET', endpoints.getCourseTemplatesList, ({ query }) => {
|
||||
let list = filterItems(adminCourseTemplates, query, {
|
||||
title: 'includes',
|
||||
status: (item, v) => String(item.isActiveByDefault ? 1 : 0) === String(v),
|
||||
})
|
||||
list = filterDateRange(list, query)
|
||||
return paginate(list, query)
|
||||
})
|
||||
|
||||
register('GET', endpoints.showCourseTemplate, ({ params }) => ({
|
||||
data: findOrThrow(adminCourseTemplates, params.id),
|
||||
}))
|
||||
|
||||
register('POST', endpoints.addNewCourseTemplate, ({ data }) => {
|
||||
const teacher = adminUsers.find((u) => u.id === Number(data.defaultTeacherId))
|
||||
const item = {
|
||||
id: makeId(),
|
||||
title: data.title || '',
|
||||
description: data.description || '',
|
||||
image: data.imageId ? `https://picsum.photos/seed/course-${data.imageId}/200/200` : '',
|
||||
defaultTeacher: teacher
|
||||
? {
|
||||
id: teacher.id,
|
||||
firstName: teacher.firstName,
|
||||
lastName: teacher.lastName,
|
||||
fullName: `${teacher.firstName} ${teacher.lastName}`,
|
||||
}
|
||||
: null,
|
||||
defaultCapacity: Number(data.defaultCapacity) || 0,
|
||||
isActiveByDefault: !!data.isActiveByDefault,
|
||||
prerequisitesCount: (data.prerequisites || []).length,
|
||||
prerequisites: (data.prerequisites || []).map((id) => ({
|
||||
courseId: id,
|
||||
course: adminCourseTemplates.find((c) => c.id === Number(id)) || { id },
|
||||
})),
|
||||
createdAt: isoNow(),
|
||||
}
|
||||
adminCourseTemplates.unshift(item)
|
||||
return { data: item }
|
||||
})
|
||||
|
||||
register('PUT', endpoints.updateCourseTemplate, ({ params, data }) => {
|
||||
const teacher = adminUsers.find((u) => u.id === Number(data.defaultTeacherId))
|
||||
return {
|
||||
data: updateById(adminCourseTemplates, params.id, {
|
||||
title: data.title,
|
||||
description: data.description,
|
||||
image: data.imageId ? `https://picsum.photos/seed/course-${data.imageId}/200/200` : undefined,
|
||||
defaultTeacher: teacher
|
||||
? {
|
||||
id: teacher.id,
|
||||
firstName: teacher.firstName,
|
||||
lastName: teacher.lastName,
|
||||
fullName: `${teacher.firstName} ${teacher.lastName}`,
|
||||
}
|
||||
: undefined,
|
||||
defaultCapacity: Number(data.defaultCapacity) || 0,
|
||||
isActiveByDefault: !!data.isActiveByDefault,
|
||||
prerequisites: (data.prerequisites || []).map((id) => ({
|
||||
courseId: id,
|
||||
course: adminCourseTemplates.find((c) => c.id === Number(id)) || { id },
|
||||
})),
|
||||
prerequisitesCount: (data.prerequisites || []).length,
|
||||
}),
|
||||
}
|
||||
})
|
||||
|
||||
register('DELETE', endpoints.deleteCourseTemplate, ({ params }) => {
|
||||
removeById(adminCourseTemplates, params.id)
|
||||
return { data: { message: 'حذف موفق' } }
|
||||
})
|
||||
|
||||
register('POST', endpoints.changeStatusCourseTemplate, ({ params, data }) => ({
|
||||
data: updateById(adminCourseTemplates, params.id, {
|
||||
isActiveByDefault: !!data.isActiveByDefault,
|
||||
}),
|
||||
}))
|
||||
|
||||
register('GET', endpoints.getCoursesList, ({ query }) => {
|
||||
let list = filterItems(adminOfferedCourses, query, {
|
||||
title: 'includes',
|
||||
termId: 'eq',
|
||||
status: (item, v) => String(item.isActive ? 1 : 0) === String(v),
|
||||
})
|
||||
list = filterDateRange(list, query, 'startDate')
|
||||
return paginate(list, query)
|
||||
})
|
||||
|
||||
register('GET', endpoints.showCourse, ({ params }) => ({
|
||||
data: findOrThrow(adminOfferedCourses, params.id),
|
||||
}))
|
||||
|
||||
register('POST', endpoints.addNewCourse, ({ data }) => {
|
||||
const template = adminCourseTemplates.find((t) => t.id === Number(data.templateId))
|
||||
const term = adminTerms.find((t) => t.id === Number(data.termId))
|
||||
const teacher = adminUsers.find((u) => u.id === Number(data.teacherId))
|
||||
const item = {
|
||||
id: makeId(),
|
||||
title: data.title || template?.title || '',
|
||||
image: data.imageId ? `https://picsum.photos/seed/offered-${data.imageId}/200/200` : '',
|
||||
template: template ? { id: template.id, title: template.title } : null,
|
||||
templateId: template?.id,
|
||||
term: term ? { id: term.id, title: term.title } : null,
|
||||
termId: term?.id,
|
||||
teacher: teacher
|
||||
? {
|
||||
id: teacher.id,
|
||||
firstName: teacher.firstName,
|
||||
lastName: teacher.lastName,
|
||||
fullName: `${teacher.firstName} ${teacher.lastName}`,
|
||||
}
|
||||
: null,
|
||||
capacity: Number(data.capacity) || 0,
|
||||
isActive: !!data.isActive,
|
||||
prerequisitesCount: 0,
|
||||
startDate: term?.startDate || '',
|
||||
endDate: term?.endDate || '',
|
||||
createdAt: isoNow(),
|
||||
}
|
||||
adminOfferedCourses.unshift(item)
|
||||
return { data: item }
|
||||
})
|
||||
|
||||
register('PUT', endpoints.updateCourse, ({ params, data }) => {
|
||||
const template = adminCourseTemplates.find((t) => t.id === Number(data.templateId))
|
||||
const term = adminTerms.find((t) => t.id === Number(data.termId))
|
||||
return {
|
||||
data: updateById(adminOfferedCourses, params.id, {
|
||||
title: data.title,
|
||||
image: data.imageId
|
||||
? `https://picsum.photos/seed/offered-${data.imageId}/200/200`
|
||||
: undefined,
|
||||
template: template ? { id: template.id, title: template.title } : undefined,
|
||||
templateId: template?.id,
|
||||
term: term ? { id: term.id, title: term.title } : undefined,
|
||||
termId: term?.id,
|
||||
capacity: Number(data.capacity) || 0,
|
||||
isActive: !!data.isActive,
|
||||
}),
|
||||
}
|
||||
})
|
||||
|
||||
register('DELETE', endpoints.deleteCourse, ({ params }) => {
|
||||
removeById(adminOfferedCourses, params.id)
|
||||
return { data: { message: 'حذف موفق' } }
|
||||
})
|
||||
|
||||
register('POST', endpoints.changeStatusCourse, ({ params, data }) => ({
|
||||
data: updateById(adminOfferedCourses, params.id, { isActive: !!data.isActive }),
|
||||
}))
|
||||
@@ -0,0 +1,94 @@
|
||||
import { register } from '@/services/mock/registry'
|
||||
import { endpoints } from '@/services/api/endpoints'
|
||||
import { adminExams, examParticipants } from '@/services/mock/fixtures/admin-exams'
|
||||
import { adminCourseTemplates } from '@/services/mock/fixtures/admin-courses'
|
||||
import { adminSessions } from '@/services/mock/fixtures/admin-sessions'
|
||||
import {
|
||||
filterDateRange,
|
||||
filterItems,
|
||||
findOrThrow,
|
||||
isoNow,
|
||||
makeId,
|
||||
paginate,
|
||||
removeById,
|
||||
updateById,
|
||||
} from '@/services/mock/helpers'
|
||||
|
||||
register('GET', endpoints.getExamsList, ({ query }) => {
|
||||
let list = filterItems(adminExams, query, {
|
||||
title: 'includes',
|
||||
courseTemplateId: (item, v) => String(item.courseTemplate?.id) === String(v),
|
||||
})
|
||||
list = filterDateRange(list, query)
|
||||
return paginate(list, query)
|
||||
})
|
||||
|
||||
register('GET', endpoints.showExam, ({ params }) => ({
|
||||
data: findOrThrow(adminExams, params.id),
|
||||
}))
|
||||
|
||||
register('POST', endpoints.addNewExam, ({ data }) => {
|
||||
const session = adminSessions.find((s) => s.id === Number(data.sessionId))
|
||||
const template = session?.courseTemplate
|
||||
? adminCourseTemplates.find((c) => c.id === Number(session.courseTemplate.id))
|
||||
: null
|
||||
const item = {
|
||||
id: makeId(),
|
||||
title: data.title || '',
|
||||
description: data.description || '',
|
||||
session: session ? { id: session.id, title: session.title } : null,
|
||||
sessionTitle: session?.title || '',
|
||||
courseTemplate: template ? { id: template.id, title: template.title } : null,
|
||||
courseTemplateTitle: template?.title || '',
|
||||
durationMinutes: Number(data.durationMinutes) || 0,
|
||||
passingScore: Number(data.passingScore) || 0,
|
||||
questionsCount: data.questions?.length || 0,
|
||||
randomize: !!data.randomize,
|
||||
endDate: data.endDate || '',
|
||||
startDate: isoNow(),
|
||||
createdAt: isoNow(),
|
||||
questions: data.questions || [],
|
||||
usedInTerms: [],
|
||||
}
|
||||
adminExams.unshift(item)
|
||||
return { data: item }
|
||||
})
|
||||
|
||||
register('PUT', endpoints.updateExam, ({ params, data }) => {
|
||||
const session = adminSessions.find((s) => s.id === Number(data.sessionId))
|
||||
const template = session?.courseTemplate
|
||||
? adminCourseTemplates.find((c) => c.id === Number(session.courseTemplate.id))
|
||||
: null
|
||||
return {
|
||||
data: updateById(adminExams, params.id, {
|
||||
title: data.title,
|
||||
description: data.description,
|
||||
session: session ? { id: session.id, title: session.title } : undefined,
|
||||
sessionTitle: session?.title,
|
||||
courseTemplate: template ? { id: template.id, title: template.title } : undefined,
|
||||
courseTemplateTitle: template?.title,
|
||||
durationMinutes: Number(data.durationMinutes) || 0,
|
||||
passingScore: Number(data.passingScore) || 0,
|
||||
questionsCount: data.questions?.length || 0,
|
||||
randomize: !!data.randomize,
|
||||
endDate: data.endDate,
|
||||
questions: data.questions || [],
|
||||
}),
|
||||
}
|
||||
})
|
||||
|
||||
register('DELETE', endpoints.deleteExam, ({ params }) => {
|
||||
removeById(adminExams, params.id)
|
||||
return { data: { message: 'حذف موفق' } }
|
||||
})
|
||||
|
||||
register('GET', endpoints.getExamParticipants, ({ params, query }) => {
|
||||
const list = examParticipants.get(Number(params.examId)) || []
|
||||
return paginate(list, query)
|
||||
})
|
||||
|
||||
register('GET', endpoints.showExamParticipant, ({ params }) => {
|
||||
const list = examParticipants.get(Number(params.examId)) || []
|
||||
const found = list.find((p) => String(p.id) === String(params.participantId))
|
||||
return { data: found || null }
|
||||
})
|
||||
@@ -0,0 +1,49 @@
|
||||
import { register } from '@/services/mock/registry'
|
||||
import { endpoints } from '@/services/api/endpoints'
|
||||
import { pendingStudents } from '@/services/mock/fixtures/admin-pending-students'
|
||||
import {
|
||||
filterDateRange,
|
||||
filterItems,
|
||||
findOrThrow,
|
||||
paginate,
|
||||
removeById,
|
||||
updateById,
|
||||
} from '@/services/mock/helpers'
|
||||
|
||||
register('GET', endpoints.getPendingStudents, ({ query }) => {
|
||||
let list = filterItems(pendingStudents, query, {
|
||||
name: (item, v) =>
|
||||
`${item.firstName} ${item.lastName}`.toLowerCase().includes(String(v).toLowerCase()),
|
||||
nationalCode: 'includes',
|
||||
})
|
||||
list = filterDateRange(list, query, 'submittedAt')
|
||||
return paginate(list, query)
|
||||
})
|
||||
|
||||
register('GET', endpoints.showPendingStudent, ({ params }) => ({
|
||||
data: findOrThrow(pendingStudents, params.id),
|
||||
}))
|
||||
|
||||
register('POST', endpoints.changeStatusPendingStudent, ({ params, data }) => {
|
||||
const target = findOrThrow(pendingStudents, params.id)
|
||||
const patch = {
|
||||
status: data.status,
|
||||
verification: {
|
||||
...target.verification,
|
||||
status: data.status,
|
||||
rejectionReason: data.rejectionReason || '',
|
||||
adminNote: data.adminNote || '',
|
||||
},
|
||||
}
|
||||
updateById(pendingStudents, params.id, patch)
|
||||
if (data.status === 'approved') {
|
||||
removeById(pendingStudents, params.id)
|
||||
}
|
||||
return { data: { user: { ...target, ...patch } } }
|
||||
})
|
||||
|
||||
register('GET', endpoints.downloadPdfPendingStudentInfo, ({ params }) => ({
|
||||
data: {
|
||||
downloadUrl: `https://example.com/mock-pdf-${params.id}.pdf`,
|
||||
},
|
||||
}))
|
||||
@@ -0,0 +1,86 @@
|
||||
import { register } from '@/services/mock/registry'
|
||||
import { endpoints } from '@/services/api/endpoints'
|
||||
import { adminSessions, sessionAttendance } from '@/services/mock/fixtures/admin-sessions'
|
||||
import { adminCourseTemplates } from '@/services/mock/fixtures/admin-courses'
|
||||
import { SESSION_TYPE } from '@/enums'
|
||||
import {
|
||||
filterDateRange,
|
||||
filterItems,
|
||||
findOrThrow,
|
||||
isoNow,
|
||||
makeId,
|
||||
paginate,
|
||||
removeById,
|
||||
updateById,
|
||||
} from '@/services/mock/helpers'
|
||||
|
||||
const enrich = (session) => ({
|
||||
...session,
|
||||
sessionTypeFa: SESSION_TYPE[session.sessionType] || session.sessionTypeFa || '',
|
||||
})
|
||||
|
||||
register('GET', endpoints.getSessionsList, ({ query }) => {
|
||||
let list = filterItems(adminSessions, query, {
|
||||
title: 'includes',
|
||||
courseTemplateId: (item, v) => String(item.courseTemplate?.id) === String(v),
|
||||
sessionType: 'eq',
|
||||
})
|
||||
list = filterDateRange(list, query)
|
||||
// eslint-disable-next-line unicorn/no-array-callback-reference
|
||||
return paginate(list.map(enrich), query)
|
||||
})
|
||||
|
||||
register('GET', endpoints.showSession, ({ params }) => ({
|
||||
data: enrich(findOrThrow(adminSessions, params.id)),
|
||||
}))
|
||||
|
||||
register('POST', endpoints.addNewSession, ({ data }) => {
|
||||
const tpl = adminCourseTemplates.find((c) => c.id === Number(data.courseTemplateId))
|
||||
const item = {
|
||||
id: makeId(),
|
||||
title: data.title || '',
|
||||
description: data.description || '',
|
||||
image: data.imageId ? `https://picsum.photos/seed/session-${data.imageId}/200/200` : '',
|
||||
courseTemplate: tpl ? { id: tpl.id, title: tpl.title } : null,
|
||||
sessionType: data.sessionType || 'in_person',
|
||||
durationMinutes: Number(data.durationMinutes) || 0,
|
||||
order: Number(data.order) || 1,
|
||||
sessionConfig: data.sessionConfig || {},
|
||||
materials: data.materials || [],
|
||||
usedInTerms: [],
|
||||
createdAt: isoNow(),
|
||||
}
|
||||
adminSessions.unshift(item)
|
||||
return { data: enrich(item) }
|
||||
})
|
||||
|
||||
register('PUT', endpoints.updateSession, ({ params, data }) => {
|
||||
const tpl = adminCourseTemplates.find((c) => c.id === Number(data.courseTemplateId))
|
||||
const updated = updateById(adminSessions, params.id, {
|
||||
title: data.title,
|
||||
description: data.description,
|
||||
image: data.imageId ? `https://picsum.photos/seed/session-${data.imageId}/200/200` : undefined,
|
||||
courseTemplate: tpl ? { id: tpl.id, title: tpl.title } : undefined,
|
||||
sessionType: data.sessionType,
|
||||
durationMinutes: Number(data.durationMinutes) || 0,
|
||||
order: Number(data.order) || 1,
|
||||
sessionConfig: data.sessionConfig ?? undefined,
|
||||
materials: data.materials ?? undefined,
|
||||
})
|
||||
return { data: enrich(updated) }
|
||||
})
|
||||
|
||||
register('DELETE', endpoints.deleteSession, ({ params }) => {
|
||||
removeById(adminSessions, params.id)
|
||||
return { data: { message: 'حذف موفق' } }
|
||||
})
|
||||
|
||||
register('POST', endpoints.changeStatusSession, ({ params, data }) => {
|
||||
const updated = updateById(adminSessions, params.id, { isActive: !!data.isActive })
|
||||
return { data: enrich(updated) }
|
||||
})
|
||||
|
||||
register('GET', endpoints.getSessionsAttendance, ({ params, query }) => {
|
||||
const list = sessionAttendance.get(Number(params.sessionId)) || []
|
||||
return paginate(list, query)
|
||||
})
|
||||
@@ -0,0 +1,153 @@
|
||||
import { register } from '@/services/mock/registry'
|
||||
import { endpoints } from '@/services/api/endpoints'
|
||||
import { adminTerms, termStudentLinks } from '@/services/mock/fixtures/admin-terms'
|
||||
import { adminUsers } from '@/services/mock/fixtures/admin-users'
|
||||
import { adminOfferedCourses } from '@/services/mock/fixtures/admin-courses'
|
||||
import {
|
||||
filterDateRange,
|
||||
filterItems,
|
||||
findOrThrow,
|
||||
isoNow,
|
||||
makeId,
|
||||
paginate,
|
||||
removeById,
|
||||
updateById,
|
||||
} from '@/services/mock/helpers'
|
||||
|
||||
register('GET', endpoints.getTermsList, ({ query }) => {
|
||||
let list = filterItems(adminTerms, query, {
|
||||
title: 'includes',
|
||||
status: (item, v) => String(item.isActive ? 1 : 0) === String(v),
|
||||
})
|
||||
list = filterDateRange(list, query, 'startDate')
|
||||
return paginate(list, query)
|
||||
})
|
||||
|
||||
register('GET', endpoints.showTerm, ({ params }) => ({
|
||||
data: findOrThrow(adminTerms, params.id),
|
||||
}))
|
||||
|
||||
register('POST', endpoints.addNewTerm, ({ data }) => {
|
||||
const term = {
|
||||
id: makeId(),
|
||||
title: data.title || '',
|
||||
description: data.description || '',
|
||||
image: data.imageId ? `https://picsum.photos/seed/term-${data.imageId}/200/200` : '',
|
||||
startDate: data.startDate || '',
|
||||
endDate: data.endDate || '',
|
||||
isActive: true,
|
||||
studentsCount: 0,
|
||||
coursesCount: 0,
|
||||
createdAt: isoNow(),
|
||||
}
|
||||
adminTerms.unshift(term)
|
||||
return { data: term }
|
||||
})
|
||||
|
||||
register('PUT', endpoints.updateTerm, ({ params, data }) => ({
|
||||
data: updateById(adminTerms, params.id, {
|
||||
title: data.title,
|
||||
description: data.description,
|
||||
startDate: data.startDate,
|
||||
endDate: data.endDate,
|
||||
image: data.imageId ? `https://picsum.photos/seed/term-${data.imageId}/200/200` : undefined,
|
||||
}),
|
||||
}))
|
||||
|
||||
register('DELETE', endpoints.deleteTerm, ({ params }) => {
|
||||
removeById(adminTerms, params.id)
|
||||
return { data: { message: 'حذف موفق' } }
|
||||
})
|
||||
|
||||
register('POST', endpoints.cloneTerm, ({ params }) => {
|
||||
const src = findOrThrow(adminTerms, params.id)
|
||||
const clone = { ...src, id: makeId(), title: `${src.title} (کپی)`, createdAt: isoNow() }
|
||||
adminTerms.unshift(clone)
|
||||
return { data: clone }
|
||||
})
|
||||
|
||||
register('POST', endpoints.changeStatusTerm, ({ params, data }) => ({
|
||||
data: updateById(adminTerms, params.id, { isActive: !!data.isActive }),
|
||||
}))
|
||||
|
||||
const studentSnapshot = (link) => {
|
||||
const user = adminUsers.find((u) => u.id === link.userId)
|
||||
return user ? { ...user, isOnLeave: link.isOnLeave } : null
|
||||
}
|
||||
|
||||
register('GET', endpoints.listUserTerm, ({ params, query }) => {
|
||||
const links = termStudentLinks.get(Number(params.termId)) || []
|
||||
const list = links.map((element) => studentSnapshot(element)).filter(Boolean)
|
||||
return paginate(list, query)
|
||||
})
|
||||
|
||||
register('POST', endpoints.addUserTerm, ({ params, data }) => {
|
||||
const termId = Number(params.termId)
|
||||
const links = termStudentLinks.get(termId) || []
|
||||
const ids = Array.isArray(data.userIds) ? data.userIds : []
|
||||
ids.forEach((userId) => {
|
||||
if (!links.some((l) => l.userId === Number(userId))) {
|
||||
links.push({ userId: Number(userId), isOnLeave: false })
|
||||
}
|
||||
})
|
||||
termStudentLinks.set(termId, links)
|
||||
const added = ids
|
||||
.map((id) => adminUsers.find((u) => u.id === Number(id)))
|
||||
.filter(Boolean)
|
||||
.map((u) => ({ ...u, isOnLeave: false }))
|
||||
const term = adminTerms.find((t) => t.id === termId)
|
||||
if (term) term.studentsCount = links.length
|
||||
return { data: added }
|
||||
})
|
||||
|
||||
register('DELETE', endpoints.removeUserTerm, ({ params }) => {
|
||||
const termId = Number(params.termId)
|
||||
const links = termStudentLinks.get(termId) || []
|
||||
const idx = links.findIndex((l) => String(l.userId) === String(params.userId))
|
||||
if (idx !== -1) links.splice(idx, 1)
|
||||
termStudentLinks.set(termId, links)
|
||||
const term = adminTerms.find((t) => t.id === termId)
|
||||
if (term) term.studentsCount = links.length
|
||||
return { data: { message: 'حذف موفق' } }
|
||||
})
|
||||
|
||||
register('POST', endpoints.changeLeaveStatus, ({ params, data }) => {
|
||||
const termId = Number(params.termId)
|
||||
const links = termStudentLinks.get(termId) || []
|
||||
const link = links.find((l) => String(l.userId) === String(params.userId))
|
||||
if (link) link.isOnLeave = !!data.setLeave
|
||||
return { data: { isOnLeave: !!data.setLeave } }
|
||||
})
|
||||
|
||||
register('GET', endpoints.listCourseTerm, ({ params, query }) => {
|
||||
const termId = Number(params.termId)
|
||||
const list = adminOfferedCourses.filter((c) => Number(c.termId) === termId)
|
||||
return paginate(list, query)
|
||||
})
|
||||
|
||||
register('POST', endpoints.addCourseTerm, ({ params, data }) => {
|
||||
const termId = Number(params.termId)
|
||||
const ids = Array.isArray(data.courseIds) ? data.courseIds : []
|
||||
const linked = []
|
||||
ids.forEach((id) => {
|
||||
const course = adminOfferedCourses.find((c) => Number(c.id) === Number(id))
|
||||
if (course) {
|
||||
course.termId = termId
|
||||
course.term = adminTerms.some((t) => t.id === termId)
|
||||
? { id: termId, title: adminTerms.find((t) => t.id === termId).title }
|
||||
: course.term
|
||||
linked.push(course)
|
||||
}
|
||||
})
|
||||
return { data: linked }
|
||||
})
|
||||
|
||||
register('DELETE', endpoints.removeCourseTerm, ({ params }) => {
|
||||
const courseId = Number(params.courseId)
|
||||
const course = adminOfferedCourses.find((c) => c.id === courseId)
|
||||
if (course) {
|
||||
course.termId = null
|
||||
course.term = null
|
||||
}
|
||||
return { data: { message: 'حذف موفق' } }
|
||||
})
|
||||
@@ -0,0 +1,55 @@
|
||||
import { register } from '@/services/mock/registry'
|
||||
import { endpoints } from '@/services/api/endpoints'
|
||||
import { adminTickets } from '@/services/mock/fixtures/admin-tickets'
|
||||
import {
|
||||
filterDateRange,
|
||||
filterItems,
|
||||
findOrThrow,
|
||||
isoNow,
|
||||
makeId,
|
||||
paginate,
|
||||
updateById,
|
||||
} from '@/services/mock/helpers'
|
||||
|
||||
register('GET', endpoints.getTicketsList, ({ query }) => {
|
||||
let list = filterItems(adminTickets, query, {
|
||||
status: 'eq',
|
||||
userName: (item, v) =>
|
||||
`${item.user?.firstName || ''} ${item.user?.lastName || ''}`
|
||||
.toLowerCase()
|
||||
.includes(String(v).toLowerCase()),
|
||||
})
|
||||
list = filterDateRange(list, query)
|
||||
return paginate(list, query)
|
||||
})
|
||||
|
||||
register('GET', endpoints.showTicket, ({ params }) => ({
|
||||
data: findOrThrow(adminTickets, params.id),
|
||||
}))
|
||||
|
||||
register('POST', endpoints.sendTicketMessage, ({ params, data }) => {
|
||||
const ticket = findOrThrow(adminTickets, params.id)
|
||||
const message = {
|
||||
id: makeId(),
|
||||
sender: 'admin',
|
||||
text: data.text || '',
|
||||
time: 'همین الان',
|
||||
sentAt: isoNow(),
|
||||
}
|
||||
ticket.messages = [...(ticket.messages || []), message]
|
||||
ticket.status = 'answered'
|
||||
ticket.statusLabel = 'پاسخ داده شده'
|
||||
return { data: ticket }
|
||||
})
|
||||
|
||||
register('POST', endpoints.changeTicketStatus, ({ params, data }) => ({
|
||||
data: updateById(adminTickets, params.id, {
|
||||
status: data.status,
|
||||
statusLabel:
|
||||
data.status === 'closed'
|
||||
? 'بسته شده'
|
||||
: data.status === 'answered'
|
||||
? 'پاسخ داده شده'
|
||||
: 'در انتظار پاسخ',
|
||||
}),
|
||||
}))
|
||||
@@ -0,0 +1,103 @@
|
||||
import { register } from '@/services/mock/registry'
|
||||
import { endpoints } from '@/services/api/endpoints'
|
||||
import { adminUsers, roles } from '@/services/mock/fixtures/admin-users'
|
||||
import {
|
||||
filterDateRange,
|
||||
filterItems,
|
||||
findOrThrow,
|
||||
isoNow,
|
||||
makeId,
|
||||
paginate,
|
||||
removeById,
|
||||
updateById,
|
||||
} from '@/services/mock/helpers'
|
||||
|
||||
register('GET', endpoints.getApprovedUsers, ({ query }) => {
|
||||
let list = filterItems(adminUsers, query, {
|
||||
name: (item, v) =>
|
||||
`${item.firstName} ${item.lastName}`.toLowerCase().includes(String(v).toLowerCase()),
|
||||
nationalCode: 'includes',
|
||||
phoneNumber: 'includes',
|
||||
roleId: (item, v) => String(item.roleId) === String(v),
|
||||
})
|
||||
list = filterDateRange(list, query)
|
||||
return paginate(list, query)
|
||||
})
|
||||
|
||||
register('GET', endpoints.showUserDetails, ({ params }) => ({
|
||||
data: findOrThrow(adminUsers, params.id),
|
||||
}))
|
||||
|
||||
register('POST', endpoints.addNewUser, ({ data }) => {
|
||||
const id = makeId()
|
||||
const role = roles.find((r) => r.id === Number(data.roleId)) || null
|
||||
const province = data.provinceId ? { id: data.provinceId, name: '' } : null
|
||||
const city = data.cityId ? { id: data.cityId, name: '' } : null
|
||||
const user = {
|
||||
id,
|
||||
firstName: data.firstName || '',
|
||||
lastName: data.lastName || '',
|
||||
fullName: `${data.firstName || ''} ${data.lastName || ''}`.trim(),
|
||||
phoneNumber: data.phoneNumber || '',
|
||||
nationalCode: data.nationalCode || '',
|
||||
avatarUrl: '',
|
||||
status: 'approved',
|
||||
roles: role ? [role.name] : [],
|
||||
roleId: role?.id,
|
||||
address: { address: data.address || '', province, city },
|
||||
profile: {
|
||||
bio: data.bio || '',
|
||||
birthDate: data.birthDate || '',
|
||||
maritalStatus: data.maritalStatus || '',
|
||||
gender: data.gender || '',
|
||||
avatarId: data.avatarId || null,
|
||||
},
|
||||
createdAt: isoNow(),
|
||||
}
|
||||
adminUsers.unshift(user)
|
||||
return { data: user }
|
||||
})
|
||||
|
||||
register('PUT', endpoints.updateUser, ({ params, data }) => {
|
||||
const role = roles.find((r) => r.id === Number(data.roleId))
|
||||
const patch = {
|
||||
firstName: data.firstName,
|
||||
lastName: data.lastName,
|
||||
fullName: `${data.firstName || ''} ${data.lastName || ''}`.trim(),
|
||||
phoneNumber: data.phoneNumber,
|
||||
nationalCode: data.nationalCode,
|
||||
roleId: role?.id,
|
||||
roles: role ? [role.name] : [],
|
||||
address: {
|
||||
address: data.address || '',
|
||||
province: data.provinceId ? { id: data.provinceId, name: '' } : null,
|
||||
city: data.cityId ? { id: data.cityId, name: '' } : null,
|
||||
},
|
||||
profile: {
|
||||
bio: data.bio || '',
|
||||
birthDate: data.birthDate || '',
|
||||
maritalStatus: data.maritalStatus || '',
|
||||
gender: data.gender || '',
|
||||
avatarId: data.avatarId || null,
|
||||
},
|
||||
}
|
||||
const updated = updateById(adminUsers, params.id, patch)
|
||||
return { data: updated }
|
||||
})
|
||||
|
||||
register('POST', endpoints.updateUserRole, ({ params, data }) => {
|
||||
const role = roles.find((r) => r.id === Number(data.roleId))
|
||||
const patch = role ? { roleId: role.id, roles: [role.name] } : {}
|
||||
return { data: updateById(adminUsers, params.id, patch) }
|
||||
})
|
||||
|
||||
register('POST', endpoints.changeUserStatus, ({ params, data }) => ({
|
||||
data: updateById(adminUsers, params.id, { status: data.status }),
|
||||
}))
|
||||
|
||||
register('DELETE', endpoints.deleteUser, ({ params }) => {
|
||||
removeById(adminUsers, params.id)
|
||||
return { data: { message: 'حذف موفق' } }
|
||||
})
|
||||
|
||||
register('GET', endpoints.getRolesList, () => ({ data: roles }))
|
||||
@@ -0,0 +1,89 @@
|
||||
import { register } from '@/services/mock/registry'
|
||||
import { endpoints } from '@/services/api/endpoints'
|
||||
import { currentProfile } from '@/services/mock/fixtures/profile'
|
||||
import { makeId } from '@/services/mock/helpers'
|
||||
|
||||
const fakeToken = 'mock-token-1234567890'
|
||||
|
||||
register('POST', endpoints.login, () => ({
|
||||
data: { user: currentProfile, token: fakeToken },
|
||||
}))
|
||||
|
||||
register('POST', endpoints.loginWithCode2Step, () => ({
|
||||
data: { user: currentProfile, token: fakeToken },
|
||||
}))
|
||||
|
||||
register('POST', endpoints.verifyCode, () => ({
|
||||
data: { user: currentProfile, token: fakeToken },
|
||||
}))
|
||||
|
||||
register('POST', endpoints.register, ({ data }) => ({
|
||||
data: { user: { ...currentProfile, ...data }, token: fakeToken },
|
||||
}))
|
||||
|
||||
register('POST', endpoints.resendVerificationCodeForRegister, () => ({
|
||||
data: { message: 'کد جدید ارسال شد' },
|
||||
}))
|
||||
|
||||
register('POST', endpoints.forgotPassword, () => ({
|
||||
data: { message: 'کد بازیابی ارسال شد' },
|
||||
}))
|
||||
|
||||
register('POST', endpoints.verifyForgotPasswordCode, () => ({
|
||||
data: { token: fakeToken },
|
||||
}))
|
||||
|
||||
register('POST', endpoints.resetPassword, () => ({
|
||||
data: { message: 'رمز عبور با موفقیت تغییر کرد' },
|
||||
}))
|
||||
|
||||
register('POST', endpoints.logout, () => ({ data: { message: 'خروج موفق' } }))
|
||||
|
||||
register('GET', endpoints.getProfile, () => ({ data: currentProfile }))
|
||||
|
||||
register('PUT', endpoints.updateProfile, ({ data }) => {
|
||||
Object.assign(currentProfile, {
|
||||
firstName: data.firstName ?? currentProfile.firstName,
|
||||
lastName: data.lastName ?? currentProfile.lastName,
|
||||
phoneNumber: data.phoneNumber ?? currentProfile.phoneNumber,
|
||||
nationalCode: data.nationalCode ?? currentProfile.nationalCode,
|
||||
})
|
||||
if (data.provinceId) {
|
||||
currentProfile.address = currentProfile.address || {}
|
||||
currentProfile.address.province = { id: data.provinceId, name: '' }
|
||||
}
|
||||
if (data.cityId) {
|
||||
currentProfile.address = currentProfile.address || {}
|
||||
currentProfile.address.city = { id: data.cityId, name: '' }
|
||||
}
|
||||
if (data.address) {
|
||||
currentProfile.address = { ...currentProfile.address, address: data.address }
|
||||
}
|
||||
currentProfile.profile = {
|
||||
...currentProfile.profile,
|
||||
bio: data.bio ?? currentProfile.profile?.bio,
|
||||
birthDate: data.birthDate ?? currentProfile.profile?.birthDate,
|
||||
maritalStatus: data.maritalStatus ?? currentProfile.profile?.maritalStatus,
|
||||
gender: data.gender ?? currentProfile.profile?.gender,
|
||||
}
|
||||
return { data: currentProfile }
|
||||
})
|
||||
|
||||
register('POST', endpoints.completeProfile, ({ data }) => ({
|
||||
data: { user: { ...currentProfile, ...data } },
|
||||
}))
|
||||
|
||||
register('GET', endpoints.getRegistrationQuestionVideo, () => ({
|
||||
data: { url: '', id: 0 },
|
||||
}))
|
||||
|
||||
register('POST', endpoints.uploadMediaTemporary, () => {
|
||||
const id = makeId()
|
||||
return {
|
||||
data: {
|
||||
id,
|
||||
uploadId: id,
|
||||
url: `https://picsum.photos/seed/${id}/240/240`,
|
||||
},
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,9 @@
|
||||
import { register } from '@/services/mock/registry'
|
||||
import { endpoints } from '@/services/api/endpoints'
|
||||
import { cities, provinces } from '@/services/mock/fixtures/common'
|
||||
|
||||
register('GET', endpoints.provinceList, () => ({ data: provinces }))
|
||||
|
||||
register('GET', endpoints.citiesList, ({ params }) => ({
|
||||
data: cities[params.provinceId] || [],
|
||||
}))
|
||||
@@ -0,0 +1,24 @@
|
||||
import { register } from '@/services/mock/registry'
|
||||
import { endpoints } from '@/services/api/endpoints'
|
||||
import { studentCourses } from '@/services/mock/fixtures/student-courses'
|
||||
import { findOrThrow, paginate } from '@/services/mock/helpers'
|
||||
|
||||
const filterByStatus = (status) => {
|
||||
if (!status) return studentCourses
|
||||
if (status === 'current') {
|
||||
return studentCourses.filter((c) => ['watching', 'waitForExam'].includes(c.status))
|
||||
}
|
||||
if (status === 'ended') {
|
||||
return studentCourses.filter((c) => ['completed', 'failed'].includes(c.status))
|
||||
}
|
||||
return studentCourses.filter((c) => c.status === status)
|
||||
}
|
||||
|
||||
register('GET', endpoints.getStudentCourses, ({ query }) => {
|
||||
const list = filterByStatus(query.status)
|
||||
return paginate(list, query)
|
||||
})
|
||||
|
||||
register('GET', endpoints.showStudentCourse, ({ params }) => ({
|
||||
data: findOrThrow(studentCourses, params.id),
|
||||
}))
|
||||
Reference in New Issue
Block a user