<template> <div> <base-toaster :open="toasterIsOpen" @close="hideDialog" > <div class="flex justify-between space-x-4 items-center"> <font-awesome-icon class="ml-3" icon="fa-solid fa-thumbs-up " size="lg" /> <h4> Sign up request successful. An activation link has been sent to the email {{ email.val }} . Please click the link to activate your account. </h4> <button class="btn btn-outline" @click="hideDialog" > <font-awesome-icon icon="fa-regular fa-circle-xmark" size="2x" /> </button> </div> </base-toaster> <div class="flex items-center justify-center"> <div class="sm:block border border-gray-300 rounded-lg w-2/5 mt-6 rounded-lg p-4"> <div class="p-8 text-left"> <h1 class=" font-bold text-left font-montserrat text-3xl sm:text-5xl mb-7 " > Sign Up to join CD-Code </h1> <form @submit.prevent="register"> <div class="my-4" :class="{ invalid: !name.isValid }" > <div class="flex justify-between"> <h1 class=" text-left font-bold mb-2 text-xl sm:text-2xl font-montserrat " > Name* </h1> <h1 class=" text-left text-gray-400 mb-2 text-lg sm:text-2xl font-montserrat " > Note: * fields are mandatory. </h1> </div> <input v-model.trim="name.val" type="text" class=" text-xl outline-none px-4 py-5 w-full bg-transparent border rounded-lg border-gray-400 hover:border-blue-700 focus:border-blue-700 " placeholder="Enter full name." @blur="clearValidity('name')" > <p v-if="!name.isValid" class="text-red-500" > Name must not be empty. </p> </div> <div class="my-4" :class="{ invalid: !email.isValid }" > <h1 class=" text-left font-bold mb-2 text-xl sm:text-2xl font-montserrat " > Email* </h1> <input v-model.trim="email.val" type="email" class=" text-xl outline-none w-full bg-transparent px-4 py-5 rounded-lg border border-gray-400 hover:border-blue-700 focus:border-blue-700 " placeholder="Enter email." @blur="clearValidity('email')" > <p v-if="!email.isValid" class="text-red-500" > Email must not be empty. </p> <p v-if="error && errorMsg" class="text-red-500" > {{ errorMsg }} </p> </div> <div class="my-4" :class="{ invalid: !password.isValid }" > <h1 class=" text-left font-bold mb-2 text-xl sm:text-2xl font-montserrat " > Password* </h1> <input v-model.trim="password.val" type="password" class=" text-xl outline-none px-4 py-5 rounded-lg border border-gray-400 w-full bg-transparent hover:border-blue-700 focus:border-blue-700 " placeholder="Password must be minimum 6 character." @blur="clearValidity('password')" > <p v-if="!password.isValid" class="text-red-500" > Password must not be empty or less than 6 character. </p> </div> <div class="my-4" :class="{ invalid: !username.isValid }" > <h1 class=" text-left font-bold mb-2 text-xl sm:text-2xl font-montserrat " > Username* </h1> <input v-model.trim="username.val" type="text" class=" text-xl outline-none px-4 py-5 rounded-lg border border-gray-400 w-full bg-transparent border-b hover:border-blue-700 focus:border-blue-700 " placeholder="Username must be minimum 3 character." @blur="clearValidity('username')" > <p v-if="!username.isValid" class="text-red-500" > Username must not be empty. </p> </div> <div class="my-4" :class="{ invalid: !current_role.isValid }" > <h1 class=" text-left font-bold mb-2 text-xl sm:text-2xl font-montserrat " > Current Role* </h1> <select id="inline-current-role" v-model="current_role.val" class=" bg-white px-4 py-5 rounded-lg border border-gray-400 w-full text-gray-700 outline-none bg-transparent border-b hover:border-blue-700 " @blur="clearValidity('current_role')" > <option id="phd" value="PhD" > PhD </option> <option id="postdoc" value="PostDoc" > PostDoc </option> <option id="research_scientist" value="Research_Scientist" > Research Scientist </option> <option id="principal_investigator" value="Principal_Investigator" > Principal Investigator </option> </select> <p v-if="!current_role.isValid" class="text-red-500" > Select a current role. </p> </div> <div class="my-4" :class="{ invalid: !scientific_discipline.isValid }" > <h1 class=" text-left font-bold mb-2 text-xl sm:text-2xl font-montserrat " > Scientific Disciplines* </h1> <div v-for="options in scientificDisciplineOptions" :key="options.id" > <input :id="options.id" v-model="scientific_discipline.val" type="checkbox" class="h-6 w-6" :name="options" :value="options.discipline" @blur="clearValidity('scientific_discipline')" > <label class="mx-3" :for="options.id" >{{ options.discipline }}</label> </div> <p v-if="!scientific_discipline.isValid" class="text-red-500" > Please select atleast one scientific discipline. </p> </div> <div class="my-4" :class="{ invalid: !affiliation.isValid }" > <h1 class=" text-left font-bold mb-2 text-xl sm:text-2xl font-montserrat " > Affiliation* </h1> <input v-model.trim="affiliation.val" type="text" class=" text-xl outline-none px-4 py-5 rounded-lg border border-gray-400 w-full bg-transparent hover:border-blue-700 focus:border-blue-700 " placeholder="Institute name currently associated with." @blur="clearValidity('affiliation')" > <p v-if="!affiliation.isValid" class="text-red-500" > Affiliation must not be empty. </p> </div> <div class="my-4" :class="{ invalid: !profileLink.isValid }" > <h1 class=" text-left font-bold mb-2 text-xl sm:text-2xl font-montserrat " > Profile Link </h1> <input v-model.trim="profileLink.val" type="text" class=" text-xl outline-none px-4 py-5 rounded-lg border border-gray-400 w-full bg-transparent hover:border-blue-700 focus:border-blue-700 " placeholder="eg- https://www.google.com (optional)" @blur="clearValidity('profileLink')" > <p v-if="!profileLink.isValid" class="text-red-500" > The url entered is invalid. Please check it again! </p> <p v-if="profileLinkError && profileLinkErrMsg" class="text-red-500" > {{ profileLinkErrMsg }} </p> </div> <div class="my-4" :class="{ invalid: !motivation.isValid }" > <h1 class=" text-left font-bold mb-2 text-xl sm:text-2xl font-montserrat " > Motivation* </h1> <textarea v-model.trim="motivation.val" rows="5" type="text" class=" text-xl outline-none w-full bg-transparent px-4 py-5 rounded-lg border border-gray-400 hover:border-blue-700 focus:border-blue-700 " placeholder="Your motivation text." @blur="clearValidity('motivation')" /> </div> <p v-if="!motivation.isValid" class="text-red-500" > Motivation text must not be empty. </p> <p v-if="!formIsValid" class="font-bold text-red-400" > Required fields were not provided. </p> <p v-show="error" class="text-red-500" > {{ errorMsg }} </p> <div v-if="isLoading"> <base-spinner /> </div> <button type="submit" class=" bg-blue-500 text-2xl font-bold rounded-lg p-5 mr-4 w-1/3 text-white hover:bg-blue-700 " > Create Account </button> <div> <h4 class="mt-6"> Already have an account? <a class="text-blue-500 hover:text-blue-600 hover:no-underline" @click="$router.go(-1)" >Sign in</a> </h4> </div> </form> </div> </div> </div> </div> </template> <script> import BaseSpinner from '../components/UI/BaseSpinner.vue'; import BaseToaster from '../components/UI/BaseToaster.vue'; let host = require('@/components/js/const').apiHost; export default { name: 'Register', components: { BaseToaster, BaseSpinner }, data() { return { name: { val: '', isValid: true, }, email: { val: '', isValid: true, }, password: { val: '', isValid: true, }, username: { val: '', isValid: true, }, motivation: { val: '', isValid: true, }, affiliation: { val: '', isValid: true, }, current_role: { val: '', isValid: true, }, profileLink: { val: '', isValid: true, }, scientific_discipline: { val: [], isValid: true, }, formIsValid: true, error: false, errorMsg: ``, isDev: process.env.NODE_ENV === 'development', toasterIsOpen: false, scientificDisciplineOptions: [ { id: '1', discipline: 'Physics' }, { id: '2', discipline: 'Chemistry' }, { id: '3', discipline: 'Biology' }, { id: '4', discipline: 'Computer Science' }, { id: '5', discipline: 'Mathematics' }, ], profileLinkError: false, profileLinkErrMsg: '', selected: [], isLoading: false, }; }, computed: {}, methods: { clearValidity(input) { this[input].isValid = true; }, validateForm() { this.formIsValid = true; if (this.name.val === '') { this.name.isValid = false; this.formIsValid = false; } if (this.email.val === '') { this.email.isValid = false; this.formIsValid = false; } if (this.password.val === '' || this.password.val.length < 6) { this.password.isValid = false; this.formIsValid = false; } if (this.username.val === '' || this.username.val.length < 3) { this.username.isValid = false; this.formIsValid = false; } if (this.current_role.val === '') { this.current_role.isValid = false; this.formIsValid = false; } if (this.scientific_discipline.val.length === 0) { this.scientific_discipline.isValid = false; this.formIsValid = false; } if (this.affiliation.val === '') { this.affiliation.isValid = false; this.formIsValid = false; } if (this.isValidHttpUrl() === false) { this.profileLink.isValid = false; this.formIsValid = false; } if (this.motivation.val === '') { this.motivation.isValid = false; this.formIsValid = false; } }, isValidHttpUrl() { let timer = null; let pattern = new RegExp( '^(https?:\\/\\/)?' + // protocol '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|' + // domain name '((\\d{1,3}\\.){3}\\d{1,3}))' + // OR ip (v4) address '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*' + // port and path '(\\?[;&a-z\\d%_.~+=-]*)?' + // query string '(\\#[-a-z\\d_]*)?$', 'i' ); // fragment locator let isValid; if (this.profileLink.val === '') { console.log('profile link empty'); return true; } else { isValid = pattern.test(this.profileLink.val); console.log('lint is there', isValid); } return isValid; // if(!isValid){ // console.log("triggered"); // this.profileLinkError= true; // this.profileLinkErrMsg="The url entered is invalid. Please check it again!" // } else{ // this.profileLinkError=false; // this.profileLinkErrMsg="" // } // clearTimeout(timer); // timer= setTimeout(()=>{ // let isValid= pattern.test(this.profileLink.val); // if(!isValid){ // console.log("triggered"); // this.profileLinkError= true; // this.profileLinkErrMsg="The url entered is invalid. Please check it again!" // } else{ // this.profileLinkError=false; // this.profileLinkErrMsg="" // } // }, 1000) }, showDialog() { this.toasterIsOpen = true; }, hideDialog() { this.toasterIsOpen = false; this.$router.push('login'); }, async register(e) { const vm = this; vm.validateForm(); if (!vm.formIsValid) { return; } if (vm.isDev) { host = require('@/components/js/const').devApiHost; } this.isLoading = true; const res = await fetch(`${host}/api/auth/local/register`, { method: 'POST', mode: 'cors', // no-cors, *cors, same-origin cache: 'no-cache', // *default, no-cache, reload, force-cache, headers: { 'Content-Type': 'application/json', // 'Content-Type': 'application/x-www-form-urlencoded', }, body: JSON.stringify({ full_name: vm.name.val, password: vm.password.val, email: vm.email.val, username: vm.username.val, motivation_text: vm.motivation.val, current_role: vm.current_role.val, scientific_discipline: vm.scientific_discipline.val, current_affiliation: vm.affiliation.val, profile_link: vm.profileLink.val, }), }); if (!res.ok && res.status === 500) { this.isLoading = false; this.error = true; this.errorMsg = `${res.status} Internal Error, please write a mail to DDCode Admin`; return; } if (!res.ok && res.status === 405) { this.isLoading = false; this.error = true; this.errorMsg = `${res.status} Internal Error, please write a mail to DDCode Admin`; return; } const response = await res.json(); if (!res.ok && response.error.status === 400 && response.error.message === 'Email is already taken') { this.isLoading = false; this.error = true; this.errorMsg = 'Email Address already registered with an existing account. You can reset your password by clicking forget password from sign up page.'; this.password.val = ''; return; } this.isLoading = false; vm.toasterIsOpen = true; this.error = false; this.errorMsg = ''; // try { // await vm.axios.post(`${host}/api/auth/local/register`, { // full_name: vm.name.val, // password: vm.password.val, // email: vm.email.val, // username: vm.username.val, // motivation_text: vm.motivation.val, // current_role: vm.current_role.val, // scientific_discipline: vm.scientific_discipline.val, // current_affiliation: vm.affiliation.val, // profile_link: vm.profileLink.val, // }); // this.isLoading = false; // vm.toasterIsOpen = true; // this.error = false; // this.errorMsg = ""; // //vm.$router.push('login') // } catch (e) { // console.error(e); // this.isLoading = false; // if (e.message === "Request failed with status code 405") { // console.log(e.message); // } // if (e.message === "Request failed with status code 400") { // vm.error = true; // vm.errorMsg = // "Email Address already registered with an existing account. You can reset your password by clicking forget password from sign up page."; // } // } }, }, }; </script> <style scoped> @import url("~@/assets/bootstrap.css"); a { color: #ef0087 !important; } .invalid h1, .invalid label { color: red; } .invalid input, .invalid textarea, .invalid select { border: 1px solid red; } </style>