diff --git a/public/personnel-info-bg-dark.png b/public/personnel-info-bg-dark.png new file mode 100644 index 00000000..c804aa9b Binary files /dev/null and b/public/personnel-info-bg-dark.png differ diff --git a/public/personnel-info-bg-light.png b/public/personnel-info-bg-light.png new file mode 100644 index 00000000..ecf25c97 Binary files /dev/null and b/public/personnel-info-bg-light.png differ diff --git a/src/i18n/en-US/user.ts b/src/i18n/en-US/user.ts index f4288221..7ae894b5 100644 --- a/src/i18n/en-US/user.ts +++ b/src/i18n/en-US/user.ts @@ -2,4 +2,7 @@ export default { firstname: 'First Name', lastname: 'Last Name', fullname: 'Full Name', + userType: 'User Type', + userRole: 'User Role', + userCode: 'User Id', }; diff --git a/src/i18n/th-th/user.ts b/src/i18n/th-th/user.ts index 27e8d431..60d38d10 100644 --- a/src/i18n/th-th/user.ts +++ b/src/i18n/th-th/user.ts @@ -2,4 +2,7 @@ export default { firstname: 'ชื่อ', lastname: 'นามสกุล', fullname: 'ชื่อ-นามสกุล', + userType: 'ประเภทผู้ใช้งาน', + userRole: 'สิทธิ์ผู้ใช้งาน', + userCode: 'รหัสพนักงาน', }; diff --git a/src/pages/02_personnel-management/MainPage.vue b/src/pages/02_personnel-management/MainPage.vue index d949c268..71ef3cdd 100644 --- a/src/pages/02_personnel-management/MainPage.vue +++ b/src/pages/02_personnel-management/MainPage.vue @@ -7,12 +7,7 @@ import useUserStore from 'stores/user'; import useBranchStore from 'src/stores/branch'; import { dialog } from 'src/stores/utils'; -import { - UserCreate, - UserTypeStats, - UserOption, - RoleData, -} from 'src/stores/user/types'; +import { UserCreate, UserTypeStats, RoleData } from 'src/stores/user/types'; import { BranchUserStats } from 'src/stores/branch/types'; import PersonCard from 'components/home/PersonCard.vue'; @@ -116,23 +111,6 @@ inputFile.addEventListener('change', (e) => { profileFile.value = (e.currentTarget as HTMLInputElement).files?.[0]; }); -const userTypeOpts = [ - { label: 'พนักงาน', value: 'USER' }, - { label: 'พนักงานส่งเอกสาร', value: 'MESSENGER' }, - { label: 'ตัวแทน', value: 'DELEGATE' }, - { label: 'เอเจนซี่', value: 'AGENCY' }, -]; -const genderOpts = [ - { label: 'ชาย', value: 'male' }, - { label: 'หญิง', value: 'female' }, -]; - -const userOption = ref({ - hqOpts: [], - brOpts: [], - roleOpts: [], -}); - const selectorList = [ { label: 'personnelSelector1', count: 0 }, { label: 'personnelSelector2', count: 0 }, @@ -150,28 +128,12 @@ async function createKeycloak() { return res.data; } -async function fetchRoleOption() { - const res = await api.get('/keycloak/role'); - res.data.map((item) => { - const formattedName = item.name - .replace(/_/g, ' ') - .toLowerCase() - .split(' ') - .map((word) => word.charAt(0).toUpperCase() + word.slice(1)) - .join(' '); - userOption.value.roleOpts.push({ - label: formattedName, - value: item.id, - }); - }); -} - async function fetchHqOption() { - if (userOption.value.hqOpts.length === 0) { + if (userStore.userOption.hqOpts.length === 0) { const res = await branchStore.fetchList({ pageSize: 999, filter: 'head' }); if (res) { res.result.map((item) => { - userOption.value.hqOpts.push({ + userStore.userOption.hqOpts.push({ label: item.code, value: item.id, }); @@ -186,7 +148,7 @@ async function fetchBrOption(id: string) { }); if (res && res?.branch) { res.branch.map((item) => { - userOption.value.brOpts.push({ + userStore.userOption.brOpts.push({ label: item.code, value: item.id, }); @@ -194,13 +156,17 @@ async function fetchBrOption(id: string) { } } -async function openDialog(id?: string) { - await fetchHqOption(); - await fetchRoleOption(); +async function openDialog(idEdit?: string) { modal.value = true; age.value = ''; - if (id && userData.value) { - const foundUser = userData.value.result.find((user) => user.id === id); + if (userStore.userOption.hqOpts.length === 0) { + await fetchHqOption(); + } + if (userStore.userOption.roleOpts.length === 0) { + await userStore.fetchRoleOption(); + } + if (idEdit && userData.value) { + const foundUser = userData.value.result.find((user) => user.id === idEdit); if (foundUser) { formData.value = { @@ -249,7 +215,9 @@ async function openDialog(id?: string) { code.value = foundUser.code; urlProfile.value = foundUser.profileImageUrl; isEdit.value = true; - await fetchBrOption(hqId.value); + if (userStore.userOption.brOpts.length === 0) { + await fetchBrOption(hqId.value); + } await formDialogRef.value.fetchSubDistrict(formData.value.districtId); await formDialogRef.value.fetchDistrict(formData.value.provinceId); } @@ -283,7 +251,7 @@ async function onSubmit() { action: async () => { const formDataEdit = { ...formData.value }; delete formDataEdit.keycloakId; - delete formDataEdit.profileImage; + // delete formDataEdit.profileImage; await userStore.editById(userId.value, formDataEdit); onClose(); userStore.fetchList({ includeBranch: true }); @@ -361,7 +329,7 @@ function calculateAge(birthDate: Date | null): string { async function selectHq(id: string) { if (!id) return; brId.value = ''; - userOption.value.brOpts = []; + userStore.userOption.brOpts = []; await fetchBrOption(id); } @@ -450,7 +418,10 @@ watch( userData?.result.map((v) => ({ id: v.id, img: `${v.profileImageUrl}`, - name: `${v.firstName} ${v.lastName}`, + name: + $i18n.locale === 'en-US' + ? `${v.firstNameEN} ${v.lastNameEN}` + : `${v.firstName} ${v.lastName}`, male: v.gender === 'male', female: v.gender === 'female', detail: [ @@ -522,7 +493,7 @@ watch( option-value="value" label="รหัสสำนักงานใหญ่" v-model="hqId" - :options="userOption.hqOpts" + :options="userStore.userOption.hqOpts" :rules="[(val: string) => !!val || 'กรุณาเลือกสำนักงานใหญ่']" @update:model-value="(val: string) => selectHq(val)" /> @@ -539,7 +510,7 @@ watch( option-label="label" option-value="value" v-model="brId" - :options="userOption.brOpts" + :options="userStore.userOption.brOpts" :rules="[(val: string) => !!val || 'กรุณาเลือกสาขา']" />
- - - + + { getCurrentUser(); getHQ(); getProvince(); + if (userStore.userOption.roleOpts.length === 0) { + userStore.fetchRoleOption(); + } }); watch(() => route.params.id, getCurrentUser); @@ -125,209 +130,358 @@ watch(() => currentUser.value?.districtId, getSubDistrict); @@ -350,4 +504,24 @@ watch(() => currentUser.value?.districtId, getSubDistrict); grid-template-columns: 1fr 4fr; } } + +.info-bg { + background-color: var(--surface-1); + height: 45vw; + background-repeat: no-repeat; + background-size: cover; +} + +.btn-edt { + color: white; + background-color: hsl(var(--info-bg)); + border-radius: var(--radius-2); +} + +.btn-delete { + color: hsl(var(--info-bg)); + background-color: var(--surface-1); + border-radius: var(--radius-2); + border: 1px solid hsl(var(--info-bg)); +} diff --git a/src/stores/user/index.ts b/src/stores/user/index.ts index d5912cfa..f47e3f1c 100644 --- a/src/stores/user/index.ts +++ b/src/stores/user/index.ts @@ -3,18 +3,77 @@ import { defineStore } from 'pinia'; import { Pagination } from '../types'; import { api } from 'src/boot/axios'; import { + RoleData, User, UserAttachment, UserAttachmentCreate, UserAttachmentDelete, UserCreate, + UserOption, } from './types'; import axios from 'axios'; import { Branch } from '../branch/types'; const useUserStore = defineStore('api-user', () => { + const userOption = ref({ + hqOpts: [], + brOpts: [], + roleOpts: [], + userTypeOpts: [ + { label: 'พนักงาน', value: 'USER' }, + { label: 'พนักงานส่งเอกสาร', value: 'MESSENGER' }, + { label: 'ตัวแทน', value: 'DELEGATE' }, + { label: 'เอเจนซี่', value: 'AGENCY' }, + ], + genderOpts: [ + { label: 'ชาย', value: 'male' }, + { label: 'หญิง', value: 'female' }, + ], + responsibleAreaOpts: [ + { label: 'เขตพื้นที่ 1 บางรัก ปทุมวัน ยานนาวสาทร และบางคอแหลม' }, + { label: 'เขตพื้นที่ 2 จอมทอง ทุ่งครุ บางขุนเทียน บางบอน และราษฎร์บูรณะ' }, + { label: 'เขตพื้นที่ 3 คลองเตย บางนา ประเวศ พระโขนง วัฒนา และสวนหลวง' }, + { label: 'เขตพื้นที่ 4 คันนายาว บางกะปิ ลาดพร้าว บึงกุ่ม และวังทางหลาง' }, + { label: 'เขตพื้นที่ 5 คลองสามวา มีนบุรี ลาดกระบัง สะพานสูง หนองจอก และสายไหม' }, + { label: 'เขตพื้นที่ 6 คลองสาน ธนบุรี บางกอกน้อย บางกอกใหญ่ และบางพลัด' }, + { label: 'เขตพื้นที่ 7 ตลิ่งชัน ทวีวัฒนา บางแค ภาษีเจริญ และหนองแขม' }, + { label: 'เขตพื้นที่ 8 ดุสิต พระนครป้อมปราบศัตรูพ่าย และสัมพันธวงศ์' }, + { label: 'เขตพื้นที่ 9 จตุจักร ดอนเมือง บางชื่อ บางเขน และหลักส' }, + { label: 'เขตพื้นที่ 10 ดินแดง พญาไท ราชเทวี และห้วยขวาง' }, + ], + nationalityOpts: [ + { label: 'ไทย', value: 'th' }, + { label: 'เมียนมา', value: 'mm' }, + { label: 'ลาว', value: 'lo' }, + { label: 'กัมพูชา', value: 'kh' }, + { label: 'เวียดนาม', value: 'vn' }, + ], + trainingPlaceOpts: [ + { label: 'สถานที่อบรมแรงงานเมียนมา-แม่สอด จ.ตาก' }, + { label: 'สถานที่อบรมแรงงานเมียนมา- เกาะสอง จ.ระนอง' }, + { label: 'สถานที่อบรมแรงงานลาว-หนองคาย จ.หนองคาย' }, + { label: 'สถานที่อบรมแรงงานกัมพูชา- อรัญประเทศ จ.สระแก้ว' }, + { label: 'สถานที่อบรมแรงงานกัมพูชา-บ้านแหลม จ.จันทบุร' }, + ], + }); const data = ref>(); + async function fetchRoleOption() { + const res = await api.get('/keycloak/role'); + res.data.map((item) => { + const formattedName = item.name + .replace(/_/g, ' ') + .toLowerCase() + .split(' ') + .map((word) => word.charAt(0).toUpperCase() + word.slice(1)) + .join(' '); + userOption.value.roleOpts.push({ + label: formattedName, + value: item.id, + }); + }); + } + async function fetchAttachment( userId: string, flow?: { @@ -228,9 +287,10 @@ const useUserStore = defineStore('api-user', () => { transactionId: string; }, ) { + const { profileImage, ...payload } = data const res = await api.put( `/user/${id}`, - data, + payload, { headers: { 'X-Session-Id': flow?.sessionId, @@ -240,10 +300,10 @@ const useUserStore = defineStore('api-user', () => { }, ); - if (data.profileImage) + if (profileImage) await axios - .put(res.data.profileImageUploadUrl, data.profileImage, { - headers: { 'Content-Type': data.profileImage.type }, + .put(res.data.profileImageUploadUrl, profileImage, { + headers: { 'Content-Type': profileImage.type }, onUploadProgress: (e) => console.log(e), }) .catch((e) => console.error(e)); @@ -368,6 +428,9 @@ const useUserStore = defineStore('api-user', () => { return { data, + userOption, + fetchRoleOption, + fetchList, fetchById, diff --git a/src/stores/user/types.ts b/src/stores/user/types.ts index d383f194..c0a8bb5d 100644 --- a/src/stores/user/types.ts +++ b/src/stores/user/types.ts @@ -100,12 +100,17 @@ export type UserTypeStats = { export type UserOption = { hqOpts: Option[]; brOpts: Option[]; + genderOpts: Option[]; + userTypeOpts: Option[]; roleOpts: Option[]; + responsibleAreaOpts: Option[]; + nationalityOpts: Option[]; + trainingPlaceOpts: Option[]; }; export type Option = { label: string; - value: string; + value?: string; }; export type RoleData = {