Files
pleno-vue/src/components/forms/auth/DriverRegistrationForm.vue
T
Jeppe B aaecffbdfa Finish Sæby demo registration and limited backoffice (#242)
Unify truckwash.dk Kundeoprettelse and QR traffic on the shared customer page, add protected registration UX, and complete the limited-backoffice demo flow.
2026-08-02 11:50:58 +02:00

181 lines
4.5 KiB
Vue

<script setup>
import { nextTick, onBeforeUnmount, onMounted, reactive, ref } from "vue";
import axios from "axios";
import { API_URL } from "@/config.js";
import { getError, parseError, removeError } from "@/components/request/HandleGlobalError.vue";
import LoadButtonWhileAwait from "@/components/request/LoadButtonWhileAwait.vue";
import {
getPublicRecaptchaConfig,
renderPublicRecaptcha,
resetPublicRecaptcha,
} from "@/services/publicRecaptcha.js";
const driverFormData = reactive({
driverCvr: null,
driverPhone: null,
});
const deliverSuccess = ref(false);
const recaptchaElement = ref(null);
const recaptchaConfig = ref({ enabled: false, site_key: "" });
const recaptchaToken = ref("");
const recaptchaWidgetId = ref(null);
let deliverTimeoutId;
const resetRecaptcha = () => {
recaptchaToken.value = "";
resetPublicRecaptcha(recaptchaWidgetId.value);
};
const submitDriver = async () => {
removeError("authRegisterDriverCvr");
try {
await axios.post(API_URL + "/subusers/me", {
cvr: driverFormData.driverCvr,
phone: driverFormData.driverPhone,
phone_country_code: "45",
...(recaptchaConfig.value.enabled ? { g_recaptcha_response: recaptchaToken.value } : {}),
});
driverFormData.driverCvr = null;
driverFormData.driverPhone = null;
deliverSuccess.value = true;
resetRecaptcha();
deliverTimeoutId = setTimeout(() => {
deliverSuccess.value = false;
}, 3500);
} catch (error) {
resetRecaptcha();
parseError(error, "authRegisterDriverCvr");
}
};
onMounted(async () => {
try {
recaptchaConfig.value = await getPublicRecaptchaConfig();
if (!recaptchaConfig.value.enabled) {
return;
}
await nextTick();
recaptchaWidgetId.value = await renderPublicRecaptcha(recaptchaElement.value, recaptchaConfig.value.site_key, {
callback: (token) => {
recaptchaToken.value = token;
},
expiredCallback: () => {
recaptchaToken.value = "";
},
errorCallback: () => {
recaptchaToken.value = "";
},
});
} catch (error) {
parseError(error, "authRegisterDriverCvr");
}
});
onBeforeUnmount(() => {
if (deliverTimeoutId) {
clearTimeout(deliverTimeoutId);
}
});
</script>
<template>
<form class="truckwash-form" data-testid="driver-registration-form" @submit.prevent="() => {}" method="post">
<div class="form-field">
<label for="driver_cvr">{{ $t("customer_creation.driver.cvr_label") }}</label>
<input
id="driver_cvr"
v-model="driverFormData.driverCvr"
type="text"
name="cvr"
inputmode="numeric"
autocomplete="organization"
placeholder="12345678"
/>
</div>
<div class="form-field">
<label for="driver_phone">{{ $t("customer_creation.driver.phone_label") }}</label>
<input
id="driver_phone"
v-model="driverFormData.driverPhone"
type="text"
name="phone"
inputmode="tel"
autocomplete="tel"
placeholder="12345678"
/>
</div>
<p v-if="getError('authRegisterDriverCvr')" id="driver_creation_alert_error" class="help is-danger">
{{ getError("authRegisterDriverCvr") }}
</p>
<div v-if="recaptchaConfig.enabled" class="form-field" data-testid="driver-registration-recaptcha">
<div ref="recaptchaElement"></div>
</div>
<p
v-if="deliverSuccess"
id="driver_creation_alert_success"
class="help is-success"
data-testid="driver-registration-success"
role="status"
>
{{ $t("customer_creation.driver.success_message") }}
</p>
<LoadButtonWhileAwait
id="driver-register-button"
class="truckwash-submit"
:disabled="!driverFormData.driverCvr || !driverFormData.driverPhone || (recaptchaConfig.enabled && !recaptchaToken)"
:loadFunction="submitDriver"
>
{{ $t("customer_creation.driver.submit") }}
</LoadButtonWhileAwait>
</form>
</template>
<style scoped>
.truckwash-form {
border: 1.5px solid #333;
padding: 20px;
border-radius: 15px;
display: flex;
flex-direction: column;
gap: 16px;
background-color: #fff;
position: relative;
margin-top: 35px;
height: max-content;
}
.form-field {
display: grid;
}
.form-field label {
color: #13324c;
}
input {
height: 44px;
padding: 0 12px;
border: 1.5px solid #333;
border-radius: 8px;
margin-top: 4px;
color: #13324c;
}
.truckwash-submit {
height: 48px;
border-radius: 8px;
border: none;
background: #13324c;
color: #fff;
cursor: pointer;
}
</style>