add email login

This commit is contained in:
Emily
2024-10-10 15:49:55 +02:00
parent 0a7f2b58d0
commit 80e3b0caa9
14 changed files with 531 additions and 27 deletions

View File

@@ -7,13 +7,22 @@ const route = useRoute();
const { project, projectList, projectId } = useProject();
const justLogged = computed(() => route.query.just_logged);
const jwtLogin = computed(() => route.query.jwt_login as string);
onMounted(() => {
if (justLogged.value) {
setTimeout(() => {
location.href = '/'
}, 500)
const { token, setToken } = useAccessToken();
onMounted(async () => {
if (jwtLogin.value) {
setToken(jwtLogin.value);
const user = await $fetch<any>('/api/user/me', { headers: { 'Authorization': 'Bearer ' + token.value } })
const loggedUser = useLoggedUser();
loggedUser.user = user;
// setTimeout(() => { location.reload(); }, 100);
}
if (justLogged.value) { setTimeout(() => { location.href = '/' }, 500) }
})
const firstInteraction = useFetch<boolean>('/api/project/first_interaction', {

View File

@@ -0,0 +1,31 @@
<script setup lang="ts">
definePageMeta({ layout: 'none' });
const route = useRoute();
const jwtLogin = computed(() => route.query.jwt_login as string);
const { token, setToken } = useAccessToken();
onMounted(async () => {
if (jwtLogin.value) {
setToken(jwtLogin.value);
const user = await $fetch<any>('/api/user/me', { headers: { 'Authorization': 'Bearer ' + token.value } })
const loggedUser = useLoggedUser();
loggedUser.user = user;
setTimeout(() => { location.href = '/project_creation?just_logged=true' }, 100);
}
})
</script>
<template>
<div> You will be redirected soon </div>
</template>
<style scoped lang="scss"></style>

View File

@@ -20,9 +20,9 @@ async function loginWithoutAuth() {
const user = await $fetch<any>('/api/user/me', { headers: { 'Authorization': 'Bearer ' + token.value } })
const loggedUser = useLoggedUser();
loggedUser.value = user;
loggedUser.user = user;
console.log('LOGIN DONE - USER', loggedUser.value);
console.log('LOGIN DONE - USER', loggedUser.user);
const isFirstTime = await $fetch<boolean>('/api/user/is_first_time', { headers: { 'Authorization': 'Bearer ' + token.value } })
@@ -58,9 +58,9 @@ async function handleOnSuccess(response: any) {
const user = await $fetch<any>('/api/user/me', { headers: { 'Authorization': 'Bearer ' + token.value } })
const loggedUser = useLoggedUser();
loggedUser.value = user;
loggedUser.user = user;
console.log('LOGIN DONE - USER', loggedUser.value);
console.log('LOGIN DONE - USER', loggedUser.user);
const isFirstTime = await $fetch<boolean>('/api/user/is_first_time', { headers: { 'Authorization': 'Bearer ' + token.value } })
@@ -107,6 +107,48 @@ onMounted(() => {
}
})
const isEmailLogin = ref<boolean>(false);
const email = ref<string>("");
const password = ref<string>("");
function goBackToEmailLogin() {
isEmailLogin.value = false;
email.value = '';
password.value = '';
}
async function signInWithCredentials() {
try {
const result = await $fetch<{error:true, message:string} | {error: false, access_token:string}>('/api/auth/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email: email.value, password: password.value })
})
if (result.error) return alert(result.message);
setToken(result.access_token);
const user = await $fetch<any>('/api/user/me', { headers: { 'Authorization': 'Bearer ' + token.value } })
const loggedUser = useLoggedUser();
loggedUser.user = user;
console.log('LOGIN DONE - USER', loggedUser.user);
const isFirstTime = await $fetch<boolean>('/api/user/is_first_time', { headers: { 'Authorization': 'Bearer ' + token.value } })
if (isFirstTime === true) {
router.push('/project_creation?just_logged=true');
} else {
router.push('/?just_logged=true');
}
} catch (ex) {
alert('Something went wrong.');
}
}
</script>
@@ -126,7 +168,7 @@ onMounted(() => {
</div>
<div class="text-text text-[2.2rem] font-bold poppins">
Sign in with
Sign in
</div>
<div class="text-text/80 text-[1.2rem] text-center w-[70%] poppins mt-2">
@@ -141,23 +183,52 @@ onMounted(() => {
<div class="mt-12">
<div v-if="!isNoAuth && isEmailLogin" class="flex flex-col gap-2">
<div class="flex flex-col gap-4 z-[100] w-[20vw] min-w-[20rem]">
<LyxUiInput class="px-3 py-2" placeholder="Email" v-model="email"></LyxUiInput>
<LyxUiInput class="px-3 py-2" placeholder="Password" v-model="password" type="password">
</LyxUiInput>
</div>
<div class="flex justify-center mt-4 z-[100]">
<LyxUiButton @click="signInWithCredentials()" class="text-center" type="primary">
Sign in
</LyxUiButton>
</div>
<div @click="goBackToEmailLogin()"
class="mt-4 text-center text-lyx-text-dark underline cursor-pointer z-[100]">
Go back
</div>
</div>
<div v-if="!isNoAuth && !isEmailLogin" class="flex flex-col gap-2">
<div v-if="!isNoAuth" class="flex flex-col gap-2">
<div @click="login"
class="hover:bg-accent cursor-pointer flex text-[1.3rem] gap-4 items-center border-[1px] border-gray-400 rounded-lg px-8 py-3 relative z-[2]">
class="hover:bg-lyx-primary cursor-pointer flex text-[1.3rem] gap-4 items-center border-[1px] border-gray-400 rounded-lg px-8 py-3 relative z-[2]">
<div class="flex items-center">
<i class="fab fa-google"></i>
</div>
Continue with Google
</div>
<div
class=" opacity-35 cursor-not-allowed flex text-[1.3rem] gap-4 items-center border-[1px] border-gray-400 rounded-lg px-8 py-3 relative z-[2]">
<div @click="isEmailLogin = true"
class="hover:bg-[#262626] cursor-pointer flex text-[1.3rem] gap-4 items-center border-[1px] border-gray-400 rounded-lg px-8 py-3 relative z-[2]">
<div class="flex items-center">
<i class="fab fa-github"></i>
<i class="far fa-envelope"></i>
</div>
Continue with GitHub
Continue with Email
</div>
<RouterLink tag="div" to="/register" class="mt-4 text-center text-lyx-text-dark underline cursor-pointer z-[100]">
You don't have an account ? Sign up
</RouterLink>
</div>
<div v-if="isNoAuth" @click="loginWithoutAuth"
@@ -170,7 +241,7 @@ onMounted(() => {
</div>
<div class="text-[.9rem] poppins mt-12 text-text-sub text-center relative z-[2]">
<div class="text-[.9rem] poppins mt-20 text-text-sub text-center relative z-[2]">
By continuing you are accepting
<br>
our

View File

@@ -0,0 +1,170 @@
<script setup lang="ts">
definePageMeta({ layout: 'none' });
const emailSended = ref<boolean>(false);
const email = ref<string>("");
const password = ref<string>("");
const passwordConfirm = ref<string>("");
const canRegister = computed(() => {
if (email.value.length == 0) return false;
if (!email.value.includes('@')) return false;
if (!email.value.includes('.')) return false;
if (password.value !== passwordConfirm.value) return false;
if (password.value.length < 6) return false;
return true;
});
async function registerAccount() {
try {
const res = await $fetch<any>('/api/auth/register', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ email: email.value, password: password.value })
});
if (res.error === true) return alert(res.message);
emailSended.value = true;
} catch (ex) {
alert('Something went wrong');
}
}
</script>
<template>
<div class="home w-full h-full">
<div class="flex h-full">
<div class="flex-1 flex flex-col items-center pt-20 lg:pt-[22vh]">
<div class="rotating-thing absolute top-0"></div>
<div class="mb-8 bg-black rounded-xl">
<img class="w-[5rem]" :src="'logo.png'">
</div>
<div class="text-text text-[2.2rem] font-bold poppins">
Sign up
</div>
<div class="text-text/80 text-[1.2rem] text-center w-[70%] poppins mt-2">
Track web analytics and custom events
<br>
with extreme simplicity in under 30 sec.
<br>
<!-- <div class="font-bold poppins mt-4">
Start for Free now! Up to 3k visits/events monthly.
</div> -->
</div>
<div v-if="!emailSended" class="mt-12">
<div class="flex flex-col gap-2">
<div class="flex flex-col gap-4 z-[100] w-[20vw] min-w-[20rem]">
<LyxUiInput class="px-3 py-2" placeholder="Email" v-model="email">
</LyxUiInput>
<LyxUiInput class="px-3 py-2" placeholder="Password" v-model="password" type="password">
</LyxUiInput>
<LyxUiInput class="px-3 py-2" placeholder="Confirm password" v-model="passwordConfirm"
type="password">
</LyxUiInput>
</div>
<div class="text-lyx-text-darker text-end text-[.8rem]">
Password must be at least 6 chars long
</div>
<div class="flex justify-center mt-4 z-[100]">
<LyxUiButton :disabled="!canRegister" @click="registerAccount()" class="text-center"
type="primary">
Sign up
</LyxUiButton>
</div>
<RouterLink to="/login"
class="mt-4 text-center text-lyx-text-dark underline cursor-pointer z-[100]">
Go back to login
</RouterLink>
</div>
</div>
<div v-if="emailSended" class="mt-12 flex flex-col text-center text-[1.1rem] z-[100]">
<div>
We sent you a confirm email.
</div>
<div>
Please check your inbox to confirm your account and complete your registration.
</div>
<RouterLink tag="div" to="/login"
class="mt-6 text-center text-lyx-text-dark underline cursor-pointer">
Go back
</RouterLink>
</div>
<div v-if="!emailSended" class="text-[.9rem] poppins mt-20 text-text-sub text-center relative z-[2]">
By continuing you are accepting
<br>
our
<a class="underline" href="https://litlyx.com/terms" target="_blank">Terms of Service</a> and
<a class="underline" href="https://litlyx.com/privacy" target="_blank">Privacy Policy</a>.
</div>
</div>
<div class="grow flex-1 items-center justify-center hidden lg:flex">
<!-- <GlobeSvg></GlobeSvg> -->
<img :src="'image-bg.png'" class="h-full py-6">
</div>
</div>
</div>
</template>
<style scoped lang="scss">
.rotating-thing {
height: 100%;
aspect-ratio: 1 / 1;
opacity: 0.15;
background: radial-gradient(51.24% 31.29% at 50% 50%, rgb(51, 58, 232) 0%, rgba(51, 58, 232, 0) 100%);
animation: 12s linear 0s infinite normal none running spin;
}
.google-login {
cursor: pointer;
font-weight: bold;
background-color: #fcefed;
padding: 1rem 2rem;
border-radius: 1rem;
display: flex;
gap: 1rem;
align-items: center;
&.disabled {
filter: brightness(50%);
}
i {
font-size: 1.5rem;
}
}
</style>