Advertisement
kidto1412

baseform

May 15th, 2025
310
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. <template>
  2.   <div class="tw-container tw-mx-auto tw-max-w-[800px]">
  3.     <q-header class="tw-bg-primary tw-text-gray-50">
  4.       <q-toolbar>
  5.         <q-breadcrumbs class="tw-block md:tw-hidden">
  6.           <q-breadcrumbs-el
  7.             icon="arrow_back"
  8.             class="tw-text-xl tw-cursor-pointer"
  9.             @click="onBack"
  10.             :disable="isCount == true"
  11.           />
  12.         </q-breadcrumbs>
  13.         <q-space></q-space>
  14.         <q-toolbar-title class="tw-flex tw-items-center tw-justify-center tw-px-0 -tw-translate-x-4">
  15.           <img src="~assets/images/login-logo-bprks.svg" alt="" class="tw-h-[30px]" />
  16.         </q-toolbar-title>
  17.         <q-space></q-space>
  18.       </q-toolbar>
  19.     </q-header>
  20.  
  21.     <div class="tw-flex tw-flex-col tw-space-y-2 tw-py-4">
  22.       <h3 class="tw-font-semibold tw-text-2xl tw-text-center">Kredit Online BPR KS</h3>
  23.  
  24.       <h5 class="tw-text-base tw-text-center">Mulai pengajuan pinjaman dengan mudah</h5>
  25.  
  26.       <k-stepper align="center" class="k-stepper-applicant">
  27.         <k-step
  28.           v-for="(section, index) in sections"
  29.           :key="section.id"
  30.           :name="section.sectionCode"
  31.           :class="{
  32.            'step-done': currentOrder(sectionCode) > index + 1,
  33.            'border-black': currentOrder(sectionCode) == index + 1,
  34.          }"
  35.         >
  36.           <q-icon v-if="currentOrder(sectionCode) > index + 1" name="done" />
  37.           <span v-else>{{ (index + 1)?.toString() }}</span>
  38.         </k-step>
  39.       </k-stepper>
  40.  
  41.       <k-step-panels v-model="sectionCode">
  42.         <k-step-panel v-for="section in sections" :key="section.id" :name="section.sectionCode">
  43.           <q-tabs
  44.             v-if="section.subSections.length > 0"
  45.             v-model="subSectionCode"
  46.             align="left"
  47.             active-color="primary"
  48.             indicator-color="primary"
  49.           >
  50.             <q-tab
  51.               v-for="(subSection, subIndex) in section.subSections"
  52.               :key="subSection.id"
  53.               :name="subSection.subSectionCode"
  54.               :class="{ 'step-done': currentSubOrder(sectionCode, subSectionCode) > subIndex + 1 }"
  55.               :disable="true"
  56.             >
  57.               <div class="tw-flex tw-items-center tw-space-x-2">
  58.                 <q-avatar
  59.                   color="primary"
  60.                   text-color="white"
  61.                   icon="done"
  62.                   size="sm"
  63.                   v-if="currentSubOrder(sectionCode, subSectionCode) > subIndex + 1"
  64.                 />
  65.  
  66.                 <q-icon
  67.                   v-else
  68.                   name="radio_button_unchecked"
  69.                   size="1.25rem"
  70.                   :color="subSectionCode === subSection.subSectionCode ? 'primary' : 'grey-8'"
  71.                 />
  72.                 <span>{{ subSection.subSectionName }}</span>
  73.               </div>
  74.             </q-tab>
  75.           </q-tabs>
  76.           <q-separator></q-separator>
  77.  
  78.           <k-tab-panels v-model="subSectionCode">
  79.             <!-- loan data -->
  80.             <k-tab-panel :name="SUB_SECTION_LOAN">
  81.               <loan-data v-model="form"></loan-data>
  82.             </k-tab-panel>
  83.             <!-- end loan data -->
  84.  
  85.             <!-- collateral data -->
  86.             <k-tab-panel :name="SUB_SECTION_COLLATERAL">
  87.               <collateral-data v-model="form"></collateral-data>
  88.             </k-tab-panel>
  89.             <!-- collateral data -->
  90.  
  91.             <!-- applicant data -->
  92.             <k-tab-panel :name="KK">
  93.               <upload-k-k v-model="form" :countDown="countDown"></upload-k-k>
  94.             </k-tab-panel>
  95.             <!-- applicant data -->
  96.  
  97.             <!-- work data -->
  98.             <k-tab-panel :name="SUB_SECTION_WORKER">
  99.               <work-data v-model="form"></work-data>
  100.             </k-tab-panel>
  101.             <!-- work data -->
  102.  
  103.             <!-- Upload KTP -->
  104.             <k-tab-panel :name="KTP">
  105.               <upload-ktp v-model="form" :countDown="countDown"></upload-ktp>
  106.             </k-tab-panel>
  107.             <!-- Upload KTP -->
  108.  
  109.             <!-- Upload KTP_PASANGAN -->
  110.             <k-tab-panel :name="KTP_PASANGAN">
  111.               <upload-partner-id-card v-model="form"></upload-partner-id-card>
  112.             </k-tab-panel>
  113.             <!-- Upload KTP_PASANGAN -->
  114.  
  115.             <!-- Upload Data -->
  116.             <k-tab-panel :name="SUB_SECTION_COLLATERAL_UPLOAD">
  117.               <upload-data v-model="form"></upload-data>
  118.             </k-tab-panel>
  119.             >
  120.             <!-- Upload Data -->
  121.  
  122.             <!-- AGREEMENT -->
  123.             <k-tab-panel :name="SECTION_AGREEMENT">
  124.               <aggrement v-model="form"></aggrement>
  125.             </k-tab-panel>
  126.             >
  127.             <!-- AGREEMENT -->
  128.  
  129.             <k-tab-panel :name="SUB_SECTION_EMERGENCY_CONTACT">
  130.               <contact-emergency-data v-model="form"></contact-emergency-data>
  131.             </k-tab-panel>
  132.             <!-- Upload Data -->
  133.           </k-tab-panels>
  134.  
  135.           <div class="tw-flex tw-items-center tw-justify-between tw-px-4">
  136.             <q-btn
  137.               :label="t('button.back')"
  138.               color="black"
  139.               type="button"
  140.               dense
  141.               class="tw-hidden md:tw-block"
  142.               flat
  143.               icon="arrow_back"
  144.               @click="onBack"
  145.               :disable="isCount == true"
  146.             />
  147.  
  148.             <q-btn
  149.               label="Lanjutkan"
  150.               color="secondary"
  151.               rounded
  152.               class="tw-w-full md:tw-w-auto"
  153.               @click="onSubmit"
  154.               :disable="isDisable || isCount == true"
  155.               :loading="buttonLoading"
  156.             />
  157.           </div>
  158.  
  159.           <!-- <div v-if="isCount == true && subSectionCode != 'KK' && subSectionCode != 'KTP'" class="tw-text-center">
  160.             {{ countDown }}
  161.           </div> -->
  162.         </k-step-panel>
  163.       </k-step-panels>
  164.     </div>
  165.   </div>
  166. </template>
  167. <script setup lang="ts">
  168. import { ApplicantSectionResponse, ApplicantSubSection } from 'src/common/entities/applicant-section.entity'
  169. import { useAuthenticationStore } from 'src/stores/authentication.store'
  170. import { computed, onMounted, reactive, ref, watch } from 'vue'
  171. import { useRoute, useRouter } from 'vue-router'
  172. import KStepper from '../ui/KStepper.vue'
  173. import KStep from '../ui/KStep.vue'
  174. import KStepPanels from '../ui/KStepPanels.vue'
  175. import KStepPanel from '../ui/KStepPanel.vue'
  176. import { id, SectionCollection, sectionOder } from 'src/common/interfaces/response.interface'
  177. import CollateralData from '../form/applicant/CollateralData.vue'
  178. import LoanData from '../form/applicant/LoanData.vue'
  179. import { Loading, LocalStorage, Notify } from 'quasar'
  180. import { GetErrorMessage } from 'src/common/utils/error.utils'
  181. import WorkData from '../form/applicant/WorkData.vue'
  182. import ContactEmergencyData from '../form/applicant/ContactEmergencyData.vue'
  183. import { ApplicantDataRequest } from 'src/common/entities/applicant.entity'
  184. import { useAppStore } from 'src/stores/app.store'
  185. import KTabPanels from '../ui/KTabPanels.vue'
  186. import KTabPanel from '../ui/KTabPanel.vue'
  187. import ApplicantData from '../form/applicant/ApplicantData.vue'
  188. import UploadKtp from '../form/applicant/UploadKtp.vue'
  189. import UploadKK from '../form/applicant/UploadKK.vue'
  190. import UploadData from '../form/applicant/UploadData.vue'
  191.  
  192. import {
  193.   SUB_SECTION_APPLICANT,
  194.   SUB_SECTION_COLLATERAL,
  195.   SUB_SECTION_EMERGENCY_CONTACT,
  196.   SUB_SECTION_LOAN,
  197.   SUB_SECTION_WORKER,
  198.   SUB_SECTION_PERSONAL_UPLOAD,
  199.   SUB_SECTION_COLLATERAL_UPLOAD,
  200.   SECTION_AGREEMENT,
  201.   KTP,
  202.   KK,
  203.   KTP_PASANGAN,
  204. } from 'src/common/constants/applicant-section.constant'
  205. import { useI18n } from 'vue-i18n'
  206. import { ErrorId } from 'src/common/exceptions/error-id'
  207. import { useApplicantEndpoint } from 'src/common/endpoints/applicant.endpoint'
  208. import { useUplaodStore } from 'src/stores/upload.store'
  209. import { toInteger } from 'lodash'
  210. import Aggrement from '../form/applicant/Aggrement.vue'
  211. import { useParameterStore } from 'src/stores/parameter.store'
  212. import moment from 'moment'
  213. import { useOCRStore } from 'src/stores/ocr.store'
  214. import { checkSameAdress } from '../../common/utils/validationAddress'
  215. import UploadPartnerIdCard from '../form/applicant/UploadPartnerIdCard.vue'
  216. import { FailedNotification } from '../../common/utils/notification.utils'
  217. import { nextTick } from 'process'
  218.  
  219. export interface ApplicantBaseFormProps {
  220.   modelValue: ApplicantDataRequest
  221. }
  222.  
  223. export interface ApplicantBaseFormEmits {
  224.   (event: 'update:model-value', value: ApplicantBaseFormProps['modelValue']): void
  225. }
  226.  
  227. interface SectionTemp {
  228.   sectionId?: id
  229.   subSectionId?: id
  230. }
  231.  
  232. const appStore = useAppStore()
  233.  
  234. const applicantDataStore = computed(() => appStore.$state.applicantData)
  235.  
  236. const applicantEndpoint = useApplicantEndpoint()
  237.  
  238. const { t } = useI18n()
  239.  
  240. const router = useRouter()
  241.  
  242. const route = useRoute()
  243.  
  244. const authStore = useAuthenticationStore()
  245.  
  246. const props = withDefaults(defineProps<ApplicantBaseFormProps>(), {})
  247.  
  248. const emit = defineEmits<ApplicantBaseFormEmits>()
  249.  
  250. const form = computed({
  251.   get: () => props.modelValue,
  252.   set: (value) => emit('update:model-value', value),
  253. })
  254.  
  255. const isMarriage = computed(() => {
  256.   return form.value.marriage == '13939713532562'
  257. })
  258. const sections = computed(() => {
  259.   // Ambil data sections dari store
  260.   const rawSections = authStore.$state?.applicantSections || []
  261.  
  262.   // Urutkan sections berdasarkan sectionOrder
  263.   const sortedSections = rawSections.slice().sort((a, b) => a.sectionOrder - b.sectionOrder)
  264.  
  265.   return sortedSections.map((section) => ({
  266.     ...section,
  267.     subSections: section.subSections
  268.       ?.slice()
  269.       .sort((a, b) => a.subSectionOrder - b.subSectionOrder)
  270.       .filter((subSection) => isMarriage.value || subSection.subSectionCode !== 'KTP_PASANGAN'), // Hanya tampilkan "KTP PASANGAN" jika isMarriage true
  271.   }))
  272. })
  273. const sectionCode = ref<string>()
  274.  
  275. const subSectionCode = ref<string>()
  276.  
  277. const collectionParams = computed(() => route.params?.collection as string)
  278.  
  279. const sectionTemp = reactive<SectionTemp>({})
  280.  
  281. const currentOrder = (code?: string) => {
  282.   return sections.value?.find(({ sectionCode }) => sectionCode === code)?.sectionOrder || 0
  283. }
  284. const currentSubOrder = (code?: string, subCode?: string) => {
  285.   const filterSection = sections.value?.find(({ sectionCode }) => sectionCode === code)
  286.  
  287.   const subSections = filterSection?.subSections.find((sub) => sub.subSectionCode == subCode)?.subSectionOrder
  288.  
  289.   // return subSections.subSectionOrder || 0
  290.   return subSections || 0
  291. }
  292.  
  293. const parameterStore = useParameterStore()
  294. const flagging = computed(() => parameterStore.getFlagging)
  295.  
  296. onMounted(() => {
  297.   const currentSections = [...sections.value]
  298.  
  299.   const sectionIndex = currentSections.findIndex((section) => section.sectionCode === sectionCode.value)
  300.   const section = currentSections[sectionIndex]
  301.  
  302.   if (collectionParams.value) {
  303.     const collection = JSON.parse(collectionParams.value) as SectionCollection
  304.  
  305.     const sectionOrder = collection.sectionOder // pastikan ini adalah number
  306.  
  307.     sectionCode.value = sectionCodeByOrder(sectionOrder)
  308.     subSectionCode.value = subSectionCodeByOrder(sectionOrder)
  309.  
  310.     sectionTemp.sectionId = sectionByOrder(sectionOrder)?.id
  311.  
  312.     sectionTemp.subSectionId = subSectionByOrder(sectionOrder)?.id
  313.  
  314.     form.value = { ...applicantDataStore.value }
  315.     if (applicantDataStore.value.collateral_type !== null) {
  316.       parameterStore.setGetWhell(applicantDataStore.value.vehicle_type)
  317.     }
  318.     if (applicantDataStore.value.brand !== null) {
  319.       parameterStore.setBrand(applicantDataStore.value.brand)
  320.     }
  321.     if (applicantDataStore.value.type !== null) {
  322.       parameterStore.setModel(applicantDataStore.value.type!)
  323.     }
  324.  
  325.     if (applicantDataStore.value.id != null) {
  326.       uploadStore.setIdLoan(toInteger(applicantDataStore.value.id))
  327.     }
  328.   }
  329. })
  330.  
  331. const sectionIdByCode = (sectionCode?: string) => {
  332.   const currentSection = [...sections.value]?.find((section) => section.sectionCode === sectionCode)
  333.   return currentSection?.sectionOrder
  334. }
  335.  
  336. // const sectionById = (sectionId?: id): ApplicantSectionResponse | undefined => {
  337. //   const currentSection = [...sections.value]?.find(({ id }) => id === sectionId)
  338. //   return currentSection
  339. // }
  340.  
  341. // const sectionCodeById = (sectionId: id): string | undefined => {
  342. //   return sectionById(sectionId)?.sectionCode
  343. // }
  344.  
  345. // const subSectionById = (sectionId?: id): ApplicantSubSection | undefined => {
  346. //   const currentSection = [...sections.value]?.find(({ id }) => id === sectionId)
  347. //   if (currentSection && currentSection?.subSections?.length > 0) {
  348. //     const [section] = currentSection?.subSections
  349. //     return section
  350. //   }
  351. // }
  352.  
  353. // const subSectionCodeById = (sectionId: id): string | undefined => {
  354. //   return subSectionById(sectionId)?.subSectionCode
  355. // }
  356.  
  357. const sectionByOrder = (sectionOrder: sectionOder): ApplicantSectionResponse | undefined => {
  358.   const currentSection = [...sections.value]?.find(({ order }) => order === sectionOrder)
  359.  
  360.   return currentSection
  361. }
  362.  
  363. const sectionCodeByOrder = (sectionOrder: sectionOder): string | undefined => {
  364.   return sectionByOrder(sectionOrder)?.sectionCode
  365. }
  366.  
  367. const subSectionByOrder = (sectionOrder: sectionOder): ApplicantSubSection | undefined => {
  368.   const currentSection = sectionByOrder(sectionOrder)
  369.   if (currentSection && currentSection?.subSections?.length > 0) {
  370.     // Dapatkan subSection berdasarkan order (misalnya subSectionOrder)
  371.     const currentSubSection = currentSection.subSections.find((sub) => sub.sectionOrder === sectionOrder)
  372.     return currentSubSection
  373.   }
  374. }
  375.  
  376. const subSectionCodeByOrder = (sectionOrder: sectionOder): string | undefined => {
  377.   return subSectionByOrder(sectionOrder)?.subSectionCode
  378. }
  379.  
  380. // old
  381. function onStepper(value: id) {
  382.   try {
  383.     const currentSection = [...sections.value]?.find(({ sectionCode }) => sectionCode === value)
  384.     if (currentSection && currentSection?.subSections?.length > 0) {
  385.       const [section] = currentSection?.subSections
  386.       // Pastikan tidak lompat ke subSection yang lebih tinggi
  387.       if (currentOrder(sectionCode.value) <= currentSection.sectionOrder) {
  388.         subSectionCode.value = section?.subSectionCode
  389.       } else {
  390.         Notify.create({
  391.           type: 'negative',
  392.           message: 'Anda harus menyelesaikan langkah sebelumnya terlebih dahulu!',
  393.         })
  394.       }
  395.     }
  396.   } catch (error) {
  397.     Notify.create({
  398.       type: 'negative',
  399.       message: GetErrorMessage(error as Error),
  400.     })
  401.   }
  402. }
  403.  
  404. // new
  405. // function onStepper(value: id) {
  406. //   try {
  407. //     const currentSection = sections.value.find(({ sectionCode }) => sectionCode === value)
  408. //     if (currentSection) {
  409. //       sectionCode.value = currentSection.sectionCode // Update sectionCode sesuai step
  410. //       if (currentSection.subSections.length > 0) {
  411. //         subSectionCode.value = currentSection.subSections[0].subSectionCode // Reset subSection
  412. //       }
  413. //     }
  414. //   } catch (error) {
  415. //     Notify.create({
  416. //       type: 'negative',
  417. //       message: GetErrorMessage(error as Error),
  418. //     })
  419. //   }
  420. // }
  421.  
  422. // function onStepper(value: id) {
  423. //   const currentSection = findSectionBy({ sectionCode: value })
  424. //   if (currentSection) {
  425. //     sectionCode.value = currentSection.sectionCode
  426. //     sectionTemp.sectionId = currentSection.id
  427.  
  428. //     const firstSubSection = currentSection.subSections?.[0]
  429. //     subSectionCode.value = firstSubSection?.subSectionCode
  430. //     sectionTemp.subSectionId = firstSubSection?.id
  431. //   }
  432. // }
  433.  
  434. async function onBack() {
  435.   try {
  436.     const currentSections = [...sections.value]
  437.     const sectionIndex = currentSections.findIndex((section) => section.sectionCode === sectionCode.value)
  438.     const section = currentSections[sectionIndex]
  439.  
  440.     if (!section) throw new Error('Section not found.')
  441.  
  442.     if (section.subSections.length > 0) {
  443.       const currentSubSections = [...section.subSections]
  444.       const subSectionIndex = currentSubSections.findIndex(
  445.         (subSection) => subSection.subSectionCode === subSectionCode.value
  446.       )
  447.  
  448.       if (subSectionIndex > 0) {
  449.         const prevSubSection = currentSubSections[subSectionIndex - 1]
  450.         sectionTemp.subSectionId = prevSubSection.id
  451.         subSectionCode.value = prevSubSection.subSectionCode
  452.         loadSubmission()
  453.       } else if (sectionIndex > 0) {
  454.         const prevSection = currentSections[sectionIndex - 1]
  455.         sectionTemp.subSectionId = prevSection.subSections[prevSection.subSections.length - 1]?.id || 0
  456.         sectionCode.value = prevSection.sectionCode
  457.         subSectionCode.value = prevSection.subSections[prevSection.subSections.length - 1]?.subSectionCode || ''
  458.         loadSubmission()
  459.       } else {
  460.         router.back()
  461.       }
  462.     }
  463.   } catch (error) {
  464.     Notify.create({
  465.       type: 'negative',
  466.       message: GetErrorMessage(error as Error),
  467.     })
  468.   }
  469. }
  470.  
  471. const uploadStore = useUplaodStore()
  472. const statusOCR = computed(() => uploadStore.getStatusOCR)
  473.  
  474. function parseCurrency(value: string) {
  475.   return value.replace(/\D/g, '')
  476. }
  477. const genders = computed(() => parameterStore.getGender)
  478. const typeOfWorks = computed(() => parameterStore.typeOfWorks)
  479. const marriages = computed(() => parameterStore.marriages)
  480.  
  481. async function loadSubmission() {
  482.   const sectionId = sectionIdByCode(sectionCode.value)
  483.  
  484.   try {
  485.     Loading.show()
  486.  
  487.     const inquiryData = await applicantEndpoint.getOne()
  488.  
  489.     appStore.setApplicantData(inquiryData.data)
  490.     if (inquiryData.data.domicile == undefined || inquiryData.data.domicile == null) {
  491.       inquiryData.data.domicile = true
  492.     }
  493.     if (inquiryData.data.flagging) {
  494.       parameterStore.setFlagging(inquiryData.data.flagging)
  495.     }
  496.     form.value = { ...inquiryData.data }
  497.  
  498.     console.log(form.value, 'new form data')
  499.  
  500.     if (inquiryData.data.applicantKkId) {
  501.       form.value.applicantKkId = inquiryData.data.applicantKkId
  502.       ocrStore.setApplicantKKId(inquiryData.data.applicantKkId)
  503.     } else {
  504.       ocrStore.setApplicantKKId(null)
  505.     }
  506.  
  507.     if (inquiryData.data.applicantKtpId) {
  508.       ocrStore.setApplicantKTPId(inquiryData.data.applicantKtpId)
  509.       form.value.applicantKtpId = inquiryData.data.applicantKtpId
  510.     } else {
  511.       ocrStore.setApplicantKTPId(null)
  512.     }
  513.   } catch (error) {
  514.     Notify.create({
  515.       type: 'negative',
  516.       message: GetErrorMessage(error as Error),
  517.     })
  518.   } finally {
  519.     Loading.hide()
  520.   }
  521. }
  522.  
  523. const statusKTP = ref<string | null>(null)
  524. const statusKK = ref<string | null>(null)
  525.  
  526. const isCount = ref<boolean>(false)
  527. const countDown = ref<number>(0)
  528.  
  529. const maxCounterKtp = ref<number>(0)
  530. const maxCounterKK = ref<number>(0)
  531.  
  532. let timerId: any
  533.  
  534. function countDownTimer(callback: any) {
  535.   if (countDown.value > 0) {
  536.     timerId = setTimeout(() => {
  537.       countDown.value -= 1
  538.       callback(countDown.value)
  539.       countDownTimer(callback)
  540.     }, 1000)
  541.   }
  542. }
  543.  
  544. function clearTimer() {
  545.   if (timerId) {
  546.     clearTimeout(timerId)
  547.     timerId = null
  548.   }
  549. }
  550.  
  551. function updateCountDown(newCount: number) {
  552.   countDown.value = newCount
  553.  
  554.   if (newCount === 0) {
  555.     isCount.value = false
  556.     clearTimer()
  557.   }
  558. }
  559.  
  560. function updateContDownOCR(newCount: number) {
  561.   const currentSections = [...sections.value]
  562.   const sectionIndex = currentSections.findIndex((section) => section.sectionCode === sectionCode.value)
  563.  
  564.   countDown.value = newCount
  565.   Loading.show({ message: `Silahkan tunggu ${countDown.value}` })
  566.   const nextSection = currentSections[sectionIndex + 1]
  567.   if (newCount === 0) {
  568.     isCount.value = false
  569.     clearTimer()
  570.     Loading.hide()
  571.     sectionTemp.subSectionId = nextSection.subSections[0]?.subSectionOrder || 0
  572.     sectionCode.value = nextSection.sectionCode
  573.     subSectionCode.value = nextSection.subSections[0]?.subSectionCode || ''
  574.     console.log(subSectionCode.value, 'update countdown')
  575.     loadSubmission()
  576.   }
  577. }
  578.  
  579. const ocrStore = useOCRStore()
  580. const statusOcrKTP = computed(() => ocrStore.getStatusOCRKTP)
  581. const statusOcrKK = computed(() => ocrStore.getStatusOCRKK)
  582. const applicantKKId = computed(() => ocrStore.getApplicantKKId)
  583. const applicantKTPId = computed(() => ocrStore.getApplicantKTPId)
  584.  
  585. const inqueryStatusOCR = async (fileOCR: string) => {
  586.   try {
  587.     const checkStatus = await applicantEndpoint.checkStatusOCR({
  588.       applicantId: fileOCR == 'KTP' ? applicantKTPId.value ?? '' : applicantKKId.value ?? '',
  589.     })
  590.  
  591.     if (fileOCR == 'KTP') {
  592.       ocrStore.setStatusOCRKTP(checkStatus.data.status)
  593.     } else {
  594.       ocrStore.setStatusOCRKK(checkStatus.data.status)
  595.     }
  596.  
  597.     if (checkStatus.data.status == 'IN_PROGRESS' || checkStatus.data.status == 'on_queue') {
  598.       isCount.value = true
  599.       clearTimer()
  600.       countDown.value = 10
  601.       countDownTimer(updateCountDown)
  602.       Notify.create({
  603.         type: 'positive',
  604.         message: 'Sedang diproses',
  605.       })
  606.       if (fileOCR == 'KTP') {
  607.         setKTPDataToNull()
  608.       }
  609.     } else if (checkStatus.data.status == 'MANUAL') {
  610.       if (fileOCR == 'KTP') {
  611.         Notify.create({
  612.           type: 'negative',
  613.           message: 'Silahkan isi formulir manual',
  614.         })
  615.       }
  616.       await loadSubmission()
  617.     } else if (checkStatus.data.status == 'ERROR') {
  618.       // isCount.value = true
  619.       // clearTimer()
  620.       // countDown.value = 10
  621.       // countDownTimer(updateCountDown)
  622.       if (fileOCR == 'KTP') {
  623.         Notify.create({
  624.           type: 'negative',
  625.           message: 'Silahkan isi formulir manual',
  626.         })
  627.       } else {
  628.         Notify.create({
  629.           type: 'negative',
  630.           message: 'OCR gagal',
  631.         })
  632.       }
  633.       await loadSubmission()
  634.     } else {
  635.       Notify.create({
  636.         type: 'positive',
  637.         message: 'OCR berhasil',
  638.       })
  639.       await loadSubmission()
  640.     }
  641.   } catch (error) {
  642.     isCount.value = false
  643.     ocrStore.setStatusOCRKTP(null)
  644.     ocrStore.setStatusOCRKK(null)
  645.     Notify.create({
  646.       type: 'negative',
  647.       message: GetErrorMessage(error as Error),
  648.     })
  649.   } finally {
  650.   }
  651. }
  652.  
  653. const setKTPDataToNull = () => {
  654.   form.value.legal_id = ''
  655.   form.value.full_name = ''
  656.   form.value.place_of_birth = ''
  657.   form.value.date_of_birth = ''
  658.   form.value.gender = ''
  659.   form.value.marriage = ''
  660.   form.value.province = ''
  661.   form.value.city_or_district = ''
  662.   form.value.subdistrict = ''
  663.   form.value.village = ''
  664.   form.value.rt = ''
  665.   form.value.rw = ''
  666.   form.value.postal_code = ''
  667.   form.value.address = ''
  668. }
  669.  
  670. const buttonLoading = ref<boolean>(false)
  671. const dataKtpPasanganExist = computed(() => uploadStore.getExistKtpPasangan)
  672. async function onSubmit() {
  673.   console.log(subSectionCode.value, 'sub section')
  674.   try {
  675.     buttonLoading.value = true
  676.     const sectionId = sectionIdByCode(sectionCode.value)
  677.  
  678.     if (!sectionId) throw new ErrorId('SectionId is undefined')
  679.  
  680.     const currentForm: ApplicantDataRequest = { ...form.value, sectionId }
  681.     console.log(currentForm, 'form request')
  682.     currentForm.subSection = subSectionCode.value ?? ''
  683.  
  684.     if (form.value.date_of_birth != null) {
  685.       const dob = form.value.date_of_birth
  686.  
  687.       // Cek apakah format awalnya adalah DD-MM-YYYY (misalnya dari OCR)
  688.       const isFormatDMY = moment(dob, 'DD-MM-YYYY', true).isValid()
  689.       const isFormatYMD = moment(dob, 'YYYY-MM-DD', true).isValid()
  690.       const isFormatYMDslash = moment(dob, 'YYYY/MM/DD', true).isValid()
  691.  
  692.       if (isFormatDMY) {
  693.         currentForm.date_of_birth = moment(dob, 'DD-MM-YYYY').format('YYYY-MM-DD')
  694.       } else if (isFormatYMD) {
  695.         currentForm.date_of_birth = dob // sudah sesuai, tidak diubah
  696.       } else if (isFormatYMDslash) {
  697.         currentForm.date_of_birth = moment(dob, 'YYYY/MM/DD').format('YYYY-MM-DD')
  698.       } else {
  699.         currentForm.date_of_birth = dob // fallback jika format tidak dikenal
  700.       }
  701.     }
  702.     // if (form.value.tax_date != null) {
  703.     //   currentForm.tax_date = moment(form.value.tax_date, 'YYYY/MM/DD').format('YYYY-MM-DD')
  704.     // }
  705.  
  706.     if (form.value.gender != null && genders.value!.length != 0) {
  707.       const filterGender = genders.value!.filter((item) => item.description == form.value.gender)[0]
  708.       if (filterGender) {
  709.         currentForm.gender = filterGender.id
  710.       }
  711.     }
  712.     if (form.value.marriage != null && marriages.value!.length != 0) {
  713.       const filterMarriage = marriages.value!.filter(
  714.         (item) => item.description.toLowerCase() == form.value.marriage.toLowerCase()
  715.       )[0]
  716.       if (filterMarriage) {
  717.         currentForm.marriage = filterMarriage.id
  718.       }
  719.     }
  720.  
  721.     console.log(currentForm.gender, 'gender')
  722.     if (form.value.credit_amount != null) {
  723.       currentForm.credit_amount = parseCurrency(form.value.credit_amount)
  724.     }
  725.     if (form.value.net_income) {
  726.       currentForm.net_income = parseCurrency(form.value.net_income)
  727.     }
  728.  
  729.     const currentSections = [...sections.value]
  730.     const sectionIndex = currentSections.findIndex((section) => section.sectionCode === sectionCode.value)
  731.     const section = currentSections[sectionIndex]
  732.  
  733.     if (!section) throw new Error('Section not found.')
  734.  
  735.     if (section.subSections.length > 0) {
  736.       const currentSubSections = [...section.subSections]
  737.       // const subSectionIndex = currentSubSections.findIndex((subSection) => subSection.id === sectionTemp.subSectionId)
  738.       const subSectionIndex = currentSubSections.findIndex(
  739.         (subSection) => subSection.subSectionCode === subSectionCode.value
  740.       )
  741.       const nexSubSection = currentSubSections[subSectionIndex + 1]
  742.  
  743.       if (nexSubSection) {
  744.         console.log(subSectionCode.value, 'next')
  745.         if (subSectionCode.value == 'COLLATERAL') {
  746.           currentForm.type =
  747.             typeof form.value.type === 'object' && form.value.type !== null ? form.value.type.label : form.value.type
  748.           currentForm.flagging = flagging.value != null ? flagging.value : form.value.flagging
  749.           currentForm.year =
  750.             typeof form.value.year === 'object' && form.value.year !== null ? form.value.year.tahun : form.value.year
  751.         }
  752.         if (subSectionCode.value != 'KK' && subSectionCode.value != 'KTP' && subSectionCode.value != 'KTP_PASANGAN') {
  753.           const response = await applicantEndpoint.create(currentForm)
  754.           console.log('post subSection next')
  755.           if (form.value.id == null) {
  756.             form.value.id = response.data.id
  757.           }
  758.         }
  759.         if (subSectionCode.value != 'KTP' && subSectionCode.value != 'KTP_PASANGAN') {
  760.           await loadSubmission()
  761.           console.log('load subSection next')
  762.         }
  763.  
  764.         uploadStore.setIdLoan(toInteger(form.value.id))
  765.  
  766.         if (subSectionCode.value == 'KTP_PASANGAN') {
  767.           const idCardPartner = computed(() => uploadStore.getIdCardPartnerFormData)
  768.  
  769.           if (idCardPartner.value) {
  770.             try {
  771.               await applicantEndpoint.uploadKtpPasangan(idCardPartner.value)
  772.               await applicantEndpoint.create(currentForm)
  773.               await loadSubmission()
  774.               uploadStore.setIdCardPartnerFormData(null)
  775.               sectionTemp.subSectionId = nexSubSection.id
  776.               subSectionCode.value = nexSubSection.subSectionCode
  777.             } catch (error) {
  778.               Notify.create({
  779.                 message: GetErrorMessage(error as Error),
  780.               })
  781.             }
  782.             return
  783.           }
  784.           if (dataKtpPasanganExist.value) {
  785.             await applicantEndpoint.create(currentForm)
  786.             await loadSubmission()
  787.             uploadStore.setIdCardPartnerFormData(null)
  788.             sectionTemp.subSectionId = nexSubSection.id
  789.             subSectionCode.value = nexSubSection.subSectionCode
  790.           }
  791.         }
  792.  
  793.         if (subSectionCode.value != 'KTP' && subSectionCode.value != 'KK' && subSectionCode.value != 'KTP_PASANGAN') {
  794.           sectionTemp.subSectionId = nexSubSection.id
  795.           subSectionCode.value = nexSubSection.subSectionCode
  796.         }
  797.         if (
  798.           (statusOcrKTP.value == 'COMPLETED' && subSectionCode.value == 'KTP') ||
  799.           (statusOcrKTP.value == 'MANUAL' && subSectionCode.value == 'KTP') ||
  800.           (statusOcrKTP.value == 'ERROR' && subSectionCode.value == 'KTP')
  801.         ) {
  802.           currentForm.address2 = form.value.domicile == true ? form.value.address : form.value.address2
  803.           currentForm.city_or_district2 =
  804.             form.value.domicile == true ? form.value.city_or_district : form.value.city_or_district2
  805.           currentForm.subdistrict2 = form.value.domicile == true ? form.value.subdistrict : form.value.subdistrict2
  806.           currentForm.village2 = form.value.domicile == true ? form.value.village : form.value.village2
  807.           currentForm.rt2 = form.value.domicile == true ? form.value.rt : form.value.rt2
  808.           currentForm.rw2 = form.value.domicile == true ? form.value.rw : form.value.rw2
  809.           currentForm.province2 = form.value.domicile == true ? form.value.province : form.value.province2
  810.           currentForm.postal_code2 = form.value.domicile == true ? form.value.postal_code : form.value.postal_code2
  811.  
  812.           await applicantEndpoint.create(currentForm)
  813.           await loadSubmission()
  814.  
  815.           sectionTemp.subSectionId = nexSubSection.id
  816.           subSectionCode.value = nexSubSection.subSectionCode
  817.         }
  818.  
  819.         if (subSectionCode.value == 'KTP') {
  820.           inqueryStatusOCR('KTP')
  821.         }
  822.       } else {
  823.         const nextSection = currentSections[sectionIndex + 1]
  824.         if (nextSection) {
  825.           console.log(subSectionCode.value, 'nexxxt sectiom')
  826.           if (subSectionCode.value == 'EMERGENCY_CONTACT') {
  827.             const addressIsSame = checkSameAdress(form.value.address, form.value.emergency_address)
  828.  
  829.             if (addressIsSame == true) {
  830.               Notify.create({
  831.                 type: 'negative',
  832.                 message: 'Alamat tidak boleh sama dengan pemohon',
  833.               })
  834.               return
  835.             }
  836.           }
  837.           if (
  838.             subSectionCode.value != 'KK' &&
  839.             subSectionCode.value != 'KTP' &&
  840.             subSectionCode.value != 'COLLATERAL_UPLOAD'
  841.           ) {
  842.             const response = await applicantEndpoint.create(currentForm)
  843.             if (form.value.id == null) {
  844.               form.value.id = response.data.id
  845.             }
  846.             console.log('post section next')
  847.           }
  848.           if (subSectionCode.value != 'KK' && subSectionCode.value != 'COLLATERAL_UPLOAD') {
  849.             console.log('get section next')
  850.             await loadSubmission()
  851.           }
  852.           if (subSectionCode.value == 'KK') {
  853.             const famillyCardFormData = computed(() => uploadStore.getFamillyCardFormData)
  854.  
  855.             if (famillyCardFormData.value && !form.value.applicantKkId) {
  856.               try {
  857.                 // await applicantEndpoint.upload(famillyCardFormData.value!)
  858.                 const uploadKK = await applicantEndpoint.uploadOCR(famillyCardFormData.value!)
  859.                 appStore.setMaxCounterKK(0)
  860.  
  861.                 ocrStore.setStatusOCRKK(uploadKK.data.status)
  862.                 ocrStore.setApplicantKKId(uploadKK.data.applicantId ? uploadKK.data.applicantId : null)
  863.  
  864.                 if (uploadKK.data.applicantId) {
  865.                   form.value.applicantKkId = uploadKK.data.applicantId
  866.                 }
  867.  
  868.                 if (uploadKK.data.status == 'on_queue') {
  869.                   Notify.create({
  870.                     type: 'positive',
  871.                     message: 'Sedang diproses',
  872.                   })
  873.                 } else if (uploadKK.data.status == 'ERROR' || uploadKK.data.status == 'MANUAL') {
  874.                   Notify.create({
  875.                     type: 'negative',
  876.                     message: 'OCR gagal',
  877.                   })
  878.                 } else {
  879.                   Notify.create({
  880.                     type: 'positive',
  881.                     message: 'OCR berhasil',
  882.                   })
  883.                 }
  884.               } catch (error) {
  885.                 Notify.create({
  886.                   type: 'negative',
  887.                   message: GetErrorMessage(error as Error),
  888.                 })
  889.               }
  890.             }
  891.           }
  892.  
  893.           if (subSectionCode.value == 'COLLATERAL_UPLOAD') {
  894.             const bpkb1 = computed(() => uploadStore.getBPKB1FormData)
  895.             const bpkb2 = computed(() => uploadStore.getBPKB2FormData)
  896.             const stnk = computed(() => uploadStore.getSTNK)
  897.             const vehicleWarranty = computed(() => uploadStore.getVehicleWarranty)
  898.             const vehicleWarranty2 = computed(() => uploadStore.getVehicleWarranty2)
  899.             const vehicleWarranty3 = computed(() => uploadStore.getVehicleWarranty3)
  900.             const vehicleWarranty4 = computed(() => uploadStore.getVehicleWarranty4)
  901.  
  902.             try {
  903.               await Promise.all([
  904.                 bpkb1.value ? applicantEndpoint.uploadOCR(bpkb1.value!) : null,
  905.                 bpkb2.value ? applicantEndpoint.upload(bpkb2.value!) : null,
  906.                 stnk.value ? applicantEndpoint.uploadOCR(stnk.value!) : null,
  907.                 vehicleWarranty.value ? applicantEndpoint.upload(vehicleWarranty.value!) : null,
  908.                 vehicleWarranty2.value ? applicantEndpoint.upload(vehicleWarranty2.value!) : null,
  909.                 vehicleWarranty3.value ? applicantEndpoint.upload(vehicleWarranty3.value!) : null,
  910.                 vehicleWarranty4.value ? applicantEndpoint.upload(vehicleWarranty4.value!) : null,
  911.               ])
  912.               await loadSubmission()
  913.               isCount.value = true
  914.               clearTimer()
  915.               countDown.value = 10
  916.               console.log('All uploads completed')
  917.               try {
  918.                 const newForm: ApplicantDataRequest = { ...form.value, sectionId }
  919.                 const response = await applicantEndpoint.create(newForm)
  920.                 if (form.value.id == null) {
  921.                   form.value.id = response.data.id
  922.                 }
  923.               } catch (error) {
  924.                 FailedNotification(GetErrorMessage(error as Error))
  925.               }
  926.               countDownTimer(updateContDownOCR)
  927.             } catch (error) {
  928.               console.log(error, 'Upload failed')
  929.               isCount.value = false
  930.               clearTimer()
  931.               countDown.value = 0
  932.               FailedNotification(GetErrorMessage(error as Error))
  933.             }
  934.           }
  935.  
  936.           uploadStore.setIdLoan(toInteger(form.value.id))
  937.  
  938.           if (
  939.             subSectionCode.value != 'KTP' &&
  940.             subSectionCode.value != 'KK' &&
  941.             subSectionCode.value != 'COLLATERAL_UPLOAD'
  942.           ) {
  943.             sectionTemp.subSectionId = nextSection.subSections[0]?.subSectionOrder || 0
  944.             sectionCode.value = nextSection.sectionCode
  945.             subSectionCode.value = nextSection.subSections[0]?.subSectionCode || ''
  946.           }
  947.  
  948.           if (
  949.             (subSectionCode.value == 'KK' && statusOcrKK.value == 'IN_PROGRESS') ||
  950.             (subSectionCode.value == 'KK' && statusOcrKK.value == 'on_queue')
  951.           ) {
  952.             await inqueryStatusOCR('KK')
  953.           }
  954.           if (
  955.             (statusOcrKK.value == 'COMPLETED' && subSectionCode.value == 'KK') ||
  956.             (statusOcrKK.value == 'MANUAL' && subSectionCode.value == 'KK') ||
  957.             (statusOcrKK.value == 'ERROR' && subSectionCode.value == 'KK')
  958.           ) {
  959.             await applicantEndpoint.create(currentForm)
  960.             sectionTemp.subSectionId = nextSection.subSections[0]?.subSectionOrder || 0
  961.             sectionCode.value = nextSection.sectionCode
  962.             subSectionCode.value = nextSection.subSections[0]?.subSectionCode || ''
  963.           }
  964.         } else {
  965.           await applicantEndpoint.create(currentForm)
  966.           parameterStore.setIsAggree(false)
  967.           router.push('/submission/history')
  968.           uploadStore.reset()
  969.           uploadStore.resetUploadFile()
  970.           parameterStore.resetAmountIsValid()
  971.         }
  972.       }
  973.     }
  974.   } catch (error) {
  975.     Notify.create({
  976.       type: 'negative',
  977.       message: GetErrorMessage(error as Error),
  978.     })
  979.   } finally {
  980.     buttonLoading.value = false
  981.   }
  982. }
  983.  
  984. // watch(sectionCode, (newVal, oldVal) => {
  985. //   console.log(newVal, 'new')
  986. //   console.log(oldVal, 'lod')
  987. // })
  988.  
  989. const netIncomeIsValid = computed(() => parameterStore.getNetIncomeIsValid)
  990. const creditIsValid = computed(() => parameterStore.getCreditIsValid)
  991.  
  992. const isAggree = computed(() => parameterStore.getIsAggree)
  993. const dataKTP = computed(() => uploadStore.getIdCardFormData)
  994. const dataFamillyCard = computed(() => uploadStore.getFamillyCardFormData)
  995.  
  996. const dataSTNK = computed(() => uploadStore.getSTNK)
  997. const dataBPKB1 = computed(() => uploadStore.getBPKB1FormData)
  998. const dataBPKB2 = computed(() => uploadStore.getBPKB2FormData)
  999. const dataTTJ = computed(() => uploadStore.getVehicleWarranty)
  1000. const dataTTJ2 = computed(() => uploadStore.getVehicleWarranty2)
  1001. const dataTTJ3 = computed(() => uploadStore.getVehicleWarranty3)
  1002. const dataTTJ4 = computed(() => uploadStore.getVehicleWarranty4)
  1003.  
  1004. const isWestJava = computed(() => appStore.getIsWestJava)
  1005.  
  1006. const existKTP = computed(() => uploadStore.getExistKtp)
  1007. const existKK = computed(() => uploadStore.getExistKK)
  1008. const kkFile = computed(() => uploadStore.getKKFile)
  1009. const existBPKB1 = computed(() => uploadStore.getExistBPKB1)
  1010. const existBPKB2 = computed(() => uploadStore.getExistBPKB2)
  1011. const existSTNK = computed(() => uploadStore.getExistSTNK)
  1012. const existTTJ = computed(() => uploadStore.getExistTTJ)
  1013. const existTTJ2 = computed(() => uploadStore.getExistTTJ2)
  1014. const existTTJ3 = computed(() => uploadStore.getExistTTJ3)
  1015. const existTTJ4 = computed(() => uploadStore.getExistTTJ4)
  1016.  
  1017. const KtpPasanganFIle = computed(() => uploadStore.getKtpPasanganFile)
  1018. const existKtpPasangan = computed(() => uploadStore.getExistKtpPasangan)
  1019. // console.log(
  1020. //       !!(form.value.vehicle_type && form.value.brand && typeof form.value.type == 'object' && form.value.type != null
  1021. //         ? form.value.type.label
  1022. //         : form.value.type && typeof form.value.year == 'object' && form.value.year != null
  1023. //         ? form.value.year.tahun
  1024. //         : form.value.year),
  1025. //       'rules collateral'
  1026. //     )
  1027. const validationRules: any = {
  1028.   COLLATERAL: () => {
  1029.     return !!(form.value.vehicle_type && form.value.brand && form.value.type && form.value.year)
  1030.   },
  1031.   LOAN: () => {
  1032.     return !!(form.value.purpose_of_use && form.value.tenor && form.value.credit_amount)
  1033.   },
  1034.   KTP: () => {
  1035.     if (!dataKTP.value && !existKTP.value) {
  1036.       return false // Validasi gagal jika data KTP tidak ada
  1037.     }
  1038.     if (statusOcrKTP.value === 'IN_PROGRESS' || statusOcrKTP.value === 'on_queue') {
  1039.       return true
  1040.     }
  1041.  
  1042.     const dob = form.value.date_of_birth
  1043.     const format1 = moment(dob, 'DD-MM-YYYY', true)
  1044.     const format2 = moment(dob, 'YYYY-MM-DD', true)
  1045.     const format3 = moment(dob, 'YYYY/MM/DD', true)
  1046.     const isDateValid = format1.isValid() || format2.isValid() || format3.isValid()
  1047.  
  1048.     if (!isDateValid) {
  1049.       return false
  1050.     }
  1051.  
  1052.     // Validasi data identitas utama
  1053.     const isPersonalDataValid = !!(
  1054.       (form.value.legal_id?.length ?? 0) > 15 &&
  1055.       form.value.full_name &&
  1056.       form.value.place_of_birth &&
  1057.       form.value.date_of_birth &&
  1058.       form.value.gender &&
  1059.       form.value.marriage &&
  1060.       (form.value.referral_code?.length ?? 0) > 0
  1061.     )
  1062.  
  1063.     // Validasi alamat pertama jika domicile == true
  1064.     const isAddress1Valid =
  1065.       form.value.domicile === true &&
  1066.       !!(
  1067.         form.value.province &&
  1068.         form.value.city_or_district &&
  1069.         form.value.subdistrict &&
  1070.         form.value.village &&
  1071.         form.value.rt &&
  1072.         form.value.rw &&
  1073.         form.value.postal_code &&
  1074.         form.value.address
  1075.       )
  1076.  
  1077.     // Validasi alamat kedua jika domicile == false
  1078.     const isAddress2Valid =
  1079.       form.value.domicile === false &&
  1080.       !!(
  1081.         form.value.province2 &&
  1082.         form.value.city_or_district2 &&
  1083.         form.value.subdistrict2 &&
  1084.         form.value.village2 &&
  1085.         form.value.rt2 &&
  1086.         form.value.rw2 &&
  1087.         form.value.postal_code2 &&
  1088.         form.value.address2
  1089.       )
  1090.  
  1091.     return isPersonalDataValid && (isAddress1Valid || isAddress2Valid)
  1092.   },
  1093.   KTP_PASANGAN: () => {
  1094.     if (isMarriage.value) {
  1095.       return !!(KtpPasanganFIle.value || existKtpPasangan.value)
  1096.     } else {
  1097.       return true
  1098.     }
  1099.   },
  1100.   KK: () => {
  1101.     return !!(kkFile.value || existKK.value)
  1102.   },
  1103.   WORKER: () => {
  1104.     return !!(
  1105.       form.value.type_of_work &&
  1106.       form.value.net_income &&
  1107.       form.value.length_of_work &&
  1108.       form.value.company_name &&
  1109.       form.value.address_company
  1110.     )
  1111.   },
  1112.   EMERGENCY_CONTACT: () => {
  1113.     return !!(
  1114.       form.value.emergency_name &&
  1115.       form.value.emergency_address &&
  1116.       form.value.emergency_contact &&
  1117.       form.value.relation
  1118.     )
  1119.   },
  1120.   COLLATERAL_UPLOAD: () => {
  1121.     return !!(
  1122.       (existBPKB1.value || dataBPKB1.value) &&
  1123.       (existBPKB2.value || dataBPKB2.value) &&
  1124.       (existSTNK.value || dataSTNK.value) &&
  1125.       (existTTJ.value || dataTTJ.value) &&
  1126.       (existTTJ2.value || dataTTJ2.value) &&
  1127.       (existTTJ3.value || dataTTJ3.value) &&
  1128.       (existTTJ4.value || dataTTJ4.value)
  1129.     )
  1130.   },
  1131.   AGREEMENT: () => {
  1132.     return !!(form.value.isAgree === true)
  1133.   },
  1134.   // Tambahkan subSectionCode lainnya jika ada...
  1135. }
  1136.  
  1137. const isDisable = computed(() => {
  1138.   // Urutan langkah dari awal hingga akhir
  1139.   const steps = [
  1140.     'COLLATERAL',
  1141.     'LOAN',
  1142.     'KTP',
  1143.     'KTP_PASANGAN',
  1144.     'KK',
  1145.     'WORKER',
  1146.     'EMERGENCY_CONTACT',
  1147.     'COLLATERAL_UPLOAD',
  1148.     'AGREEMENT',
  1149.     // Tambahkan langkah lain jika ada...
  1150.   ]
  1151.  
  1152.   // Cari index langkah saat ini
  1153.   const currentIndex = steps.indexOf(subSectionCode.value!)
  1154.  
  1155.   // Validasi semua langkah dari awal hingga langkah saat ini
  1156.   for (let i = 0; i <= currentIndex; i++) {
  1157.     const step = steps[i]
  1158.     const isValid = validationRules[step]?.()
  1159.     if (!isValid) {
  1160.       return true // Tombol di-disable jika ada langkah tidak valid
  1161.     }
  1162.   }
  1163.  
  1164.   return false // Semua langkah valid, tombol diaktifkan
  1165. })
  1166.  
  1167. watch(
  1168.   isCount,
  1169.   (newVal, oldVal) => {
  1170.     if (newVal != oldVal) {
  1171.       appStore.setIsCount(newVal)
  1172.     }
  1173.   },
  1174.   { deep: true }
  1175. )
  1176.  
  1177. // check status first when step ktp and kk
  1178. watch(
  1179.   subSectionCode,
  1180.   (val) => {
  1181.     if (applicantKTPId.value && val == 'KTP') {
  1182.       inqueryStatusOCR('KTP')
  1183.     }
  1184.  
  1185.     if (applicantKKId.value && val == 'KK') {
  1186.       inqueryStatusOCR('KK')
  1187.     }
  1188.  
  1189.     // if (!applicantKKId.value && val == 'KK' && existKK.value) {
  1190.     //   Notify.create({
  1191.     //     type: 'negative',
  1192.     //     message: 'Silahkan unggah ulang Foto Kartu Keluarga',
  1193.     //   })
  1194.     // }
  1195.  
  1196.     if (subSectionCode.value != 'KK' && subSectionCode.value != 'KTP') {
  1197.       ocrStore.setStatusOCRKK(null)
  1198.       ocrStore.setStatusOCRKTP(null)
  1199.     }
  1200.   },
  1201.   { immediate: true }
  1202. )
  1203.  
  1204. watch(
  1205.   subSectionCode,
  1206.   () => {
  1207.     validationRules
  1208.   },
  1209.   { deep: true }
  1210. )
  1211. </script>
  1212.  
  1213. <style lang="scss">
  1214. .k-stepper-applicant {
  1215.   .q-tabs__content {
  1216.     .k-step.disabled {
  1217.       @apply tw-cursor-default !important;
  1218.       .q-tab__content {
  1219.         @apply tw-cursor-default !important;
  1220.       }
  1221.     }
  1222.   }
  1223. }
  1224. .disabled {
  1225.   opacity: 1 !important;
  1226. }
  1227. </style>
  1228.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement
OSZAR »