diff --git a/public/images/customer-CORP-avartar-female.png b/public/images/customer-CORP-avartar-female.png index 446ef866..4cbb894f 100644 Binary files a/public/images/customer-CORP-avartar-female.png and b/public/images/customer-CORP-avartar-female.png differ diff --git a/public/images/customer-CORP-avartar-male.png b/public/images/customer-CORP-avartar-male.png index 6ad95d7d..ae177f60 100644 Binary files a/public/images/customer-CORP-avartar-male.png and b/public/images/customer-CORP-avartar-male.png differ diff --git a/public/images/customer-PERS-avartar-female.png b/public/images/customer-PERS-avartar-female.png index ca0a2bf1..c3ba574e 100644 Binary files a/public/images/customer-PERS-avartar-female.png and b/public/images/customer-PERS-avartar-female.png differ diff --git a/public/images/customer-PERS-avartar-male.png b/public/images/customer-PERS-avartar-male.png index e9fd15fe..ce0ab20c 100644 Binary files a/public/images/customer-PERS-avartar-male.png and b/public/images/customer-PERS-avartar-male.png differ diff --git a/public/images/employee-avatar-female.png b/public/images/employee-avatar-female.png index 66ace3a0..ce9370f1 100644 Binary files a/public/images/employee-avatar-female.png and b/public/images/employee-avatar-female.png differ diff --git a/public/images/employee-avatar-male.png b/public/images/employee-avatar-male.png index a8daa8ff..aaf5fb1f 100644 Binary files a/public/images/employee-avatar-male.png and b/public/images/employee-avatar-male.png differ diff --git a/public/no-img-female.png b/public/no-img-female.png index 4e177dca..95f959ff 100644 Binary files a/public/no-img-female.png and b/public/no-img-female.png differ diff --git a/public/no-img-man.png b/public/no-img-man.png index 861f356a..f0ccba15 100644 Binary files a/public/no-img-man.png and b/public/no-img-man.png differ diff --git a/src/components/03_customer-management/DialogEmployee.vue b/src/components/03_customer-management/DialogEmployee.vue new file mode 100644 index 00000000..db428f83 --- /dev/null +++ b/src/components/03_customer-management/DialogEmployee.vue @@ -0,0 +1,1656 @@ + + diff --git a/src/components/03_customer-management/DrawerEmployee.vue b/src/components/03_customer-management/DrawerEmployee.vue new file mode 100644 index 00000000..1c1d39bf --- /dev/null +++ b/src/components/03_customer-management/DrawerEmployee.vue @@ -0,0 +1,1772 @@ + + + diff --git a/src/components/03_customer-management/FormEmployeePassport.vue b/src/components/03_customer-management/FormEmployeePassport.vue index 040c9676..06373538 100644 --- a/src/components/03_customer-management/FormEmployeePassport.vue +++ b/src/components/03_customer-management/FormEmployeePassport.vue @@ -20,8 +20,8 @@ const issuePlace = defineModel('issuePlace'); const issueCountry = defineModel('issueCountry'); const issueDate = defineModel('issueDate'); const type = defineModel('type'); -const expireDate = defineModel('expireDate'); -const birthDate = defineModel('birthDate'); +const expireDate = defineModel('expireDate'); +const birthDate = defineModel('birthDate'); const workerStatus = defineModel('workerStatus'); const nationality = defineModel('nationality'); const gender = defineModel('gender'); diff --git a/src/components/03_customer-management/FormEmployeeVisa.vue b/src/components/03_customer-management/FormEmployeeVisa.vue index a5f0f292..7c9085c4 100644 --- a/src/components/03_customer-management/FormEmployeeVisa.vue +++ b/src/components/03_customer-management/FormEmployeeVisa.vue @@ -28,12 +28,12 @@ const arrivalAt = defineModel('arrivalAt'); const arrivalTMNo = defineModel('arrivalTmNo'); const arrivalTM = defineModel('arrivalTm'); const mrz = defineModel('mrz'); -const entryCount = defineModel('entryCount'); +const entryCount = defineModel('entryCount'); const issuePlace = defineModel('issuePlace'); const issueCountry = defineModel('issueCountry'); const issueDate = defineModel('visaIssueDate'); const type = defineModel('type'); -const expireDate = defineModel('expireDate'); +const expireDate = defineModel('expireDate'); const remark = defineModel('remark'); const workerType = defineModel('workerType'); const number = defineModel('number'); diff --git a/src/components/03_customer-management/TableEmpoloyee.vue b/src/components/03_customer-management/TableEmpoloyee.vue index d93c6085..000c701a 100644 --- a/src/components/03_customer-management/TableEmpoloyee.vue +++ b/src/components/03_customer-management/TableEmpoloyee.vue @@ -141,8 +141,9 @@ defineEmits<{ ('drawerOpen', { const myForm = ref(); function reset() { + if (props.beforeClose) { + drawerOpen.value = props.beforeClose + ? props.beforeClose() + : !drawerOpen.value; + } if (myForm.value) { myForm.value.resetValidation(); } @@ -62,7 +67,6 @@ async function onValidationError(ref: any) { @show="show" @before-hide="reset" @hide="close" - @update:model-value="(v) => (drawerOpen = beforeClose ? beforeClose() : v)" :width="$q.screen.gt.xs ? windowSize * 0.85 : windowSize" v-model="drawerOpen" behavior="mobile" diff --git a/src/components/index.ts b/src/components/index.ts index ecca1c1e..4f82d6a8 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -16,3 +16,4 @@ export { default as SideMenu } from './SideMenu.vue'; export { default as StatCardComponent } from './StatCardComponent.vue'; export { default as TooltipComponent } from './TooltipComponent.vue'; export { default as TreeComponent } from './TreeComponent.vue'; +export { default as PaginationPageSize } from './PaginationPageSize.vue'; diff --git a/src/components/upload-file/UploadFileGroup.vue b/src/components/upload-file/UploadFileGroup.vue index edc689bf..399d5192 100644 --- a/src/components/upload-file/UploadFileGroup.vue +++ b/src/components/upload-file/UploadFileGroup.vue @@ -45,9 +45,9 @@ const props = withDefaults( readonly?: boolean; showTitle?: boolean; ocr?: ( - group: any, + group: string, file: File, - ) => void | Promise<{ + ) => Promise<{ status: boolean; group: string; meta: { name: string; value: string }[]; diff --git a/src/css/quasar.variables.scss b/src/css/quasar.variables.scss index 7bd226ac..eb2b877b 100644 --- a/src/css/quasar.variables.scss +++ b/src/css/quasar.variables.scss @@ -198,3 +198,10 @@ i.q-icon.mdi.mdi-chevron-down-circle.q-expansion-item__toggle-icon.q-expansion-i .q-focus-helper { visibility: hidden; } + +.clear-btn { + opacity: 0.6; + &:hover { + opacity: 1; + } +} diff --git a/src/pages/03_customer-management/BranchPage.vue b/src/pages/03_customer-management/BranchPage.vue index 3c2e07bb..dd8c4737 100644 --- a/src/pages/03_customer-management/BranchPage.vue +++ b/src/pages/03_customer-management/BranchPage.vue @@ -18,6 +18,8 @@ import { CustomerBranch, CustomerType } from 'stores/customer/types'; import { columnsEmployee } from './constant'; import { useCustomerBranchForm, useEmployeeForm } from './form'; +import DialogEmployee from 'src/components/03_customer-management/DialogEmployee.vue'; +import DrawerEmployee from 'src/components/03_customer-management/DrawerEmployee.vue'; import EmployerFormAuthorized from './components/employer/EmployerFormAuthorized.vue'; import FloatingActionButton from 'components/FloatingActionButton.vue'; import SideMenu from 'components/SideMenu.vue'; @@ -89,6 +91,11 @@ const prop = withDefaults( currentCitizenId?: string; gender: string; selectedImage: string; + fetchImageList: ( + id: string, + selectedName: string, + type: 'customer' | 'employee', + ) => Promise; }>(), { color: 'green', @@ -96,7 +103,6 @@ const prop = withDefaults( ); const currentBranchEmployee = ref(''); const listEmployee = ref([]); - const customerId = defineModel('customerId', { required: true }); defineEmits<{ @@ -106,16 +112,6 @@ defineEmits<{ (e: 'dialog'): void; }>(); -onMounted(async () => { - customerBranchFormState.value.currentCustomerId = route.params - .customerId as string; - await fetchList(); - - branch.value?.forEach((v) => { - currentBtnOpen.value.push(false); - }); -}); - const columns = [ { name: 'branchName', @@ -257,10 +253,6 @@ async function fetchEmployee(opts: { branchId: string; pageSize?: number }) { } } -onMounted(async () => { - await fetchList(); -}); - watch([customerId, inputSearch, currentStatus, pageSizeBranch], async () => { await fetchList(); }); @@ -280,6 +272,16 @@ watch( } }, ); + +onMounted(async () => { + customerBranchFormState.value.currentCustomerId = route.params + .customerId as string; + await fetchList(); + + branch.value?.forEach((v) => { + currentBtnOpen.value.push(false); + }); +}); + + + + diff --git a/src/pages/03_customer-management/TabEmployee.vue b/src/pages/03_customer-management/TabEmployee.vue new file mode 100644 index 00000000..81348622 --- /dev/null +++ b/src/pages/03_customer-management/TabEmployee.vue @@ -0,0 +1,514 @@ + + + + diff --git a/src/pages/03_customer-management/components/employer/EmployerFormAbout.vue b/src/pages/03_customer-management/components/employer/EmployerFormAbout.vue index 0d19e8e9..7353db3c 100644 --- a/src/pages/03_customer-management/components/employer/EmployerFormAbout.vue +++ b/src/pages/03_customer-management/components/employer/EmployerFormAbout.vue @@ -336,6 +336,7 @@ watch( (v) => (typeof v === 'string' ? (prefixName = v) : '') " @clear="prefixName = ''" + :rules="[(val: string) => !!val || $t('form.error.required')]" > - { const customerStore = useCustomerStore(); + const onCreateImageList = ref<{ + selectedImage: string; + list: { url: string; imgFile: File | null; name: string }[]; + }>({ selectedImage: '', list: [] }); const { t } = useI18n(); const flowStore = useFlowStore(); @@ -84,6 +88,7 @@ export const useCustomerForm = defineStore('form-customer', () => { formDataOcr: Record; isImageEdit: boolean; currentCustomerId?: string; + imageList: { list: string[]; selectedImage: string }; }>({ dialogType: 'info', dialogOpen: false, @@ -100,6 +105,7 @@ export const useCustomerForm = defineStore('form-customer', () => { treeFile: [], formDataOcr: {}, isImageEdit: false, + imageList: { list: [], selectedImage: '' }, }); watch( @@ -497,6 +503,7 @@ export const useCustomerForm = defineStore('form-customer', () => { } return { + onCreateImageList, tabFieldRequired, registerAbleBranchOption, state, @@ -783,6 +790,7 @@ export const useEmployeeForm = defineStore('form-employee', () => { } | undefined; ocr: boolean; + imageList: { list: string[]; selectedImage: string }; }>({ currentBranchId: '', isImageEdit: false, @@ -807,6 +815,7 @@ export const useEmployeeForm = defineStore('form-employee', () => { infoEmployeePersonCard: [], formDataEmployeeOwner: undefined, ocr: false, + imageList: { list: [], selectedImage: '' }, }); const defaultFormData: EmployeeCreate & { image?: File } = { @@ -959,6 +968,7 @@ export const useEmployeeForm = defineStore('form-employee', () => { state.value.currentIndexVisa = -1; state.value.currentIndexCheckup = -1; state.value.currentIndexWorkHistory = -1; + state.value.imageList = { list: [], selectedImage: '' }; // state.value.currentTab = 'personalInfo'; if (clean) { state.value.formDataEmployeeOwner = undefined; @@ -1388,12 +1398,10 @@ export const useEmployeeForm = defineStore('form-employee', () => { statusSave: true, })), ), - employeeOtherInfo: structuredClone( - { - ...payload.employeeOtherInfo, - statusSave: !!payload.employeeOtherInfo?.id ? true : false, - } || {}, - ), + employeeOtherInfo: structuredClone({ + ...(payload.employeeOtherInfo ?? {}), + statusSave: true, + }), employeeWork: structuredClone( payload.employeeWork?.length === 0 ? state.value.dialogModal diff --git a/src/stores/customer/index.ts b/src/stores/customer/index.ts index d17fd1af..ca6dd6ba 100644 --- a/src/stores/customer/index.ts +++ b/src/stores/customer/index.ts @@ -115,6 +115,10 @@ const useCustomerStore = defineStore('api-customer', () => { customerType?: CustomerType; startDate?: string; endDate?: string; + businessType?: string; + province?: string; + district?: string; + subDistrict?: string; }, Data extends Pagination< (Customer & @@ -484,6 +488,10 @@ const useCustomerStore = defineStore('api-customer', () => { activeBranchOnly?: boolean; startDate?: string | Date; endDate?: string | Date; + businessType?: string; + province?: string; + district?: string; + subDistrict?: string; }) { let url = baseUrl + '/' + 'customer-export';