Files
pleno-vue/src/components/displays/department/pos/steps/mobile/elements/PosDepartmentStepMobilePopupAddCustomer.vue
T
Jeppe BandJeppe Bundgaard aa5e0a5507 Add EAN to customer registration flows (#147)
* Add EAN to economic customer registration

* Focus EAN PR Playwright mapping

---------

Co-authored-by: Jeppe Bundgaard <jb@truckwash.dk>
2026-07-06 18:12:05 +02:00

203 lines
6.0 KiB
Vue

<script setup lang="ts">
import { useI18n } from "vue-i18n";
import { watch } from "vue";
import { actionButtons, metadata, popups } from "../objects/PosDepartmentStepMobileFlow.vue";
import { usePosAddCustomerForm } from "@/composables/usePosAddCustomerForm.js";
const ADD_CUSTOMER_SUBMIT_TEST_ID = "pos-mobile-add-customer-submit";
const { t } = useI18n();
const emit = defineEmits<{
(e: "close"): void;
}>();
const {
searchQuery,
searchResult,
searching,
submitting,
errorMessage,
form,
isValidSearchResult,
canCreateCustomer,
handleAutofillFieldInput,
submitCustomer,
} = usePosAddCustomerForm({
onCustomerCreated: async (_selectedCustomer, createdCustomerNumber) => {
metadata.setCustomerId(createdCustomerNumber);
emit("close");
},
});
const syncPopupActionButtons = () => {
const popup = popups.get();
if (!popup) {
return;
}
if (submitting.value) {
popup.actionButtons = [];
return;
}
const nextButtons = [{ ...actionButtons.default.value.cancel }];
if (canCreateCustomer.value) {
nextButtons.push({
label: t("admin.pos.add_customer"),
onClick: submitCustomer,
color: "primary",
testId: ADD_CUSTOMER_SUBMIT_TEST_ID,
});
}
popup.actionButtons = nextButtons;
};
watch(
() => [
form.cvr,
form.companyPhone,
form.invoiceEmail,
form.contactEmail,
form.contactPhone,
form.ean,
canCreateCustomer.value,
searchResult.value,
errorMessage.value,
submitting.value,
],
syncPopupActionButtons,
{ immediate: true }
);
</script>
<template>
<div
style="overflow-y: auto; overflow-x: hidden; height: 100%; padding-bottom: 10px"
data-testid="pos-mobile-add-customer-popup"
>
<div class="mx-3">
<div class="field">
<label class="label"><small>CVR</small></label>
<div class="control has-icons-right" :class="{ 'is-loading': searching }">
<input
v-model="searchQuery"
class="input is-searched"
:class="{
'is-danger': searchResult === null || !isValidSearchResult,
'is-success': isValidSearchResult,
}"
type="text"
:placeholder="$t('global.search_cvr')"
:disabled="submitting"
data-testid="pos-mobile-add-customer-search-input"
/>
<span
class="icon is-right"
:class="{
'has-text-danger': !isValidSearchResult && !searching,
'has-text-success': isValidSearchResult && !searching,
}"
>
<i class="fas fa-check" v-if="isValidSearchResult && !searching"></i>
<i class="fas fa-exclamation-triangle" v-else-if="!isValidSearchResult && !searching"></i>
<i class="fas fa-search" v-else-if="!searching"></i>
</span>
</div>
<p class="help" v-if="isValidSearchResult">{{ searchResult.name }}</p>
</div>
<div class="field">
<label class="label"
><small>{{ $t("admin.pos.company_phone") }}</small></label
>
<div class="control">
<input
v-model="form.companyPhone"
class="input"
type="text"
:placeholder="$t('admin.pos.company_phone')"
:disabled="searchResult === null || submitting"
:class="{ 'is-danger': searchResult !== null && form.companyPhone === '' }"
data-testid="pos-mobile-add-customer-company-phone"
@input="handleAutofillFieldInput('companyPhone')"
/>
</div>
</div>
<div class="field">
<label class="label"
><small>{{ $t("admin.pos.ean") }}</small></label
>
<div class="control">
<input
v-model="form.ean"
class="input"
type="text"
inputmode="numeric"
maxlength="13"
:placeholder="$t('admin.pos.ean')"
:disabled="searchResult === null || submitting"
data-testid="pos-mobile-add-customer-ean"
@input="handleAutofillFieldInput('ean')"
/>
</div>
</div>
<div class="field">
<label class="label"
><small>{{ $t("admin.pos.invoice_email") }}</small></label
>
<div class="control">
<input
v-model="form.invoiceEmail"
class="input"
type="text"
:placeholder="$t('admin.pos.invoice_email')"
:disabled="searchResult === null || submitting"
data-testid="pos-mobile-add-customer-invoice-email"
@input="handleAutofillFieldInput('invoiceEmail')"
/>
</div>
</div>
<div class="field">
<label class="label"
><small>{{ $t("admin.pos.contact_email") }}</small></label
>
<div class="control">
<input
v-model="form.contactEmail"
class="input"
type="text"
:placeholder="$t('admin.pos.contact_email')"
:disabled="searchResult === null || submitting"
data-testid="pos-mobile-add-customer-contact-email"
@input="handleAutofillFieldInput('contactEmail')"
/>
</div>
</div>
<div class="field">
<label class="label"
><small>{{ $t("admin.pos.contact_phone") }}</small></label
>
<div class="control">
<input
v-model="form.contactPhone"
class="input"
type="text"
:placeholder="$t('admin.pos.contact_phone')"
:disabled="searchResult === null || submitting"
:class="{ 'is-danger': searchResult !== null && form.contactPhone === '' }"
data-testid="pos-mobile-add-customer-contact-phone"
@input="handleAutofillFieldInput('contactPhone')"
/>
</div>
</div>
<div class="notification is-danger" v-if="errorMessage !== null">
{{ errorMessage }}
</div>
</div>
</div>
</template>
<style scoped></style>