fix: user changes
This commit is contained in:
@@ -67,7 +67,7 @@ const emit = defineEmits(['delete'])
|
||||
const teacherName = computed(() => {
|
||||
const t = props.course.teacher
|
||||
if (!t) return '—'
|
||||
return `${t.firstName || ''} ${t.lastName || ''}`.trim() || t.fullName || '—'
|
||||
return t.name
|
||||
})
|
||||
|
||||
const isActive = computed(() => props.course.isActive ?? false)
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
<template>
|
||||
<BasicModal width="95%" max-width="42rem" min-width="auto" :show-close-button="true">
|
||||
<BasicModal
|
||||
title="افزودن دانشجو"
|
||||
title-en="Add Student"
|
||||
width="95%"
|
||||
max-width="42rem"
|
||||
min-width="auto"
|
||||
:show-close-button="true"
|
||||
>
|
||||
<template #default="{ close }">
|
||||
<div class="add-term-student">
|
||||
<LineTitleBlock title="افزودن دانشجو" title-en="Add Student" />
|
||||
|
||||
<div class="add-term-student__search">
|
||||
<SvgIcon name="user" :size="18" color="var(--color-thd-gray)" />
|
||||
<input
|
||||
@@ -37,20 +42,6 @@
|
||||
</div>
|
||||
|
||||
<CircleButton
|
||||
v-if="isAttached(user.id)"
|
||||
tooltip="حذف از ترم"
|
||||
bg-color="rgba(104, 104, 104, 0.05)"
|
||||
size="2.25rem"
|
||||
type="button"
|
||||
:loading="pendingId === user.id"
|
||||
@click="onDetach(user)"
|
||||
>
|
||||
<template #icon>
|
||||
<SvgIcon name="trash" :size="16" color="var(--color-error)" />
|
||||
</template>
|
||||
</CircleButton>
|
||||
<CircleButton
|
||||
v-else
|
||||
tooltip="افزودن به ترم"
|
||||
bg-color="rgba(104, 104, 104, 0.05)"
|
||||
size="2.25rem"
|
||||
@@ -91,15 +82,9 @@ import BaseButton from '@/components/BaseButton.vue'
|
||||
import SvgIcon from '@/components/icons/SvgIcon.vue'
|
||||
import NoItems from '@/components/blocks/NoItems.vue'
|
||||
import CircleButton from '@/components/CircleButton.vue'
|
||||
import LineTitleBlock from '@/components/LineTitleBlock.vue'
|
||||
import { useAdminUsersListQuery } from '@/services/query/admin-users'
|
||||
import SkeletonLoaderBlock from '@/components/blocks/SkeletonLoaderBlock.vue'
|
||||
import {
|
||||
adminTermsKeys,
|
||||
useAddAdminTermStudentsMutation,
|
||||
useAdminTermStudentsQuery,
|
||||
useRemoveAdminTermStudentMutation,
|
||||
} from '@/services/query/admin-terms'
|
||||
import { adminTermsKeys, useAddAdminTermStudentsMutation } from '@/services/query/admin-terms'
|
||||
|
||||
defineOptions({ name: 'AddTermStudentModal' })
|
||||
|
||||
@@ -111,29 +96,13 @@ const termId = computed(() => modalData.value.termId ?? null)
|
||||
|
||||
const searchInput = ref('')
|
||||
const searchQuery = ref('')
|
||||
const userFilters = computed(() => ({ name: searchQuery.value }))
|
||||
const userPagination = ref({ page: 1, perPage: 20 })
|
||||
const userFilters = computed(() => ({ search: searchQuery.value }))
|
||||
const userPagination = ref({ page: 1, perPage: 10 })
|
||||
|
||||
const { data: usersResponse, isLoading } = useAdminUsersListQuery(userFilters, userPagination)
|
||||
const users = computed(() => usersResponse.value?.data ?? [])
|
||||
|
||||
const attachedFilters = computed(() => ({}))
|
||||
const attachedPagination = ref({ page: 1, perPage: 200 })
|
||||
const { data: attachedResponse } = useAdminTermStudentsQuery(
|
||||
termId,
|
||||
attachedFilters,
|
||||
attachedPagination,
|
||||
{ enabled: () => !!termId.value }
|
||||
)
|
||||
const attachedIds = computed(() => new Set((attachedResponse.value?.data ?? []).map((u) => u.id)))
|
||||
|
||||
const isAttached = (id) => attachedIds.value.has(id)
|
||||
|
||||
const userLabel = (user) =>
|
||||
`${user.firstName || ''} ${user.lastName || ''}`.trim() ||
|
||||
user.fullName ||
|
||||
user.phoneNumber ||
|
||||
'—'
|
||||
const userLabel = (user) => user.name.trim() || '—'
|
||||
|
||||
const onSearchInput = useDebounce(() => {
|
||||
searchQuery.value = searchInput.value || ''
|
||||
@@ -143,7 +112,6 @@ const onSearchInput = useDebounce(() => {
|
||||
const pendingId = ref(null)
|
||||
|
||||
const addMutation = useAddAdminTermStudentsMutation()
|
||||
const removeMutation = useRemoveAdminTermStudentMutation()
|
||||
|
||||
const invalidate = () => queryClient.invalidateQueries({ queryKey: adminTermsKeys.all })
|
||||
|
||||
@@ -153,7 +121,7 @@ const onAttach = async (user) => {
|
||||
try {
|
||||
await addMutation.mutateAsync({
|
||||
termId: termId.value,
|
||||
payload: { userIds: [user.id] },
|
||||
payload: { userId: user.id },
|
||||
})
|
||||
invalidate()
|
||||
} finally {
|
||||
@@ -161,17 +129,6 @@ const onAttach = async (user) => {
|
||||
}
|
||||
}
|
||||
|
||||
const onDetach = async (user) => {
|
||||
if (!termId.value) return
|
||||
pendingId.value = user.id
|
||||
try {
|
||||
await removeMutation.mutateAsync({ termId: termId.value, userId: user.id })
|
||||
invalidate()
|
||||
} finally {
|
||||
pendingId.value = null
|
||||
}
|
||||
}
|
||||
|
||||
watch(termId, () => {
|
||||
searchInput.value = ''
|
||||
searchQuery.value = ''
|
||||
@@ -293,7 +250,7 @@ watch(termId, () => {
|
||||
|
||||
&__footer {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
&__close-btn {
|
||||
|
||||
@@ -1,15 +1,21 @@
|
||||
<template>
|
||||
<BasicModal width="95%" max-width="80rem" min-width="auto" :show-close-button="true">
|
||||
<template #default="{ data, close }">
|
||||
<BasicModal
|
||||
title="جزئیات ترم"
|
||||
title-en="Term Details"
|
||||
width="95%"
|
||||
max-width="80rem"
|
||||
min-width="auto"
|
||||
:show-close-button="true"
|
||||
>
|
||||
<template #default="{ close }">
|
||||
<div v-if="!term" class="term-details">
|
||||
<p class="term-details__loading">در حال بارگذاری…</p>
|
||||
</div>
|
||||
<div v-else class="term-details">
|
||||
<section class="term-details__section">
|
||||
<LineTitleBlock title="جزئیات ترم" title-en="Term Details" />
|
||||
<div class="term-details__overview">
|
||||
<div class="term-details__image">
|
||||
<img v-if="term.image" :src="term.image" :alt="term.title" />
|
||||
<img v-if="term.coverUrl" :src="term.coverUrl" :alt="term.title" />
|
||||
<SvgIcon v-else name="book" :size="32" color="#bcbcbc" />
|
||||
</div>
|
||||
<div class="term-details__overview-grid">
|
||||
@@ -51,19 +57,19 @@
|
||||
<div v-else-if="students.length > 0">
|
||||
<div v-for="student in students" :key="student.id" class="term-details__student-row">
|
||||
<div class="term-details__student-main">
|
||||
<div v-if="studentAvatar(student)" class="term-details__avatar">
|
||||
<img :src="studentAvatar(student)" :alt="student.name" />
|
||||
<div v-if="studentAvatar(student?.user)" class="term-details__avatar">
|
||||
<img :src="studentAvatar(student?.user)" :alt="student.name" />
|
||||
</div>
|
||||
<div v-else class="term-details__avatar term-details__avatar--placeholder">
|
||||
<SvgIcon name="user" :size="20" color="#bcbcbc" />
|
||||
</div>
|
||||
<div>
|
||||
<p class="term-details__student-name">{{ student.name || '—' }}</p>
|
||||
<p class="term-details__student-name">{{ student?.user?.name || '—' }}</p>
|
||||
<p class="term-details__student-meta">
|
||||
<span dir="ltr">{{ student.phone || '—' }}</span>
|
||||
<template v-if="student.email">
|
||||
<span dir="ltr">{{ student?.user.phone || '—' }}</span>
|
||||
<template v-if="student?.user.email">
|
||||
<span class="term-details__sep">،</span>
|
||||
<span dir="ltr">{{ student.email }}</span>
|
||||
<span dir="ltr">{{ student?.user.email }}</span>
|
||||
</template>
|
||||
</p>
|
||||
</div>
|
||||
@@ -114,7 +120,6 @@
|
||||
</BaseButton>
|
||||
</div>
|
||||
</div>
|
||||
<span class="term-details__data-tap" v-if="false">{{ data }}</span>
|
||||
</template>
|
||||
</BasicModal>
|
||||
</template>
|
||||
@@ -135,12 +140,12 @@ import LineTitleBlock from '@/components/LineTitleBlock.vue'
|
||||
import LineInfoBlock from '@/components/blocks/LineInfoBlock.vue'
|
||||
import PaginationBlock from '@/components/blocks/PaginationBlock.vue'
|
||||
import SkeletonLoaderBlock from '@/components/blocks/SkeletonLoaderBlock.vue'
|
||||
import { useAdminTermEnrolleesQuery, useAdminTermQuery } from '@/services/query/admin-terms'
|
||||
import {
|
||||
adminCoursesKeys,
|
||||
useAdminCoursesListQuery,
|
||||
useUpdateAdminCourseMutation,
|
||||
} from '@/services/query/admin-courses'
|
||||
import { useAdminTermQuery, useTermAttendeesQuery } from '@/services/query/admin-terms'
|
||||
|
||||
defineOptions({ name: 'TermDetailsModal' })
|
||||
|
||||
@@ -167,7 +172,7 @@ const {
|
||||
reset: resetStudentPagination,
|
||||
} = usePagination({ page: 1, perPage: 10 })
|
||||
|
||||
const { data: studentsData, isLoading: studentsPending } = useTermAttendeesQuery(
|
||||
const { data: studentsData, isLoading: studentsPending } = useAdminTermEnrolleesQuery(
|
||||
termId,
|
||||
studentFilters,
|
||||
studentPagination,
|
||||
|
||||
Reference in New Issue
Block a user