diff --git a/src/components/FormDialog.vue b/src/components/FormDialog.vue index ee1cea71..928934c6 100644 --- a/src/components/FormDialog.vue +++ b/src/components/FormDialog.vue @@ -123,7 +123,7 @@ watch(provinceId, (v) => {
@@ -131,7 +131,7 @@ watch(provinceId, (v) => {
{{ $t(v.label) }} -
1
+
{{ v.count }}
diff --git a/src/components/home/PersonCard.vue b/src/components/home/PersonCard.vue index ce416225..ab17ebcd 100644 --- a/src/components/home/PersonCard.vue +++ b/src/components/home/PersonCard.vue @@ -7,6 +7,7 @@ import { Icon } from '@iconify/vue'; defineProps<{ list: { + id: string; name: string; detail: { label: string; value: string }[]; male?: boolean; @@ -18,6 +19,11 @@ defineProps<{ detailColumnCount?: number; }>(); +defineEmits<{ + (e: 'deleteCard', id: string): void; + (e: 'updateCard', id: string): void; +}>(); + const status = ref(false); @@ -55,7 +61,11 @@ const status = ref(false); {{ $t('edit') }} - + -import { ref, onMounted } from 'vue'; -import useUserStore from 'stores/user'; +import { ref, onMounted, watch } from 'vue'; +import { api } from 'src/boot/axios'; import { storeToRefs } from 'pinia'; +import useUserStore from 'stores/user'; +import useBranchStore from 'src/stores/branch'; + +import { UserCreate, UserTypeStats } from 'src/stores/user/types'; +import { BranchUserStats } from 'src/stores/branch/types'; +// import { dateFormat } from 'src/utils/datetime'; import PersonCard from 'components/home/PersonCard.vue'; import AppBox from 'components/app/AppBox.vue'; @@ -10,72 +16,170 @@ import SelectorList from 'components/SelectorList.vue'; import BtnAddComponent from 'components/01_branch-management/BtnAddComponent.vue'; import TooltipComponent from 'components/TooltipComponent.vue'; import FormDialog from 'src/components/FormDialog.vue'; +import GlobalDialog from 'components/GlobalDialog.vue'; +const branchStore = useBranchStore(); const userStore = useUserStore(); const { data: userData } = storeToRefs(userStore); -onMounted(async () => { - await userStore.fetchList(); +const defaultFormData = { + provinceId: null, + districtId: null, + subDistrictId: null, + telephoneNo: '', + email: '', + zipCode: '', + gender: '', + addressEN: '', + address: '', + trainingPlace: null, + importNationality: null, + sourceNationality: null, + licenseExpireDate: null, + licenseIssueDate: null, + licenseNo: null, + discountCondition: '', + retireDate: null, + startDate: null, + registrationNo: null, + lastNameEN: '', + lastName: '', + firstNameEN: '', + firstName: '', + userRole: '', + userType: '', + keycloakId: '', + profileImage: null, + birthDate: null, + responsibleArea: '', +}; +const userId = ref(''); +const modal = ref(false); +const status = ref(false); +const selectorLabel = ref(''); +const hqId = ref(''); +const brId = ref(''); +const username = ref(''); +const formData = ref(structuredClone(defaultFormData)); +const userStats = ref(); +const typeStats = ref(); +const age = ref(); + +const confirmData = ref({ + modal: false, + title: '', + message: '', + icon: '', + action: () => {}, }); -const branchStat = ref([ - { label: 'Branch A', amount: 1 }, - { label: 'Branch B', amount: 5 }, - { label: 'Branch C', amount: 3 }, -]); - -const selectorLabel = ref(''); -const modal = ref(false); - -const hqId = ref(''); -const branchId = ref(''); - -const genderOptions = ref([ - { label: 'ชาย', value: '1' }, - { label: 'หญิง', value: '2' }, -]); - -const hqOptions = ref([ +const userTypeOpts = [ + { label: 'พนักงาน', value: 'USER' }, + { label: 'พนักงานส่งเอกสาร', value: 'MESSENGER' }, + { label: 'ตัวแทน', value: 'DELEGATE' }, + { label: 'เอเจนซี่', value: 'AGENCY' }, +]; +const genderOpts = [ + { label: 'ชาย', value: 'male' }, + { label: 'หญิง', value: 'female' }, +]; +const hqOpts = ref([ { label: '0000000001', value: '1' }, { label: '0000000002', value: '2' }, ]); -const branchOptions = ref([ +const brOpts = ref([ { label: '0000000001-1', value: '1' }, { label: '0000000001-2', value: '2' }, ]); -const formData = ref({ - hqId: '', - branchId: '', - tel: '', - gender: '', - email: '', - addressL: { - address: '', - province: '', - district: '', - subDistrict: '', - zip: '', - }, - addressEng: { - address: '', - province: '', - district: '', - subDistrict: '', - zip: '', - }, -}); - const selectorList = [ { label: 'personnelSelector1', count: 0 }, { label: 'personnelSelector2', count: 0 }, { label: 'personnelSelector3', count: 0 }, { label: 'personnelSelector4', count: 0 }, -] satisfies InstanceType['$props']['list']; +]; + +async function createKeycloak() { + const res = await api.post('/keycloak/user', { + lastName: formData.value.lastNameEN, + firstName: formData.value.firstNameEN, + password: username.value, + username: username.value, + }); + return res.data; +} + +// function selectFile() { +// const fileInput = this.$refs.file; +// fileInput.pickFiles(); +// } function openDialog() { modal.value = true; } + +function onClose() { + modal.value = false; + Object.assign(formData.value, defaultFormData); + hqId.value = ''; + brId.value = ''; + username.value = ''; + userId.value = ''; + mapUserType(selectorLabel.value); +} + +function submitConfirm() { + confirmData.value.modal = true; +} + +async function onSubmit(id?: string) { + try { + if (id) { + await userStore.editById(id, formData.value); + } else { + formData.value.keycloakId = await createKeycloak(); + await userStore.create(formData.value); + } + } finally { + modal.value = false; + await userStore.fetchList(); + } +} + +async function onDelete(id: string) { + await userStore.deleteById(id); + await userStore.fetchList(); +} + +function mapUserType(label: string) { + if (label === 'personnelSelector1') { + formData.value.userType = 'USER'; + } else if (label === 'personnelSelector2') { + formData.value.userType = 'MESSENGER'; + } else if (label === 'personnelSelector3') { + formData.value.userType = 'DELEGATE'; + } else if (label === 'personnelSelector4') { + formData.value.userType = 'AGENCY'; + } +} + +onMounted(async () => { + await userStore.fetchList(); + typeStats.value = await userStore.typeStats(); + if ((await branchStore.userStats(formData.value.userType)) !== false) { + userStats.value = await branchStore.userStats(formData.value.userType); + } +}); + +watch( + () => selectorLabel.value, + async (label) => { + mapUserType(label); + if ((await branchStore.userStats(label)) !== false) { + userStats.value = await branchStore.userStats(label); + } + }, +); + + diff --git a/src/stores/branch/index.ts b/src/stores/branch/index.ts index 6c13dd48..0c00ed0d 100644 --- a/src/stores/branch/index.ts +++ b/src/stores/branch/index.ts @@ -225,6 +225,29 @@ const useBranchStore = defineStore('api-branch', () => { return false; } + async function userStats( + userType: string, + flow?: { + sessionId: string; + refTransactionId: string; + transactionId: string; + }, + ) { + const res = await api.get(`/branch/user-stats`, { + headers: { + 'X-Session-Id': flow?.sessionId, + 'X-Rtid': flow?.refTransactionId, + 'X-Tid': flow?.transactionId, + }, + data: userType + }); + + if (!res) return false; + if (res.status === 200) return res.data; + + return false; + } + return { data, fetchList, @@ -237,6 +260,8 @@ const useBranchStore = defineStore('api-branch', () => { getUser, addUser, removeUser, + + userStats, }; }); diff --git a/src/stores/branch/types.ts b/src/stores/branch/types.ts index b914933d..e2c90d44 100644 --- a/src/stores/branch/types.ts +++ b/src/stores/branch/types.ts @@ -47,3 +47,10 @@ export type BranchCreate = { provinceId?: string | null; headOfficeId?: string | null; }; + +export type BranchUserStats = { + id: string, + nameEN: string, + name: string; + count: 0 +} diff --git a/src/stores/user/index.ts b/src/stores/user/index.ts index 97171cc5..cbb68d6e 100644 --- a/src/stores/user/index.ts +++ b/src/stores/user/index.ts @@ -12,6 +12,7 @@ import { import axios from 'axios'; const useUserStore = defineStore('api-user', () => { + const userStats = ref() const data = ref>(); async function fetchAttachment( @@ -344,6 +345,25 @@ const useUserStore = defineStore('api-user', () => { return res.data || true; } + async function typeStats( + flow?: { + sessionId: string; + refTransactionId: string; + transactionId: string; + },) { + const res = await api.get(`/user/type-stats`, { + headers: { + 'X-Session-Id': flow?.sessionId, + 'X-Rtid': flow?.refTransactionId, + 'X-Tid': flow?.transactionId, + }, + }) + if (!res) return false; + if (res.status === 200) return res.data; + + return false; + } + return { data, fetchList, @@ -360,6 +380,8 @@ const useUserStore = defineStore('api-user', () => { fetchAttachment, addAttachment, deleteAttachment, + + typeStats, }; }); diff --git a/src/stores/user/types.ts b/src/stores/user/types.ts index 4a55fd2c..3e3a895e 100644 --- a/src/stores/user/types.ts +++ b/src/stores/user/types.ts @@ -69,6 +69,8 @@ export type UserCreate = { userType: string; keycloakId: string; profileImage: File; + birthDate?: Date | null; + responsibleArea: string, }; export type UserAttachment = { @@ -83,3 +85,10 @@ export type UserAttachmentCreate = { export type UserAttachmentDelete = { file: string[]; }; + +export type UserTypeStats = { + USER: number; + MESSENGER: number; + DELEGATE: number; + AGENCY: number; +}