From c82701888ae2f4646cb1a704a06cc9d029470ee3 Mon Sep 17 00:00:00 2001 From: sajjadtalkhabi <97734061+sajjadtalkhabi@users.noreply.github.com> Date: Fri, 15 May 2026 17:12:51 +0330 Subject: [PATCH] fix --- .eslintrc.cjs | 2 +- jsconfig.json | 2 + package-lock.json | 26 ++ package.json | 2 + scripts/vite-icon-names.js | 52 +++ src/assets/icons/chat-centered-dots.svg | 13 + src/assets/icons/heart.svg | 10 + src/assets/icons/link.svg | 4 + src/assets/icons/map-pin-simple-area.svg | 12 + src/assets/icons/microphone.svg | 12 + src/assets/icons/mood.svg | 2 +- src/assets/icons/paper-plane-right.svg | 2 +- src/assets/icons/scroll.svg | 13 + src/components/BaseButton.vue | 1 + src/components/blocks/TabsBlock.vue | 144 ++++-- src/components/blocks/VideoPlayerBlock.vue | 95 ++++ src/components/form/CheckboxField.vue | 79 ++++ src/components/form/ImageUploader.vue | 231 ++++++++++ src/components/form/VoiceRecorder.vue | 422 ++++++++++++++++++ src/components/icons/SvgIcon.vue | 6 +- src/components/icons/icon-names.d.ts | 48 ++ .../admin/courses/pages/CoursesListPage.vue | 73 +-- .../components/CertificateItem.vue | 236 ++++++++++ .../pages/StudentCertificatesPage.vue | 94 ++++ .../consultants/components/ConsultantItem.vue | 107 +++++ .../components/RequestConsultantForm.vue | 141 ++++++ .../pages/StudentConsultantsPage.vue | 110 +++++ .../components/StudentCourseItem.vue | 0 .../pages/StudentCourseDetailsPage.vue | 0 .../pages/StudentCoursesPage.vue | 2 +- .../components/StudentExamAttemptItem.vue | 147 ++++++ .../exams/components/StudentExamItem.vue | 143 ++++++ .../exams/components/StudentExamQuestion.vue | 66 +++ .../exams/components/StudentExamSummary.vue | 216 +++++++++ .../student/exams/pages/StudentExamPage.vue | 117 +++++ .../exams/pages/StudentTakeExamPage.vue | 258 +++++++++++ .../lessons/components/StudentLessonItem.vue | 190 ++++++++ .../pages/StudentLessonDetailsPage.vue | 226 ++++++++++ .../components/MissionaryDispatchItem.vue | 174 ++++++++ .../components/MissionaryNarrativeItem.vue | 177 ++++++++ .../components/MissionaryRequestItem.vue | 257 +++++++++++ .../components/MissionaryUserCard.vue | 257 +++++++++++ .../modals/DispatchDetailsModal.vue | 72 +++ .../modals/NarrativeDetailsModal.vue | 123 +++++ .../components/modals/RequestDetailsModal.vue | 71 +++ .../pages/StudentMissionaryPage.vue | 203 +++++++++ .../{ => profile}/pages/EditProfilePage.vue | 2 +- .../student/{ => profile}/schema/index.js | 0 src/features/student/router.js | 66 ++- .../services/components/CreateServiceForm.vue | 251 +++++++++++ .../services/components/ServiceItem.vue | 106 +++++ .../services/pages/StudentServicesPage.vue | 116 +++++ .../components/StudentSessionItem.vue | 162 +++++++ .../pages/StudentSessionDetailsPage.vue | 306 +++++++++++++ .../terms/components/StudentTermItem.vue | 280 ++++++++++++ .../terms/components/StudentTermSummary.vue | 227 ++++++++++ .../terms/pages/StudentTermDetailsPage.vue | 77 ++++ .../student/terms/pages/StudentTermsPage.vue | 128 ++++++ src/global-components/Badge.vue | 137 ++++++ src/global-components/Tinymce.vue | 120 +++++ src/layouts/StudentLayout.vue | 36 ++ src/layouts/sidebars/StudentSidebar.vue | 6 +- src/plugins/tinymce/importTinymce.js | 35 ++ src/plugins/tinymce/langs/fa_IR.js | 392 ++++++++++++++++ src/plugins/tinymce/tinymce.js | 30 ++ src/services/api/endpoints.js | 25 ++ src/services/api/student-certificates.js | 8 + src/services/api/student-consultants.js | 10 + src/services/api/student-exams.js | 10 + src/services/api/student-lessons.js | 4 + src/services/api/student-missionary.js | 13 + src/services/api/student-services.js | 12 + src/services/api/student-sessions.js | 8 + src/services/api/student-terms.js | 6 + src/services/mock/fixtures/profile.js | 2 +- .../mock/fixtures/student-certificates.js | 32 ++ .../mock/fixtures/student-consultants.js | 50 +++ src/services/mock/fixtures/student-exams.js | 94 ++++ src/services/mock/fixtures/student-lessons.js | 93 ++++ .../mock/fixtures/student-missionary.js | 157 +++++++ .../mock/fixtures/student-services.js | 61 +++ .../mock/fixtures/student-sessions.js | 14 + src/services/mock/fixtures/student-terms.js | 75 ++++ .../mock/routes/student-certificates.js | 15 + .../mock/routes/student-consultants.js | 29 ++ src/services/mock/routes/student-exams.js | 27 ++ src/services/mock/routes/student-lessons.js | 11 + .../mock/routes/student-missionary.js | 21 + src/services/mock/routes/student-services.js | 33 ++ src/services/mock/routes/student-sessions.js | 14 + src/services/mock/routes/student-terms.js | 21 + src/services/query/student-certificates.js | 25 ++ src/services/query/student-consultants.js | 35 ++ src/services/query/student-exams.js | 26 ++ src/services/query/student-lessons.js | 14 + src/services/query/student-missionary.js | 56 +++ src/services/query/student-services.js | 45 ++ src/services/query/student-sessions.js | 22 + src/services/query/student-terms.js | 28 ++ src/styles/plugins/tinymce.css | 7 + vite.config.js | 3 +- 101 files changed, 8125 insertions(+), 96 deletions(-) create mode 100644 scripts/vite-icon-names.js create mode 100644 src/assets/icons/chat-centered-dots.svg create mode 100644 src/assets/icons/heart.svg create mode 100644 src/assets/icons/link.svg create mode 100644 src/assets/icons/map-pin-simple-area.svg create mode 100644 src/assets/icons/microphone.svg create mode 100644 src/assets/icons/scroll.svg create mode 100644 src/components/blocks/VideoPlayerBlock.vue create mode 100644 src/components/form/CheckboxField.vue create mode 100644 src/components/form/ImageUploader.vue create mode 100644 src/components/form/VoiceRecorder.vue create mode 100644 src/components/icons/icon-names.d.ts create mode 100644 src/features/student/certificates/components/CertificateItem.vue create mode 100644 src/features/student/certificates/pages/StudentCertificatesPage.vue create mode 100644 src/features/student/consultants/components/ConsultantItem.vue create mode 100644 src/features/student/consultants/components/RequestConsultantForm.vue create mode 100644 src/features/student/consultants/pages/StudentConsultantsPage.vue rename src/features/student/{ => courses}/components/StudentCourseItem.vue (100%) rename src/features/student/{ => courses}/pages/StudentCourseDetailsPage.vue (100%) rename src/features/student/{ => courses}/pages/StudentCoursesPage.vue (97%) create mode 100644 src/features/student/exams/components/StudentExamAttemptItem.vue create mode 100644 src/features/student/exams/components/StudentExamItem.vue create mode 100644 src/features/student/exams/components/StudentExamQuestion.vue create mode 100644 src/features/student/exams/components/StudentExamSummary.vue create mode 100644 src/features/student/exams/pages/StudentExamPage.vue create mode 100644 src/features/student/exams/pages/StudentTakeExamPage.vue create mode 100644 src/features/student/lessons/components/StudentLessonItem.vue create mode 100644 src/features/student/lessons/pages/StudentLessonDetailsPage.vue create mode 100644 src/features/student/missionary/components/MissionaryDispatchItem.vue create mode 100644 src/features/student/missionary/components/MissionaryNarrativeItem.vue create mode 100644 src/features/student/missionary/components/MissionaryRequestItem.vue create mode 100644 src/features/student/missionary/components/MissionaryUserCard.vue create mode 100644 src/features/student/missionary/components/modals/DispatchDetailsModal.vue create mode 100644 src/features/student/missionary/components/modals/NarrativeDetailsModal.vue create mode 100644 src/features/student/missionary/components/modals/RequestDetailsModal.vue create mode 100644 src/features/student/missionary/pages/StudentMissionaryPage.vue rename src/features/student/{ => profile}/pages/EditProfilePage.vue (99%) rename src/features/student/{ => profile}/schema/index.js (100%) create mode 100644 src/features/student/services/components/CreateServiceForm.vue create mode 100644 src/features/student/services/components/ServiceItem.vue create mode 100644 src/features/student/services/pages/StudentServicesPage.vue create mode 100644 src/features/student/sessions/components/StudentSessionItem.vue create mode 100644 src/features/student/sessions/pages/StudentSessionDetailsPage.vue create mode 100644 src/features/student/terms/components/StudentTermItem.vue create mode 100644 src/features/student/terms/components/StudentTermSummary.vue create mode 100644 src/features/student/terms/pages/StudentTermDetailsPage.vue create mode 100644 src/features/student/terms/pages/StudentTermsPage.vue create mode 100644 src/global-components/Badge.vue create mode 100644 src/global-components/Tinymce.vue create mode 100644 src/plugins/tinymce/importTinymce.js create mode 100644 src/plugins/tinymce/langs/fa_IR.js create mode 100644 src/plugins/tinymce/tinymce.js create mode 100644 src/services/api/student-certificates.js create mode 100644 src/services/api/student-consultants.js create mode 100644 src/services/api/student-exams.js create mode 100644 src/services/api/student-lessons.js create mode 100644 src/services/api/student-missionary.js create mode 100644 src/services/api/student-services.js create mode 100644 src/services/api/student-sessions.js create mode 100644 src/services/api/student-terms.js create mode 100644 src/services/mock/fixtures/student-certificates.js create mode 100644 src/services/mock/fixtures/student-consultants.js create mode 100644 src/services/mock/fixtures/student-exams.js create mode 100644 src/services/mock/fixtures/student-lessons.js create mode 100644 src/services/mock/fixtures/student-missionary.js create mode 100644 src/services/mock/fixtures/student-services.js create mode 100644 src/services/mock/fixtures/student-sessions.js create mode 100644 src/services/mock/fixtures/student-terms.js create mode 100644 src/services/mock/routes/student-certificates.js create mode 100644 src/services/mock/routes/student-consultants.js create mode 100644 src/services/mock/routes/student-exams.js create mode 100644 src/services/mock/routes/student-lessons.js create mode 100644 src/services/mock/routes/student-missionary.js create mode 100644 src/services/mock/routes/student-services.js create mode 100644 src/services/mock/routes/student-sessions.js create mode 100644 src/services/mock/routes/student-terms.js create mode 100644 src/services/query/student-certificates.js create mode 100644 src/services/query/student-consultants.js create mode 100644 src/services/query/student-exams.js create mode 100644 src/services/query/student-lessons.js create mode 100644 src/services/query/student-missionary.js create mode 100644 src/services/query/student-services.js create mode 100644 src/services/query/student-sessions.js create mode 100644 src/services/query/student-terms.js create mode 100644 src/styles/plugins/tinymce.css diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 8f04671..9640921 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -6,7 +6,7 @@ module.exports = { es2021: true, }, plugins: ['prettier', 'unicorn', 'import', 'waterfall'], - ignorePatterns: ['node_modules/', 'dist/', 'build/', '*.min.js'], + ignorePatterns: ['node_modules/', 'dist/', 'build/', '*.min.js', 'src/components/icons/icon-names.d.ts'], parserOptions: { ecmaVersion: 2021, sourceType: 'module', diff --git a/jsconfig.json b/jsconfig.json index 686295e..85cbc8d 100644 --- a/jsconfig.json +++ b/jsconfig.json @@ -1,9 +1,11 @@ { "compilerOptions": { "baseUrl": ".", + "checkJs": false, "paths": { "@/*": ["src/*"] } }, + "include": ["src/**/*", "src/**/*.d.ts"], "exclude": ["node_modules", "dist"] } diff --git a/package-lock.json b/package-lock.json index 08f0882..fd14004 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,9 +11,11 @@ "@floating-ui/dom": "^1.7.6", "@tanstack/vue-query": "^5.62.2", "@tanstack/vue-query-devtools": "^5.62.2", + "@tinymce/tinymce-vue": "^4.0.7", "axios": "^1.12.2", "lodash": "^4.18.1", "pinia": "^3.0.3", + "tinymce": "^8.5.0", "vue": "^3.5.21", "vue-advanced-cropper": "^2.8.9", "vue-router": "^4.5.1", @@ -1671,6 +1673,24 @@ } } }, + "node_modules/@tinymce/tinymce-vue": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@tinymce/tinymce-vue/-/tinymce-vue-4.0.7.tgz", + "integrity": "sha512-1esB8wGWrjPCY+rK8vy3QB1cxwXo7HLJWuNrcyPl6LOVR+QJjub0OiV/C+TUEsLN6OpCtRv+QnIqMC5vXz783Q==", + "license": "Apache-2.0", + "dependencies": { + "tinymce": "^5.5.0" + }, + "peerDependencies": { + "vue": "^3.0.0" + } + }, + "node_modules/@tinymce/tinymce-vue/node_modules/tinymce": { + "version": "5.10.9", + "resolved": "https://registry.npmjs.org/tinymce/-/tinymce-5.10.9.tgz", + "integrity": "sha512-5bkrors87X9LhYX2xq8GgPHrIgJYHl87YNs+kBcjQ5I3CiUgzo/vFcGvT3MZQ9QHsEeYMhYO6a5CLGGffR8hMg==", + "license": "LGPL-2.1" + }, "node_modules/@types/esrecurse": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/@types/esrecurse/-/esrecurse-4.3.1.tgz", @@ -7201,6 +7221,12 @@ "url": "https://github.com/sponsors/SuperchupuDev" } }, + "node_modules/tinymce": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/tinymce/-/tinymce-8.5.0.tgz", + "integrity": "sha512-DnKEfPNQnOJc8Ca1roZBs/GSbkAZyIIbC4p8eHZyZQi85OSAXtiVNYMaRxo4mzsGKpa0sA4/Us4KXQkX8q7w2A==", + "license": "SEE LICENSE IN license.md" + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", diff --git a/package.json b/package.json index 0297ccd..bc83a12 100644 --- a/package.json +++ b/package.json @@ -18,9 +18,11 @@ "@floating-ui/dom": "^1.7.6", "@tanstack/vue-query": "^5.62.2", "@tanstack/vue-query-devtools": "^5.62.2", + "@tinymce/tinymce-vue": "^4.0.7", "axios": "^1.12.2", "lodash": "^4.18.1", "pinia": "^3.0.3", + "tinymce": "^8.5.0", "vue": "^3.5.21", "vue-advanced-cropper": "^2.8.9", "vue-router": "^4.5.1", diff --git a/scripts/vite-icon-names.js b/scripts/vite-icon-names.js new file mode 100644 index 0000000..1ec9211 --- /dev/null +++ b/scripts/vite-icon-names.js @@ -0,0 +1,52 @@ +import fs from 'node:fs' +import path from 'node:path' +import { fileURLToPath } from 'node:url' + +const __dirname = path.dirname(fileURLToPath(import.meta.url)) +const ICONS_DIR = path.resolve(__dirname, '../src/assets/icons') +const OUTPUT_FILE = path.resolve(__dirname, '../src/components/icons/icon-names.d.ts') + +const readNames = () => + fs + .readdirSync(ICONS_DIR) + .filter((f) => f.endsWith('.svg')) + .map((f) => f.replace(/\.svg$/, '')) + .sort() + +const buildContent = (names) => { + const union = names.length > 0 ? names.map((n) => ` | '${n}'`).join('\n') : ' | never' + return `// AUTO-GENERATED — do not edit by hand. +// Regenerated whenever src/assets/icons/*.svg changes (via scripts/vite-icon-names.js). + +export type IconName = +${union} + +export const iconNames: readonly IconName[] +` +} + +const writeIfChanged = () => { + const content = buildContent(readNames()) + const prev = fs.existsSync(OUTPUT_FILE) ? fs.readFileSync(OUTPUT_FILE, 'utf8') : '' + if (prev !== content) fs.writeFileSync(OUTPUT_FILE, content) +} + +export default function viteIconNames() { + return { + name: 'vite-icon-names', + buildStart() { + writeIfChanged() + }, + configureServer(server) { + writeIfChanged() + server.watcher.add(path.join(ICONS_DIR, '*.svg')) + const handler = (file) => { + if (file.startsWith(ICONS_DIR) && file.endsWith('.svg')) writeIfChanged() + } + server.watcher.on('add', handler) + server.watcher.on('unlink', handler) + }, + } +} + +export { writeIfChanged as generateIconNames } diff --git a/src/assets/icons/chat-centered-dots.svg b/src/assets/icons/chat-centered-dots.svg new file mode 100644 index 0000000..36aeefa --- /dev/null +++ b/src/assets/icons/chat-centered-dots.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/src/assets/icons/heart.svg b/src/assets/icons/heart.svg new file mode 100644 index 0000000..9857326 --- /dev/null +++ b/src/assets/icons/heart.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/assets/icons/link.svg b/src/assets/icons/link.svg new file mode 100644 index 0000000..1eba376 --- /dev/null +++ b/src/assets/icons/link.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/icons/map-pin-simple-area.svg b/src/assets/icons/map-pin-simple-area.svg new file mode 100644 index 0000000..d118d44 --- /dev/null +++ b/src/assets/icons/map-pin-simple-area.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/src/assets/icons/microphone.svg b/src/assets/icons/microphone.svg new file mode 100644 index 0000000..cc7f90d --- /dev/null +++ b/src/assets/icons/microphone.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/src/assets/icons/mood.svg b/src/assets/icons/mood.svg index e146bf6..4c152d5 100644 --- a/src/assets/icons/mood.svg +++ b/src/assets/icons/mood.svg @@ -1,3 +1,3 @@ - + diff --git a/src/assets/icons/paper-plane-right.svg b/src/assets/icons/paper-plane-right.svg index 64b1606..8200eed 100644 --- a/src/assets/icons/paper-plane-right.svg +++ b/src/assets/icons/paper-plane-right.svg @@ -1,4 +1,4 @@ - + diff --git a/src/assets/icons/scroll.svg b/src/assets/icons/scroll.svg new file mode 100644 index 0000000..fc05661 --- /dev/null +++ b/src/assets/icons/scroll.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/src/components/BaseButton.vue b/src/components/BaseButton.vue index f203790..8d0b7b4 100644 --- a/src/components/BaseButton.vue +++ b/src/components/BaseButton.vue @@ -79,6 +79,7 @@ const handleClick = (event) => { font-family: var(--font-family-fa); text-decoration: none; padding: 0 1rem; + white-space: nowrap; &__text { line-height: 1.25rem; diff --git a/src/components/blocks/TabsBlock.vue b/src/components/blocks/TabsBlock.vue index 70d8cfa..281d142 100644 --- a/src/components/blocks/TabsBlock.vue +++ b/src/components/blocks/TabsBlock.vue @@ -1,23 +1,57 @@
- +
+ +
- - {{ tab.label }} - + + + +
+ +
+ + + +
+
@@ -26,7 +60,7 @@ diff --git a/src/components/form/CheckboxField.vue b/src/components/form/CheckboxField.vue new file mode 100644 index 0000000..cf3a19e --- /dev/null +++ b/src/components/form/CheckboxField.vue @@ -0,0 +1,79 @@ + + + + + diff --git a/src/components/form/ImageUploader.vue b/src/components/form/ImageUploader.vue new file mode 100644 index 0000000..105ea10 --- /dev/null +++ b/src/components/form/ImageUploader.vue @@ -0,0 +1,231 @@ + + + + + diff --git a/src/components/form/VoiceRecorder.vue b/src/components/form/VoiceRecorder.vue new file mode 100644 index 0000000..d13ab3b --- /dev/null +++ b/src/components/form/VoiceRecorder.vue @@ -0,0 +1,422 @@ + + + + + diff --git a/src/components/icons/SvgIcon.vue b/src/components/icons/SvgIcon.vue index 4bdac10..fc37433 100644 --- a/src/components/icons/SvgIcon.vue +++ b/src/components/icons/SvgIcon.vue @@ -14,10 +14,13 @@ import { computed } from 'vue' import { iconRegistry } from '@/components/icons/registry' +/** @typedef {import('@/components/icons/icon-names').IconName} IconName */ + const props = defineProps({ + /** @type {import('vue').PropType} */ name: { type: String, required: true }, size: { type: [String, Number], default: '1.25rem' }, - color: { type: String, default: 'currentColor' }, + color: { type: String, default: 'transparent' }, }) const component = computed(() => { @@ -25,6 +28,7 @@ const component = computed(() => { if (!c && import.meta.env.DEV) { console.warn(`[SvgIcon] unknown icon "${props.name}"`) } + return c }) diff --git a/src/components/icons/icon-names.d.ts b/src/components/icons/icon-names.d.ts new file mode 100644 index 0000000..c261638 --- /dev/null +++ b/src/components/icons/icon-names.d.ts @@ -0,0 +1,48 @@ +// AUTO-GENERATED — do not edit by hand. +// Regenerated whenever src/assets/icons/*.svg changes (via scripts/vite-icon-names.js). + +export type IconName = + | 'arrow-left' + | 'arrows-clockwise' + | 'attach-file' + | 'bell' + | 'book' + | 'calendar' + | 'caret-down' + | 'caret-left' + | 'caret-right' + | 'chat' + | 'chat-centered-dots' + | 'check' + | 'check-square' + | 'close' + | 'copy' + | 'eye' + | 'eye-slash' + | 'file' + | 'funnel' + | 'heart' + | 'instagram' + | 'link' + | 'list-bullets' + | 'map-pin-simple-area' + | 'menu' + | 'microphone' + | 'mood' + | 'paper-plane' + | 'paper-plane-right' + | 'pencil' + | 'phone' + | 'plus' + | 'scroll' + | 'spinner' + | 'square' + | 'telegram' + | 'trash' + | 'upload' + | 'user' + | 'users' + | 'users-three' + | 'warning' + +export const iconNames: readonly IconName[] diff --git a/src/features/admin/courses/pages/CoursesListPage.vue b/src/features/admin/courses/pages/CoursesListPage.vue index 752817a..f38afe4 100644 --- a/src/features/admin/courses/pages/CoursesListPage.vue +++ b/src/features/admin/courses/pages/CoursesListPage.vue @@ -17,26 +17,6 @@ @reset="onFilterReset" /> -
- - - - - - -
-