dicaribapak11

FormRegistration

Oct 10th, 2025
40
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. <script lang="ts">
  2.   import type { InjectionKey } from "vue";
  3.   import ModalForm from "./ModalForm.vue";
  4.   import { useRoute } from "vue-router";
  5.  
  6.   export interface StateT {
  7.     company_name: string;
  8.     company_code: string;
  9.     rec_account: string;
  10.     rec_account_uuid: string;
  11.   }
  12.  
  13.   export const stateKey: InjectionKey<Ref<StateT>> = Symbol("form.state");
  14. </script>
  15.  
  16. <script setup lang="ts">
  17.   import { isPageAdd } from "~~/shared/utils";
  18.   import { useForm } from "vee-validate";
  19.   import { getRegistrationSchema } from "@vendor/schemas/registration/registrationByGuestSchema";
  20.   import { useToast } from "@app/composables/useToast";
  21.   import { FetchError } from "ofetch";
  22.   import SelectCompany from "./SelectCompany.vue";
  23.   import SelectAccountGroup from "./SelectAccountGroup.vue";
  24.   import SelectRecAccount from "./SelectRecAccount.vue";
  25.   import SelectCategory from "./SelectCategory.vue";
  26.  
  27.   const { t } = useI18n();
  28.   const { toast } = useToast();
  29.  
  30.   definePageMeta({
  31.     layout: "registration",
  32.   });
  33.   const route = useRoute();
  34.   const regionTypeName = ref<"Lokal" | "Internasional">("Lokal");
  35.  
  36.   const { resetForm, values } = useForm({
  37.     validationSchema: computed(() => getRegistrationSchema(regionTypeName.value)),
  38.     initialValues: {
  39.       business_region_type_name: "Lokal",
  40.     },
  41.   });
  42.  
  43.   const isUpdate = computed(() => !isPageAdd(route.path));
  44.   const token = ref(null);
  45.   token.value = localStorage.getItem("sanctum.storage.token");
  46.   const config = useRuntimeConfig();
  47.   const idCreate = ref();
  48.   const usernameCreate = ref();
  49.   const passwordCreate = ref();
  50.   const state = ref<StateT>({
  51.     company_name: "",
  52.     company_code: "",
  53.     account_group: "",
  54.     rec_account: "",
  55.     business_type_uuid: "",
  56.   });
  57.   const isLoading = ref(false);
  58.   const showModal = ref(false);
  59.   const showModalSuccess = ref(false);
  60.   const formModel = reactive({
  61.     company_uuid: "",
  62.     full_address: "",
  63.     pic_email: "",
  64.     business_region_type_uuid: "",
  65.     tax_identification_number: "",
  66.     business_type_uuid: "",
  67.     phone_number: "",
  68.     country_uuid: "",
  69.     bp_role: "",
  70.     province_uuid: "",
  71.     district_uuid: "",
  72.     subdistrict_uuid: "",
  73.     purch_org: "",
  74.     note: "",
  75.     village_uuid: "",
  76.     postal_code_uuid: "",
  77.     account_group_uuid: "",
  78.   });
  79.   const path = isPageAdd(route.path)
  80.     ? `${config.public.apiBaseUrl}/api/v1/vendor/register/internal`
  81.     : `${config.public.apiBaseUrl}/api/v1/vendors/updateVendor/${route.params.id}`;
  82.  
  83.   provide(stateKey, state);
  84.   watch(
  85.     () => values.business_region_type_name,
  86.     (val) => {
  87.       if (val === "Lokal" || val === "Internasional") {
  88.         regionTypeName.value = val;
  89.       }
  90.     },
  91.     { immediate: true },
  92.   );
  93.  
  94.   async function onSubmit(event: any) {
  95.     event.preventDefault();
  96.  
  97.     try {
  98.       const postData = {
  99.         ...formModel,
  100.         name: state.value.company_name,
  101.         pic_name: state.value.company_name,
  102.         pic_phone_number: formModel.phone_number,
  103.         email: formModel.pic_email,
  104.         account_group: state.value.account_group,
  105.         rec_account_uuid: state.value.rec_account_uuid,
  106.         rec_account: state.value.rec_account,
  107.       };
  108.  
  109.       const { return: _data, status } = await $fetch(path, {
  110.         method: isPageAdd(route.path) ? "POST" : "PUT",
  111.         body: postData,
  112.         headers: {
  113.           authorization: `Bearer ${token.value}`,
  114.         },
  115.         server: false,
  116.       });
  117.  
  118.       if (status) {
  119.         showModal.value = false;
  120.         showModalSuccess.value = true;
  121.         idCreate.value = _data?.id;
  122.         usernameCreate.value = _data?.username;
  123.         passwordCreate.value = _data?.password;
  124.       }
  125.     } catch (error: any) {
  126.       showModal.value = false;
  127.       if (error instanceof FetchError && error.response && error.response.status === 422) {
  128.         const validationErrors = error.response._data.errors; // Access _data for the response body
  129.         const errors = Object.values(error.response._data.errors as ValidationErrors).flat();
  130.         const message = errors.map((msg) => `• ${msg}`).join("\n");
  131.  
  132.         toast.error(message);
  133.         console.error("Validation Errors:", validationErrors);
  134.       } else {
  135.         console.error("Other API Error:", error);
  136.       }
  137.     } finally {
  138.       showModal.value = false;
  139.     }
  140.   }
  141.  
  142.   async function handlingResetForm() {
  143.     state.value.company_name = "";
  144.     state.value.company_code = "";
  145.     state.value.account_group = "";
  146.     state.value.rec_account = "";
  147.  
  148.     formModel.company_uuid = "";
  149.     formModel.full_address = "";
  150.     formModel.pic_email = "";
  151.     formModel.business_region_type_uuid = "";
  152.     formModel.tax_identification_number = "";
  153.     formModel.business_type_uuid = "";
  154.     formModel.phone_number = "";
  155.     formModel.country_uuid = "";
  156.     formModel.bp_role = "";
  157.     formModel.province_uuid = "";
  158.     formModel.district_uuid = "";
  159.     formModel.subdistrict_uuid = "";
  160.     formModel.purch_org = "";
  161.     formModel.note = "";
  162.     formModel.village_uuid = "";
  163.     formModel.postal_code_uuid = "";
  164.     formModel.account_group_uuid = "";
  165.     formModel.rec_account_uuid = "";
  166.  
  167.     showModalSuccess.value = false;
  168.   }
  169.  
  170.   async function fetchData() {
  171.     try {
  172.       isLoading.value = false;
  173.       const { return: _data } = await $fetch(
  174.         `${config.public.apiBaseUrl}/api/v1/vendors/getVendorById/${route.params.id}`,
  175.         {
  176.           method: "GET",
  177.           headers: {
  178.             authorization: `Bearer ${token.value}`,
  179.           },
  180.           server: false,
  181.         },
  182.       );
  183.       console.log(_data.business_type?.uuid);
  184.       formModel.company_uuid = "";
  185.       formModel.full_address = _data.address.full_address ?? "";
  186.       formModel.pic_email = _data.email ?? "";
  187.       formModel.business_region_type_uuid = "";
  188.       formModel.tax_identification_number = "";
  189.       formModel.business_type_uuid = _data.business_type?.uuid ?? "";
  190.  
  191.       formModel.phone_number = _data.address?.phone_number ?? "";
  192.       formModel.account_group = "";
  193.       formModel.country_uuid = "";
  194.       formModel.bp_role = _data.bp_role;
  195.       formModel.province_uuid = "";
  196.       state.value.rec_account = _data.rec_account?.uuid;
  197.       formModel.district_uuid = "";
  198.       formModel.subdistrict_uuid = "";
  199.       formModel.purch_org = _data.purch_org;
  200.       formModel.note = _data.note;
  201.       formModel.village_uuid = "";
  202.       formModel.postal_code_uuid = "";
  203.     } catch (error: any) {
  204.       isLoading.value = false;
  205.     } finally {
  206.       isLoading.value = false;
  207.     }
  208.   }
  209.  
  210.   onMounted(() => {
  211.     if (!isUpdate.value) {
  212.       return;
  213.     }
  214.  
  215.     fetchData();
  216.   });
  217. </script>
  218.  
  219. <template>
  220.   <div>
  221.     <Card class="shadow-none border-0" v-if="!isLoading">
  222.       <CardContent class="px-4 py-8">
  223.         <form id="formRegistration">
  224.           <div
  225.             class="grid md:grid-cols-2 gap-5"
  226.             :class="{
  227.              'lg:grid-rows-11': values.business_region_type_name === 'Lokal',
  228.              'lg:grid-rows-10': values.business_region_type_name === 'Internasional',
  229.            }"
  230.           >
  231.             <MoleculeInputDropdown
  232.               v-slot="{ componentField }"
  233.               :label="t('company')"
  234.               name="company_uuid"
  235.               v-model="formModel.company_uuid"
  236.               :required="true"
  237.             >
  238.               <SelectCompany v-bind="componentField" as-form-field />
  239.             </MoleculeInputDropdown>
  240.  
  241.             <MoleculeInputText
  242.               :label="t('address')"
  243.               name="full_address"
  244.               v-model="formModel.full_address"
  245.               :required="true"
  246.             />
  247.  
  248.             <MoleculeInputText
  249.               :label="t('pic-email')"
  250.               name="pic_email"
  251.               v-model="formModel.pic_email"
  252.               :required="true"
  253.             />
  254.  
  255.             <MoleculeInputDropdown
  256.               v-slot="{ componentField }"
  257.               :label="t('vendor-type')"
  258.               name="business_region_type_uuid"
  259.               v-model="formModel.business_region_type_uuid"
  260.               :required="true"
  261.             >
  262.               <MoleculeSelectVendorRegionType v-bind="componentField" as-form-field />
  263.             </MoleculeInputDropdown>
  264.  
  265.             <MoleculeInputText
  266.               :label="t('tax-registration-number')"
  267.               name="tax_identification_number"
  268.               v-model="formModel.tax_identification_number"
  269.               :required="true"
  270.             />
  271.  
  272.             <MoleculeInputDropdown
  273.               v-slot="{ componentField }"
  274.               :label="t('vendor-classification')"
  275.               name="business_type_uuid"
  276.               v-model="formModel.business_type_uuid"
  277.               :required="true"
  278.             >
  279.               <SelectCategory v-bind="componentField" as-form-field />
  280.             </MoleculeInputDropdown>
  281.  
  282.             <MoleculeInputText
  283.               :label="t('phone-number')"
  284.               name="phone_number"
  285.               v-model="formModel.phone_number"
  286.               :required="true"
  287.             />
  288.  
  289.             <MoleculeInputDropdown
  290.               v-slot="{ componentField }"
  291.               :label="t('vendor-account-group')"
  292.               name="vendor_account_group"
  293.               v-model="formModel.account_group_uuid"
  294.               :required="true"
  295.             >
  296.               <SelectAccountGroup v-bind="componentField" as-form-field />
  297.             </MoleculeInputDropdown>
  298.  
  299.             <MoleculeInputDropdown
  300.               v-slot="{ componentField }"
  301.               :label="t('country')"
  302.               name="country_uuid"
  303.               v-model="formModel.country_uuid"
  304.               :required="true"
  305.             >
  306.               <MoleculeSelectCountry v-bind="componentField" as-form-field />
  307.             </MoleculeInputDropdown>
  308.  
  309.             <MoleculeInputText
  310.               :label="t('bp-role')"
  311.               name="bp_role"
  312.               v-model="formModel.bp_role"
  313.               :required="true"
  314.             />
  315.  
  316.             <MoleculeInputDropdown
  317.               v-if="values.business_region_type_name === 'Lokal'"
  318.               v-slot="{ componentField }"
  319.               :label="t('province')"
  320.               name="province_uuid"
  321.               v-model="formModel.province_uuid"
  322.               :required="true"
  323.             >
  324.               <MoleculeSelectProvince
  325.                 v-bind="componentField"
  326.                 :countryUuid="formModel.country_uuid"
  327.                 as-form-field
  328.               />
  329.             </MoleculeInputDropdown>
  330.  
  331.             <MoleculeInputDropdown
  332.               v-slot="{ componentField }"
  333.               :label="t('rec-account')"
  334.               name="rec_account"
  335.               :required="true"
  336.             >
  337.               <SelectRecAccount v-bind="componentField" as-form-field />
  338.             </MoleculeInputDropdown>
  339.  
  340.             <MoleculeInputDropdown
  341.               v-if="values.business_region_type_name === 'Lokal'"
  342.               v-slot="{ componentField }"
  343.               :label="t('district_reg')"
  344.               name="district_uuid"
  345.               v-model="formModel.district_uuid"
  346.               :required="true"
  347.             >
  348.               <MoleculeSelectDistrict
  349.                 v-bind="componentField"
  350.                 :provinceUuid="formModel.province_uuid"
  351.                 as-form-field
  352.               />
  353.             </MoleculeInputDropdown>
  354.  
  355.             <MoleculeInputText
  356.               :label="t('company-code')"
  357.               :required="true"
  358.               :disable="true"
  359.               v-model="state.company_code"
  360.             />
  361.  
  362.             <MoleculeInputDropdown
  363.               v-if="values.business_region_type_name === 'Lokal'"
  364.               v-slot="{ componentField }"
  365.               :label="t('sub-district')"
  366.               name="subdistrict_uuid"
  367.               v-model="formModel.subdistrict_uuid"
  368.               :required="true"
  369.             >
  370.               <MoleculeSelectSubDistrict
  371.                 v-bind="componentField"
  372.                 :districtUuid="formModel.district_uuid"
  373.                 as-form-field
  374.               />
  375.             </MoleculeInputDropdown>
  376.  
  377.             <MoleculeInputText
  378.               :label="t('purch-org')"
  379.               name="purch_org"
  380.               v-model="formModel.purch_org"
  381.               :required="true"
  382.             />
  383.  
  384.             <MoleculeInputDropdown
  385.               v-if="values.business_region_type_name === 'Lokal'"
  386.               v-slot="{ componentField }"
  387.               :label="t('village')"
  388.               name="village_uuid"
  389.               v-model="formModel.village_uuid"
  390.               :required="true"
  391.             >
  392.               <MoleculeSelectVillage
  393.                 v-bind="componentField"
  394.                 :subdistrictUuid="formModel.subdistrict_uuid"
  395.                 as-form-field
  396.               />
  397.             </MoleculeInputDropdown>
  398.  
  399.             <MoleculeInputDropdown
  400.               v-if="values.business_region_type_name === 'Lokal'"
  401.               v-slot="{ componentField }"
  402.               :label="t('postal-code')"
  403.               name="postal_code_uuid"
  404.               v-model="formModel.postal_code_uuid"
  405.               :required="true"
  406.             >
  407.               <MoleculeSelectPostalCode
  408.                 v-bind="componentField"
  409.                 :subdistrictUuid="formModel.subdistrict_uuid"
  410.                 as-form-field
  411.               />
  412.             </MoleculeInputDropdown>
  413.  
  414.             <div class="col-span-2">
  415.               <MoleculeInputTextArea
  416.                 :label="t('note')"
  417.                 name="note"
  418.                 v-model="formModel.note"
  419.                 :required="true"
  420.               />
  421.             </div>
  422.  
  423.             <MoleculeInputText
  424.               v-if="values.business_type_name === 'Lainnya'"
  425.               :label="t('Other Business Category')"
  426.               name="other_business_type"
  427.               :required="true"
  428.             />
  429.  
  430.             <!-- Internatioinal -->
  431.             <MoleculeInputText
  432.               v-if="values.business_region_type_name === 'Internasional'"
  433.               :label="t('province')"
  434.               name="other_province"
  435.               :required="true"
  436.             />
  437.             <MoleculeInputText
  438.               v-if="values.business_region_type_name === 'Internasional'"
  439.               :label="t('district')"
  440.               name="other_district"
  441.               :required="true"
  442.             />
  443.             <MoleculeInputText
  444.               v-if="values.business_region_type_name === 'Internasional'"
  445.               :label="t('sub-district')"
  446.               name="other_subdistrict"
  447.               :required="true"
  448.             />
  449.             <MoleculeInputText
  450.               v-if="values.business_region_type_name === 'Internasional'"
  451.               :label="t('postal-code')"
  452.               name="other_postal_code"
  453.               :required="false"
  454.             />
  455.  
  456.             <MoleculeInputText
  457.               v-if="values.business_region_type_name === 'Internasional'"
  458.               :label="t('passport-number')"
  459.               name="pic_identity_number"
  460.               :required="true"
  461.             />
  462.  
  463.             <!-- End of internatioinal -->
  464.           </div>
  465.  
  466.           <div class="mt-5 flex flex-col md:flex-row md:justify-center gap-4">
  467.             <button
  468.               type="button"
  469.               class="w-full md:max-w-96 bg-[#D2D2D2] hover:bg-[#BDBDBD] text-black rounded-[0.375rem] cursor-pointer"
  470.               @click="
  471.                () => {
  472.                  resetForm();
  473.                  $router.push($localePath('/vendor/registration'));
  474.                }
  475.              "
  476.             >
  477.               {{ t("cancel") }}
  478.             </button>
  479.  
  480.             <Button
  481.               @click="() => (showModal = true)"
  482.               type="button"
  483.               class="w-full md:max-w-96 bg-[#FF9700] hover:bg-orange-500 text-white rounded-[0.375rem] cursor-pointer"
  484.             >
  485.               {{ t("submit") }}
  486.             </Button>
  487.           </div>
  488.         </form>
  489.       </CardContent>
  490.     </Card>
  491.  
  492.     <ModalForm v-model="showModal" :isForm="false" :useHeader="false">
  493.       <template v-slot:header>
  494.         <div class="flex justify-end">
  495.           <button @click="() => (showModal = false)" class="text-gray-400 hover:text-gray-600">
  496.             ✕
  497.           </button>
  498.         </div>
  499.       </template>
  500.       <slot>
  501.         <div class="flex flex-col w-full space-y-2">
  502.           <div class="flex justify-center">
  503.             <img src="/icon/file-check.png" alt="icon" />
  504.           </div>
  505.           <p class="text-center text-[#FF9700] font-light text-lg">SUBMIT CONFIRMATION</p>
  506.           <p class="text-center font-light">Are you sure you want to send this data?</p>
  507.         </div>
  508.       </slot>
  509.       <template v-slot:footer>
  510.         <div class="flex justify-center space-x-2 mt-5">
  511.           <Button
  512.             type="button"
  513.             class="bg-[#ED1C24] hover:bg-red-700 text-white rounded-[0.375rem] cursor-pointer"
  514.             @click="() => (showModal = false)"
  515.           >
  516.             {{ t("cancel") }}
  517.           </Button>
  518.  
  519.           <Button
  520.             type="button"
  521.             class="bg-[#2FCA5E] text-white rounded-[0.375rem] cursor-pointer hover:bg-green-500"
  522.             @click="onSubmit"
  523.           >
  524.             {{ t("submit") }}
  525.           </Button>
  526.         </div>
  527.       </template>
  528.     </ModalForm>
  529.  
  530.     <ModalForm v-model="showModalSuccess" :isForm="false" :useHeader="false">
  531.       <template v-slot:header>
  532.         <div class="flex justify-end">
  533.           <button
  534.             @click="() => (showModalSuccess = false)"
  535.             class="text-gray-400 hover:text-gray-600"
  536.           >
  537.             ✕
  538.           </button>
  539.         </div>
  540.       </template>
  541.       <slot>
  542.         <div class="flex flex-col w-full space-y-2">
  543.           <div class="flex justify-center">
  544.             <img src="/icon/checklist-success.png" alt="icon" />
  545.           </div>
  546.           <p class="text-center text-[#2FCA5E] font-light text-lg">SUCCESS</p>
  547.           <p class="text-center font-light my-5">Thank you for your request</p>
  548.           <div class="my-3">
  549.             <p class="text-center font-light">Username and Password Have Been Created</p>
  550.             <p class="text-center font-light">The following is the Business Partner</p>
  551.           </div>
  552.           <p class="text-center font-light my-5">Business Partner Number : {{ idCreate }}</p>
  553.           <p class="text-center font-light">Username : {{ usernameCreate }}</p>
  554.           <p class="text-center font-light">Password : {{ passwordCreate }}</p>
  555.         </div>
  556.       </slot>
  557.       <template v-slot:footer>
  558.         <div class="flex justify-center space-x-2 mt-5">
  559.           <Button
  560.             type="button"
  561.             class="bg-[#ED1C24] hover:bg-red-700 text-white rounded-[0.375rem] cursor-pointer"
  562.             @click="handlingResetForm"
  563.           >
  564.             {{ t("cancel") }}
  565.           </Button>
  566.         </div>
  567.       </template>
  568.     </ModalForm>
  569.   </div>
  570. </template>
  571.  
Advertisement
Add Comment
Please, Sign In to add comment