// Data mapping utilities for converting backend data to frontend format // Map student data from backend to frontend format export const mapStudent = (backendData) => { if (!backendData) return null; return { id: backendData.id, name: backendData.realName, // realName -> name studentId: backendData.studentNo, // studentNo -> studentId gender: backendData.gender === "MALE" ? "男" : "女", school: backendData.school, major: backendData.major, enrollDate: backendData.enrollDate, mbtiType: backendData.mbtiType, className: backendData.class?.name, classId: backendData.classId, stageName: backendData.currentStage?.name, stageId: backendData.currentStageId, // User info email: backendData.user?.email, phone: backendData.user?.phone, username: backendData.user?.username, lastLogin: backendData.user?.lastLogin, }; }; // Map student list export const mapStudentList = (backendList) => { if (!Array.isArray(backendList)) return []; return backendList.map(mapStudent); }; // Map course data export const mapCourse = (backendData) => { if (!backendData) return null; return { id: backendData.id, name: backendData.name, code: backendData.code, description: backendData.description, category: backendData.category, type: backendData.type, credits: backendData.credits, hours: backendData.hours, isAiCourse: backendData.isAiCourse, teacher: backendData.teacher ? { id: backendData.teacher.id, name: backendData.teacher.realName, } : null, stage: backendData.stage, enrollmentCount: backendData.enrollmentCount || backendData._count?.enrollments || 0, }; }; // Map course list export const mapCourseList = (backendList) => { if (!Array.isArray(backendList)) return []; return backendList.map(mapCourse); }; // Map job data export const mapJob = (backendData) => { if (!backendData) return null; // Format salary range let salary = "面议"; if (backendData.salaryMin && backendData.salaryMax) { const min = Math.floor(backendData.salaryMin / 1000); const max = Math.floor(backendData.salaryMax / 1000); salary = `${min}K-${max}K`; } return { id: backendData.id, company: backendData.company, position: backendData.title, // title -> position description: backendData.description, requirements: backendData.requirements, responsibilities: backendData.responsibilities, companyName: backendData.company?.name || "", companyId: backendData.companyId, type: mapJobType(backendData.type), jobType: backendData.type === "INTERNSHIP" ? "internship" : "fulltime", level: backendData.level, location: backendData.location, salary: salary, salaryMin: backendData.salaryMin, salaryMax: backendData.salaryMax, benefits: backendData.benefits || [], skills: backendData.skills || [], isActive: backendData.isActive, status: backendData.isActive ? "available" : "closed", remainingPositions: backendData._count?.interviews || 5, // Mock remaining positions applicationStatus: "not_applied", // Default status tags: generateJobTags(backendData), deadline: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString(), // 30 days from now }; }; // Map job list export const mapJobList = (backendList) => { if (!Array.isArray(backendList)) return []; return backendList.map(mapJob); }; // Map job type const mapJobType = (type) => { const typeMap = { FULLTIME: "全职", PARTTIME: "兼职", INTERNSHIP: "实习", CONTRACT: "合同制", REMOTE: "远程", }; return typeMap[type] || type; }; // Generate job tags const generateJobTags = (job) => { const tags = []; if (job.location) tags.push(job.location.split("市")[0] + "市"); if (job.type === "FULLTIME") tags.push("五险一金"); if (job.benefits?.includes("双休")) tags.push("双休"); if (job.benefits?.includes("弹性工作")) tags.push("弹性工作"); return tags.slice(0, 4); // Max 4 tags }; // Map company data export const mapCompany = (backendData) => { if (!backendData) return null; return { id: backendData.id, name: backendData.name, companyName: backendData.name, // Alias for compatibility description: backendData.description, industry: backendData.industry, scale: mapCompanyScale(backendData.scale), location: backendData.location, website: backendData.website, logo: backendData.logo, contact: backendData.contact, jobCount: backendData._count?.jobs || 0, jobs: backendData.jobs ? mapJobList(backendData.jobs) : [], }; }; // Map company list export const mapCompanyList = (backendList) => { if (!Array.isArray(backendList)) return []; return backendList.map(mapCompany); }; // Map company scale const mapCompanyScale = (scale) => { const scaleMap = { SMALL: "50人以下", MEDIUM: "50-200人", LARGE: "200-1000人", ENTERPRISE: "1000人以上", }; return scaleMap[scale] || scale; }; // Map resume data export const mapResume = (backendData) => { if (!backendData) return null; return { id: backendData.id, title: backendData.title, content: backendData.content, isActive: backendData.isActive, version: backendData.version, student: backendData.student ? mapStudent(backendData.student) : null, studentId: backendData.studentId, createdAt: backendData.createdAt, updatedAt: backendData.updatedAt, }; }; // Map interview data export const mapInterview = (backendData) => { if (!backendData) return null; return { id: backendData.id, scheduledAt: backendData.scheduledAt, interviewTime: new Date(backendData.scheduledAt).toLocaleString("zh-CN"), type: backendData.type, status: backendData.status, location: backendData.location, notes: backendData.notes, feedback: backendData.feedback, result: backendData.result, student: backendData.student ? mapStudent(backendData.student) : null, job: backendData.job ? mapJob(backendData.job) : { // Provide default job object when no job relation exists salary: "面议", tags: [], company: { name: backendData.company || "" } }, company: backendData.company || backendData.job?.company?.name || "", position: backendData.position || backendData.job?.title || "", // Map status for frontend statusText: mapInterviewStatus(backendData.status, backendData.result), }; }; // Map interview list export const mapInterviewList = (backendList) => { if (!Array.isArray(backendList)) return []; return backendList.map(mapInterview); }; // Map interview status const mapInterviewStatus = (status, result) => { if (status === "COMPLETED") { if (result === "PASS" || result === "OFFER") return "面试成功"; if (result === "FAIL") return "面试失败"; return "已完成"; } const statusMap = { SCHEDULED: "待面试", CANCELLED: "已取消", NO_SHOW: "未到场", }; return statusMap[status] || status; }; // Map enrollment data export const mapEnrollment = (backendData) => { if (!backendData) return null; return { id: backendData.id, courseId: backendData.courseId, studentId: backendData.studentId, status: backendData.status, progress: backendData.progress || 0, score: backendData.score, enrolledAt: backendData.enrolledAt, completedAt: backendData.completedAt, course: backendData.course ? mapCourse(backendData.course) : null, student: backendData.student ? mapStudent(backendData.student) : null, // Map status for display statusText: mapEnrollmentStatus(backendData.status), }; }; // Map enrollment status const mapEnrollmentStatus = (status) => { const statusMap = { NOT_STARTED: "未开始", IN_PROGRESS: "学习中", COMPLETED: "已完成", }; return statusMap[status] || status; }; // Map class data export const mapClass = (backendData) => { if (!backendData) return null; return { id: backendData.id, name: backendData.name, className: backendData.name, // Alias for compatibility description: backendData.description, startDate: backendData.startDate, endDate: backendData.endDate, isActive: backendData.isActive, teacher: backendData.teacher ? { id: backendData.teacher.id, name: backendData.teacher.realName, } : null, studentCount: backendData._count?.students || 0, students: backendData.students ? mapStudentList(backendData.students) : [], }; }; // Map stage data export const mapStage = (backendData) => { if (!backendData) return null; return { id: backendData.id, name: backendData.name, description: backendData.description, order: backendData.order, duration: backendData.duration, requirements: backendData.requirements, courseCount: backendData._count?.courses || 0, studentCount: backendData._count?.students || 0, courses: backendData.courses ? mapCourseList(backendData.courses) : [], students: backendData.students ? mapStudentList(backendData.students) : [], }; }; // Map learning record export const mapLearningRecord = (backendData) => { if (!backendData) return null; return { id: backendData.id, studentId: backendData.studentId, courseId: backendData.courseId, date: backendData.date, duration: backendData.duration, progress: backendData.progress, content: backendData.content, }; }; // Map profile data (for personal profile page) export const mapProfile = (studentData) => { if (!studentData) return null; const mapped = mapStudent(studentData); return { ...mapped, avatar: "/api/placeholder/80/80", // Default avatar badges: { credits: 84, // Mock data, should come from backend classRank: 9, // Mock data, should come from backend mbti: studentData.mbtiType || "ENTP", }, courses: studentData.enrollments ? studentData.enrollments.map((e) => e.course?.name).filter(Boolean) : [], mbtiReport: studentData.mbtiReport || generateMockMBTIReport(studentData.mbtiType), }; }; // Generate mock MBTI report (temporary until backend provides) const generateMockMBTIReport = (type) => { return { type: type || "ENTP", title: "Personality Type", description: "Your personality type description", characteristics: ["Creative", "Analytical", "Strategic"], strengths: ["Problem-solving", "Leadership", "Innovation"], recommendations: ["Focus on execution", "Develop patience", "Listen more"], careerSuggestions: ["Product Manager", "Consultant", "Entrepreneur"], }; }; // Export all mappers export default { mapStudent, mapStudentList, mapCourse, mapCourseList, mapJob, mapJobList, mapCompany, mapCompanyList, mapResume, mapInterview, mapInterviewList, mapEnrollment, mapClass, mapStage, mapLearningRecord, mapProfile, };