From d9cf3ef50979705334de8a9fcefce824f9e9fc3c Mon Sep 17 00:00:00 2001 From: Erik Borgeteien Hansen <erik@erikbhan.no> Date: Mon, 25 Apr 2022 12:41:38 +0200 Subject: [PATCH] refactor to tailwindcss --- src/components/RegisterFormComponent.vue | 375 ++++++++++++++--------- src/utils/apiutil.js | 19 +- src/views/RegisterView.vue | 11 +- 3 files changed, 251 insertions(+), 154 deletions(-) diff --git a/src/components/RegisterFormComponent.vue b/src/components/RegisterFormComponent.vue index b69d388..254e427 100644 --- a/src/components/RegisterFormComponent.vue +++ b/src/components/RegisterFormComponent.vue @@ -1,155 +1,240 @@ <template> - <v-form ref="form" v-model="valid" lazy-validation> - <v-text-field - v-model="email" - :rules="emailRules" - label="E-mail" - required - ></v-text-field> - - <v-text-field - v-model="password" - :counter="32" - :rules="passwordRules" - label="Passord" - :append-icon="passwordHidden ? 'mdi-eye' : 'mdi-eye-off'" - :type="passwordHidden ? 'text' : 'password'" - @click:append="passwordHidden = !passwordHidden" - required - ></v-text-field> - - <v-container class="grey lighten-5"> - <v-row> - <v-text-field - class="pr-2" - v-model="firstName" - :counter="32" - :rules="firstNameRules" - label="Fornavn" - required - ></v-text-field> - - <v-text-field - class="pl-2" - v-model="lastName" - :counter="32" - :rules="lastNameRules" - label="Etternavn" - required - ></v-text-field> - </v-row> - </v-container> - - <v-text-field - v-model="address" - :counter="32" - :rules="addressRules" - label="Addresse" - required - ></v-text-field> - - <!-- <v-text-field - v-model="confirmPassword" - :rules="confirmPasswordRules" - label="Bekreft passord" - :append-icon="confirmPasswordHidden ? 'mdi-eye' : 'mdi-eye-off'" - :type="confirmPasswordHidden ? 'text' : 'password'" - @click:append="confirmPasswordHidden = !confirmPasswordHidden" - required - ></v-text-field> --> - - <!-- <v-select - v-model="select" - :items="items" - :rules="[(v) => !!v || 'Item is required']" - label="Item" - required - ></v-select> --> - - <!-- <v-checkbox - v-model="checkbox" - :rules="[(v) => !!v || 'You must agree to continue!']" - label="Do you agree?" - required - ></v-checkbox> --> - - <v-btn :disabled="!valid" color="success" class="mr-4" @click="submit()" - >Registrer</v-btn - > - - <v-btn color="error" class="mr-4" @click="reset()">Tøm felter</v-btn> - </v-form> + <section + class="max-w-4xl p-6 mx-auto bg-white rounded-md shadow-md dark:bg-gray-800" + > + <h2 class="text-lg font-semibold text-gray-700 capitalize dark:text-white"> + Opprett ny bruker + </h2> + + <form @submit.prevent> + <div class="grid grid-cols-1 gap-6 mt-4 sm:grid-cols-2"> + <div> + <label class="text-gray-700 dark:text-gray-200" for="email" + >E-mail</label + > + <input + v-model="email" + id="email" + type="email" + class="block w-full px-4 py-2 mt-2 text-gray-700 bg-white border border-gray-200 rounded-md dark:bg-gray-800 dark:text-gray-300 dark:border-gray-600 focus:border-blue-400 focus:ring-blue-300 focus:ring-opacity-40 dark:focus:border-blue-300 focus:outline-none focus:ring" + /> + </div> + + <div> + <label class="text-gray-700 dark:text-gray-200" for="pword" + >Passord</label + > + <input + v-model="pword" + id="pword" + type="password" + class="block w-full px-4 py-2 mt-2 text-gray-700 bg-white border border-gray-200 rounded-md dark:bg-gray-800 dark:text-gray-300 dark:border-gray-600 focus:border-blue-400 focus:ring-blue-300 focus:ring-opacity-40 dark:focus:border-blue-300 focus:outline-none focus:ring" + /> + </div> + + <div> + <label class="text-gray-700 dark:text-gray-200" for="cpword" + >Bekreft Passord</label + > + <input + v-model="cpword" + id="cpword" + type="password" + class="block w-full px-4 py-2 mt-2 text-gray-700 bg-white border border-gray-200 rounded-md dark:bg-gray-800 dark:text-gray-300 dark:border-gray-600 focus:border-blue-400 focus:ring-blue-300 focus:ring-opacity-40 dark:focus:border-blue-300 focus:outline-none focus:ring" + /> + </div> + + <div> + <label class="text-gray-700 dark:text-gray-200" for="fname" + >Fornavn</label + > + <input + v-model="fname" + id="fname" + type="text" + class="block w-full px-4 py-2 mt-2 text-gray-700 bg-white border border-gray-200 rounded-md dark:bg-gray-800 dark:text-gray-300 dark:border-gray-600 focus:border-blue-400 focus:ring-blue-300 focus:ring-opacity-40 dark:focus:border-blue-300 focus:outline-none focus:ring" + /> + </div> + + <div> + <label class="text-gray-700 dark:text-gray-200" for="lname" + >Etternavn</label + > + <input + v-model="lname" + id="lname" + type="text" + class="block w-full px-4 py-2 mt-2 text-gray-700 bg-white border border-gray-200 rounded-md dark:bg-gray-800 dark:text-gray-300 dark:border-gray-600 focus:border-blue-400 focus:ring-blue-300 focus:ring-opacity-40 dark:focus:border-blue-300 focus:outline-none focus:ring" + /> + </div> + + <div> + <label class="text-gray-700 dark:text-gray-200" for="address" + >Addresse</label + > + <input + v-model="address" + id="address" + type="text" + class="block w-full px-4 py-2 mt-2 text-gray-700 bg-white border border-gray-200 rounded-md dark:bg-gray-800 dark:text-gray-300 dark:border-gray-600 focus:border-blue-400 focus:ring-blue-300 focus:ring-opacity-40 dark:focus:border-blue-300 focus:outline-none focus:ring" + /> + </div> + </div> + + <div class="flex justify-end mt-6"> + <button + class="px-6 py-2 leading-5 text-white transition-colors duration-200 transform bg-gray-700 rounded-md hover:bg-gray-600 focus:outline-none focus:bg-gray-600" + @click="submit()" + type="submit" + :disabled="loading" + > + <div v-if="loading"> + <div v-if="loading" class="lds-ring"> + <div></div> + <div></div> + <div></div> + <div></div> + </div> + </div> + <div v-else>Lagre</div> + </button> + </div> + </form> + <p v-for="error of v$.$errors" :key="error.$uid"> + <strong>{{ error.$validator }}</strong> + <small> on property</small> + <strong>{{ error.$property }}</strong> + <small> says:</small> + <strong>{{ error.$message }}</strong> + </p> + </section> </template> + <script> -import axios from "axios"; +import useVuelidate from "@vuelidate/core"; +import { doLogin, registerUser } from "@/utils/apiutil"; +import { required, email, minLength, sameAs } from "@vuelidate/validators"; -export default { - data: () => ({ - passwordHidden: false, - // confirmPasswordHidden: false, - valid: true, - firstName: "", - firstNameRules: [ - (v) => !!v || "Fornavn er påkrevd", - (v) => (v && v.length <= 32) || "Fornavn må være mindre enn 32 bokstaver", - ], - lastName: "", - lastNameRules: [ - (v) => !!v || "Etternavn er påkrevd", - (v) => - (v && v.length <= 32) || "Etternavn må være mindre enn 32 bokstaver", - ], - address: "", - addressRules: [ - (v) => !!v || "Addresse er påkrevd", - (v) => - (v && v.length <= 32) || "Addresse må være mindre enn 32 bokstaver", - ], - password: "", - passwordRules: [ - (v) => !!v || "Passord er påkrevd", - (v) => (v && v.length <= 32) || "Passord må være mindre enn 32 tegn", - (v) => (v && v.length >= 8) || "Passord må være større enn 8 tegn", - ], - // confirmPassword: "", - // confirmPasswordRules: [ - // (v) => !!v || "Passord er påkrevd", - // (v) => (v && v.length <= 32) || "Passord må være mindre enn 32 bokstaver", - // // (v) => v === this.password || "Passordene må være like", - // ], - email: "", - emailRules: [ - (v) => !!v || "E-mail is required", - (v) => /.+@.+\..+/.test(v) || "E-mail must be valid", - ], - // select: null, - // items: ["Item 1", "Item 2", "Item 3", "Item 4"], - // checkbox: false, - }), +// const isEmailTaken = (value) => +// fetch(`/api/unique/${value}`).then((r) => r.json()); // check the email in the server +export default { + setup: () => ({ v$: useVuelidate() }), + data() { + return { + userCreated: false, + loading: false, + email: "", + pword: "", + cpword: "", + fname: "", + lname: "", + address: "", + }; + }, + validations() { + return { + email: { + required, + email, + // isUnique: helpers.withAsync(isEmailTaken), + }, + pword: { + required, + minLength: minLength(8), + }, + cpword: { sameAs: sameAs(this.pword) }, + fname: { required }, + lname: { required }, + address: { required }, + }; + }, methods: { - submit() { - console.log("Attempting to register user"); - this.valid = this.$refs.form.validate(); - if (!this.valid) return; - this.valid = false; - console.log("User is validated"); - axios - .post("http://localhost:3000/api/register", { - email: this.email, - firstName: this.firstName, - lastname: this.lastName, - password: this.password, - address: this.address, - }) - .then(console.log("Sent")) - .catch((e) => console.log(e)); - }, - reset() { - this.$refs.form.reset(); - this.$refs.form.resetValidation(); - this.valid = true; + async submit() { + console.log(this.$data); + + this.loading = true; + const result = await this.v$.$validate(); + + if (!result) { + //Invalid form + console.log("Form not submitted"); + this.loading = false; + return; + } + + const registerInfo = { + email: this.email, + firstName: this.fname, + lastname: this.lname, + password: this.pword, + address: this.address, + }; + + let response = await registerUser(registerInfo); + if (response.status === 200) this.userCreated = true; + + //If a user is created succsessfully, try to login + if (this.userCreated) { + const loginRequest = { + email: this.user.email, + password: this.user.password, + }; + + const loginResponse = await doLogin(loginRequest); + + if (loginResponse === "Failed login") { + this.message = "kunne ikke logge inn"; + this.$store.commit("logout"); + this.$router.push("/login"); + return; + } + this.$router.push("/"); + + this.$store.commit("saveToken", loginResponse); + console.log(loginResponse); + } + this.loading = false; }, }, }; </script> + +<style scoped> +/* https://loading.io/css/ */ +.lds-ring { + display: inline-block; + position: relative; + width: 20px; + height: 20px; +} +.lds-ring div { + box-sizing: border-box; + display: block; + position: absolute; + width: 16px; + height: 16px; + margin: 2px; + border: 2px solid #fff; + border-radius: 50%; + animation: lds-ring 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite; + border-color: #fff transparent transparent transparent; +} +.lds-ring div:nth-child(1) { + animation-delay: -0.45s; +} +.lds-ring div:nth-child(2) { + animation-delay: -0.3s; +} +.lds-ring div:nth-child(3) { + animation-delay: -0.15s; +} +@keyframes lds-ring { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } +} +</style> diff --git a/src/utils/apiutil.js b/src/utils/apiutil.js index 773bd8d..e0f6efc 100644 --- a/src/utils/apiutil.js +++ b/src/utils/apiutil.js @@ -1,9 +1,26 @@ import axios from "axios"; +const API_URL = "http://65.108.62.223:3000/api/"; + export function doLogin(loginRequest) { return axios - .post(`http://65.108.62.223:3000/api/login/authentication`, loginRequest) + .post(API_URL + "login/authentication", loginRequest) .then((response) => { return response.data; }); } + +export function registerUser(registerInfo) { + return axios + .post(API_URL + "register", { + email: registerInfo.email, + firstName: registerInfo.fname, + lastname: registerInfo.lname, + password: registerInfo.pword, + address: registerInfo.address, + }) + .then((response) => { + return response; + }) + .catch((err) => console.log(err)); +} diff --git a/src/views/RegisterView.vue b/src/views/RegisterView.vue index 9d2ee69..c1478be 100644 --- a/src/views/RegisterView.vue +++ b/src/views/RegisterView.vue @@ -1,5 +1,7 @@ <template> - <register-form-component id="form" class="pa-8" /> + <div class="h-screen bg-gray-200 content-center grid place-items-center"> + <RegisterFormComponent /> + </div> </template> <script> @@ -11,10 +13,3 @@ export default { }, }; </script> - -<style scoped> -#form { - max-width: 600px; - margin: auto; -} -</style> -- GitLab