diff --git a/package.json b/package.json index ba19928..8310faa 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "dev": "vite", "build": "vite build", "preview": "vite preview", - "test": "node --test src/utils/uploadResponse.test.js" + "test": "node --test src/utils/uploadResponse.test.js src/utils/classSchedule.test.js" }, "dependencies": { "@fontsource/vazirmatn": "^5.3.0", diff --git a/src/components/classes/ClassSessionsSection.vue b/src/components/classes/ClassSessionsSection.vue index 770aa81..d56e9d9 100644 --- a/src/components/classes/ClassSessionsSection.vue +++ b/src/components/classes/ClassSessionsSection.vue @@ -254,7 +254,10 @@ const props = defineProps({ classId: { type: [String, Object], required: true }, courseId: { type: [String, Object], required: true }, professorId: { type: [String, Object], default: null }, - defaultSessionCount: { type: Number, default: 12 } + defaultSessionCount: { type: Number, default: 12 }, + days: { type: Array, default: () => [] }, + startTime: { type: String, default: '' }, + endTime: { type: String, default: '' } }); const { toPersianDigits, toLatinDigits, formatJalali } = usePersianDate(); @@ -339,11 +342,22 @@ const weekdays = [ const autoForm = reactive({ sessionCount: props.defaultSessionCount || 12, startDate: todayJalali(), - startTime: '19:00', - endTime: '20:30', - selectedDays: [6, 2] + startTime: props.startTime || '19:00', + endTime: props.endTime || '20:30', + selectedDays: props.days?.length ? [...props.days] : [6, 2] }); +watch( + () => [props.days, props.startTime, props.endTime, props.defaultSessionCount], + () => { + if (props.days?.length) autoForm.selectedDays = [...props.days]; + if (props.startTime) autoForm.startTime = props.startTime; + if (props.endTime) autoForm.endTime = props.endTime; + if (props.defaultSessionCount) autoForm.sessionCount = props.defaultSessionCount; + }, + { deep: true } +); + const toSessionDayIso = (value) => { if (!value) return null; const latin = toLatinDigits(String(value)); diff --git a/src/utils/classSchedule.js b/src/utils/classSchedule.js new file mode 100644 index 0000000..4271712 --- /dev/null +++ b/src/utils/classSchedule.js @@ -0,0 +1,41 @@ +export const WEEKDAYS = [ + { label: 'شنبه', value: 6 }, + { label: 'یکشنبه', value: 0 }, + { label: 'دوشنبه', value: 1 }, + { label: 'سهشنبه', value: 2 }, + { label: 'چهارشنبه', value: 3 }, + { label: 'پنجشنبه', value: 4 }, + { label: 'جمعه', value: 5 } +]; + +const IRAN_WEEK_ORDER = [6, 0, 1, 2, 3, 4, 5]; +const LABEL_BY_VALUE = Object.fromEntries(WEEKDAYS.map((day) => [day.value, day.label])); + +const joinFaList = (items) => { + if (!items.length) return ''; + if (items.length === 1) return items[0]; + if (items.length === 2) return `${items[0]} و ${items[1]}`; + return `${items.slice(0, -1).join('، ')} و ${items[items.length - 1]}`; +}; + +export function formatClassDays(days = []) { + const unique = [...new Set((days || []).map(Number).filter((day) => day >= 0 && day <= 6))]; + unique.sort((a, b) => IRAN_WEEK_ORDER.indexOf(a) - IRAN_WEEK_ORDER.indexOf(b)); + return joinFaList(unique.map((day) => LABEL_BY_VALUE[day]).filter(Boolean)); +} + +export function formatClassTime(startTime, endTime) { + const start = String(startTime || '').trim(); + const end = String(endTime || '').trim(); + if (!start && !end) return ''; + if (!end) return start; + if (!start) return end; + return `${start} – ${end}`; +} + +export function formatClassSchedule(cls) { + const days = formatClassDays(cls?.days); + const time = formatClassTime(cls?.startTime, cls?.endTime); + if (days && time) return `${days} | ${time}`; + return days || time || ''; +} diff --git a/src/utils/classSchedule.test.js b/src/utils/classSchedule.test.js new file mode 100644 index 0000000..63ba01c --- /dev/null +++ b/src/utils/classSchedule.test.js @@ -0,0 +1,22 @@ +import { describe, it } from 'node:test'; +import assert from 'node:assert/strict'; +import { formatClassDays, formatClassTime, formatClassSchedule } from './classSchedule.js'; + +describe('class schedule display', () => { + it('formats weekdays in Iran week order', () => { + assert.equal(formatClassDays([1, 6]), 'شنبه و دوشنبه'); + }); + + it('formats start and end times', () => { + assert.equal(formatClassTime('19:00', '21:00'), '19:00 – 21:00'); + assert.equal(formatClassTime('19:00', ''), '19:00'); + }); + + it('joins days and time for a class schedule label', () => { + assert.equal( + formatClassSchedule({ days: [6, 1], startTime: '19:00', endTime: '21:00' }), + 'شنبه و دوشنبه | 19:00 – 21:00' + ); + assert.equal(formatClassSchedule({}), ''); + }); +}); diff --git a/src/views/classes/ClassDetailView.vue b/src/views/classes/ClassDetailView.vue index e7dfd99..720aac0 100644 --- a/src/views/classes/ClassDetailView.vue +++ b/src/views/classes/ClassDetailView.vue @@ -33,6 +33,14 @@ {{ formatJalali(classData.startDate) }} — {{ formatJalali(classData.endDate) }} +