Skip to content

Commit

Permalink
Adapt contact forms to new API (#30)
Browse files Browse the repository at this point in the history
  • Loading branch information
utarwyn authored Oct 27, 2024
1 parent adc917a commit 9fe83e6
Show file tree
Hide file tree
Showing 15 changed files with 217 additions and 393 deletions.
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
VITE_API_URL=
3 changes: 3 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ on:
push:
branches: [main]

env:
VITE_API_URL: ${{ vars.API_URL }}

jobs:
build:
runs-on: ubuntu-latest
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ with [Vue.js](https://vuejs.org).
## 🚀 Project Setup

Copy `.env.example` to `.env`

```sh
npm install
```
Expand Down
42 changes: 30 additions & 12 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
},
"dependencies": {
"@fontsource-variable/mulish": "^5.1.0",
"@hcaptcha/vue3-hcaptcha": "^1.3.0",
"altcha": "^1.0.6",
"vue": "^3.5.6",
"vue-router": "^4.4.5"
},
Expand Down
148 changes: 25 additions & 123 deletions src/components/company/CaseStudyForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,43 +3,43 @@
<Fieldset>
<Textfield
id="lastname"
v-model="lastname"
name="lastname"
label="Nom :"
autocomplete="family-name"
/>
<Textfield
id="firstname"
v-model="firstname"
name="firstname"
label="Prénom :"
autocomplete="given-name"
/>
</Fieldset>

<Textfield
id="company"
v-model="company"
name="company"
label="Organisation :"
autocomplete="organization"
/>
<Textfield
id="role"
v-model="role"
name="role"
label="Rôle :"
autocomplete="organization-title"
/>

<Fieldset>
<Textfield
id="email"
v-model="email"
name="email"
type="email"
label="E-mail * :"
required
autocomplete="email"
/>
<Textfield
id="phone"
v-model="phone"
name="phone"
type="tel"
label="Téléphone :"
autocomplete="tel"
Expand All @@ -49,16 +49,10 @@
<Textfield
id="message"
type="textarea"
v-model="message"
name="message"
label="Votre besoin :"
/>

<vue-hcaptcha
@verify="getCaptcha"
sitekey="359a430d-a0bf-4548-a583-959e93110b6d"
aria-label="Rendez vous sur https://www.hcaptcha.com/accessibility pour obtenir un passe-droit accessible"
/>

<div class="form-submit">
<div class="error-message" v-if="error" aria-live="assertive">
{{ error }}
Expand All @@ -79,133 +73,41 @@
aria-label="Soumettez le formulaire"
/>
</div>

<altcha-widget
:challengeurl="captchaChallengeUrl"
name="captcha"
spamfilter
floating
/>
</form>
</template>

<script setup lang="ts">
import { ref } from "vue";
import VueHcaptcha from "@hcaptcha/vue3-hcaptcha";
import AppButton from "@/components/shared/AppButton.vue";
import { post } from "@/util/fetch";
import Textfield from "@/components/shared/form/AppTextfield.vue";
import Fieldset from "@/components/shared/form/AppFieldset.vue";
import Textfield from "@/components/shared/form/AppTextfield.vue";
import { captchaChallengeUrl, post } from "@/util/fetch";
import { extractFormData, validatePhone } from "@/util/form";
import { ref } from "vue";
/**
* Validates an email address to ensure it is not empty and follows a valid email format.
*
* @returns {boolean} True if the email is valid, false otherwise.
*/
const validateEmail = () => {
/**
* Regular expression to validate an email address:
* - It allows alphanumeric characters, dots, hyphens, percent signs, and plus or minus signs.
* - It requires an "@" symbol after the username.
* - It allows a domain consisting of alphanumeric characters, hyphens, and dots.
* - The domain must end with a dot followed by at least two alphabetic characters.
*/
const emailPattern = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
if (!email.value) {
error.value = "L'e-mail est requis.";
} else if (!emailPattern.test(email.value)) {
error.value = "L'e-mail n'est pas valide.";
} else {
error.value = "";
return true;
}
};
/**
* Validates a phone number to ensure it is not empty and follows a valid phone number format.
*
* @returns {boolean} True if the phone number is valid, false otherwise.
*/
const validatePhone = () => {
/**
* Regular expression to validate a phone number:
* - It can optionally start with a plus sign (+).
* - It can then contain one or more digits (0-9), commas, periods, or whitespace.
* - The string must end after the allowed characters.
*/
const phonePattern = /^\+?[\d,. ]+$/;
if (!phone.value) {
error.value = "";
return true;
} else if (!phonePattern.test(phone.value)) {
error.value =
"Le téléphone doit contenir uniquement des chiffres, +, ,, . ou un espace.";
return false;
}
};
/**
* Validates whether a CAPTCHA field is empty.
*
* @returns {boolean} True if the CAPTCHA field is not empty, false otherwise.
*/
const validateCaptcha = () => {
if (!captcha.value) {
error.value = "Le captcha est requis.";
} else {
error.value = "";
return true;
}
};
/**
* Validates a complete form by executing a set of validation functions.
*
* @returns {boolean} True if all fields are valid, false otherwise.
*/
const validateForm = () => {
const validationFunctions = [
validateEmail, // Function to validate email
validatePhone, // Function to validate phone number
validateCaptcha, // Function to validate CAPTCHA
];
// Return true if all form fields are valid, otherwise return false.
return validationFunctions.every((validationFunction) =>
validationFunction(),
);
};
const error = ref("");
const success = ref("");
const submitForm = async () => {
if (validateForm()) {
const formData = {
firstname: firstname.value,
lastname: lastname.value,
company: company.value,
role: role.value,
phone: phone.value,
email: email.value,
message: message.value,
captcha: captcha.value,
};
const submitForm = async (event: Event) => {
const form = event.target as HTMLFormElement;
const formData = extractFormData(form);
if (validatePhone(formData.phone as string, error)) {
try {
await post("client_case", formData);
success.value = "Votre demande a bien été enregistrée";
form.reset();
} catch {
error.value = "Erreur d'envoi, veuillez réessayer plus tard.";
}
}
};
function getCaptcha(response: any) {
captcha.value = response;
}
let captcha = ref("");
const error = ref("");
const firstname = ref("");
const lastname = ref("");
const company = ref("");
const role = ref("");
const phone = ref("");
const email = ref("");
const message = ref("");
const success = ref("");
</script>

<style scoped lang="scss">
Expand Down
Loading

0 comments on commit 9fe83e6

Please sign in to comment.