1 parent
2b94bcc20e
commit
327f59104d
6 files changed
+151
-124
No files matched your search
@@ -0,0 +1,47 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { reactive } from 'vue'
|
||||||
|
import { authClient } from '@/lib/auth-client.js'
|
||||||
|
|
||||||
|
const REMEMBERED_EMAIL_KEY = 'rememberedEmail'
|
||||||
|
|
||||||
|
const signInData = reactive({
|
||||||
|
email: localStorage.getItem(REMEMBERED_EMAIL_KEY) ?? '',
|
||||||
|
password: '',
|
||||||
|
rememberMe: true,
|
||||||
|
callbackURL: 'https://madsky.ru',
|
||||||
|
})
|
||||||
|
|
||||||
|
const signIn = async () => {
|
||||||
|
const { data, error } = await authClient.signIn.email({
|
||||||
|
email: signInData.email,
|
||||||
|
password: signInData.password,
|
||||||
|
rememberMe: signInData.rememberMe,
|
||||||
|
callbackURL: '/',
|
||||||
|
})
|
||||||
|
|
||||||
|
if (data) {
|
||||||
|
if (signInData.rememberMe) {
|
||||||
|
localStorage.setItem(REMEMBERED_EMAIL_KEY, signInData.email)
|
||||||
|
} else {
|
||||||
|
localStorage.removeItem(REMEMBERED_EMAIL_KEY)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="d-flex flex-column ga-2">
|
||||||
|
<div class="text-uppercase">sign in</div>
|
||||||
|
<v-text-field prepend-inner-icon="mdi-email" placeholder="E-mail" v-model="signInData.email" />
|
||||||
|
<v-text-field prepend-inner-icon="mdi-lock" placeholder="Password" v-model="signInData.password" />
|
||||||
|
<div class="d-flex ga-2 align-center">
|
||||||
|
<v-switch color="info" v-model="signInData.rememberMe" label="Remember me" />
|
||||||
|
<v-spacer />
|
||||||
|
<div>
|
||||||
|
<v-btn prepend-icon="mdi-login" density="comfortable" color="primary" @click="signIn">SIGN IN</v-btn>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped lang="scss"></style>
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { reactive, ref, watch } from 'vue'
|
||||||
|
import { authClient } from '@/lib/auth-client.js'
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
|
||||||
|
const REMEMBERED_EMAIL_KEY = 'rememberedEmail'
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
|
const otpError = ref('')
|
||||||
|
const signIn = reactive({
|
||||||
|
email: localStorage.getItem(REMEMBERED_EMAIL_KEY) ?? '',
|
||||||
|
OTP: '',
|
||||||
|
rememberMe: true,
|
||||||
|
showOTP: false,
|
||||||
|
})
|
||||||
|
|
||||||
|
const sendOTP = async () => {
|
||||||
|
const { data, error } = await authClient.emailOtp.sendVerificationOtp({
|
||||||
|
email: signIn.email,
|
||||||
|
type: 'sign-in',
|
||||||
|
})
|
||||||
|
|
||||||
|
if (data?.success) {
|
||||||
|
if (signIn.rememberMe) localStorage.setItem(REMEMBERED_EMAIL_KEY, signIn.email)
|
||||||
|
signIn.showOTP = true
|
||||||
|
otpError.value = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
localStorage.removeItem(REMEMBERED_EMAIL_KEY)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => signIn.OTP,
|
||||||
|
(val) => {
|
||||||
|
if (val.length >= 1) otpError.value = ''
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
const checkOTP = async () => {
|
||||||
|
const { data, error } = await authClient.signIn.emailOtp({
|
||||||
|
email: signIn.email,
|
||||||
|
otp: signIn.OTP,
|
||||||
|
})
|
||||||
|
if (data) router.push('/')
|
||||||
|
if (error) {
|
||||||
|
if (error.status === 400 && error.message) otpError.value = error.message
|
||||||
|
if (error.status === 403 && error.message) {
|
||||||
|
otpError.value = error.message
|
||||||
|
signIn.showOTP = false
|
||||||
|
}
|
||||||
|
signIn.OTP = ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="d-flex flex-column ga-2">
|
||||||
|
<div class="d-flex ga-2 align-center justify-space-between">
|
||||||
|
<div class="text-uppercase">Sign In</div>
|
||||||
|
<v-chip v-if="otpError" size="small" variant="flat" color="error" density="compact">{{ otpError }}</v-chip>
|
||||||
|
</div>
|
||||||
|
<v-text-field prepend-inner-icon="mdi-email" density="comfortable" placeholder="E-mail" v-model="signIn.email" />
|
||||||
|
<div v-if="signIn.showOTP">
|
||||||
|
<v-otp-input density="comfortable" autofocus pattern="numeric" v-model="signIn.OTP" @finish="checkOTP" />
|
||||||
|
<div class="d-flex ga-1 justify-end">
|
||||||
|
<v-btn prepend-icon="mdi-autorenew" density="comfortable" text="Resend Code" @click="sendOTP" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="d-flex ga-1 justify-end" v-else>
|
||||||
|
<v-btn prepend-icon="mdi-email-fast-outline" density="comfortable" @click="sendOTP" text="Send Code" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped lang="scss"></style>
|
||||||
@@ -22,7 +22,7 @@ const title = 'Ulitka'
|
|||||||
const isAuth = computed(() => !!session.value.data)
|
const isAuth = computed(() => !!session.value.data)
|
||||||
|
|
||||||
function goToSignIn() {
|
function goToSignIn() {
|
||||||
router.push({ path: '/sign-in-otp' })
|
router.push({ path: '/sign-in' })
|
||||||
}
|
}
|
||||||
|
|
||||||
function goToSignUp() {
|
function goToSignUp() {
|
||||||
|
|||||||
+1
-6
@@ -8,7 +8,6 @@ import { authClient } from '@/lib/auth-client.ts'
|
|||||||
import { gamesRoutes } from '@/router/games.ts'
|
import { gamesRoutes } from '@/router/games.ts'
|
||||||
import { settingsRoutes } from '@/router/settings.ts'
|
import { settingsRoutes } from '@/router/settings.ts'
|
||||||
import { calendarRoutes } from '@/router/calendar.ts'
|
import { calendarRoutes } from '@/router/calendar.ts'
|
||||||
import SignInViewOtp from '@/views/users/SignInViewOtp.vue'
|
|
||||||
import SignInView from '@/views/users/SignInView.vue'
|
import SignInView from '@/views/users/SignInView.vue'
|
||||||
|
|
||||||
declare module 'vue-router' {
|
declare module 'vue-router' {
|
||||||
@@ -30,15 +29,11 @@ const router = createRouter({
|
|||||||
component: HomeView,
|
component: HomeView,
|
||||||
meta: { layout: 'Default', fluid: true },
|
meta: { layout: 'Default', fluid: true },
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: 'sign-in-otp',
|
|
||||||
path: '/sign-in-otp',
|
|
||||||
component: SignInViewOtp,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: 'sign-in',
|
name: 'sign-in',
|
||||||
path: '/sign-in',
|
path: '/sign-in',
|
||||||
component: SignInView,
|
component: SignInView,
|
||||||
|
meta: { breadcrumb: 'Sign-In' },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/sign-up',
|
path: '/sign-up',
|
||||||
|
|||||||
@@ -1,49 +1,33 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { reactive } from 'vue'
|
import { ref } from 'vue'
|
||||||
import { authClient } from '@/lib/auth-client.js'
|
import SignInOtp from '@/components/SignInOtp.vue'
|
||||||
|
import SignInEmail from '@/components/SignInEmail.vue'
|
||||||
|
|
||||||
const REMEMBERED_EMAIL_KEY = 'rememberedEmail'
|
const tab = ref('otp')
|
||||||
|
|
||||||
const signInData = reactive({
|
|
||||||
email: localStorage.getItem(REMEMBERED_EMAIL_KEY) ?? '',
|
|
||||||
password: '',
|
|
||||||
rememberMe: true,
|
|
||||||
callbackURL: 'https://madsky.ru',
|
|
||||||
})
|
|
||||||
|
|
||||||
const signIn = async () => {
|
|
||||||
const { data, error } = await authClient.signIn.email({
|
|
||||||
email: signInData.email,
|
|
||||||
password: signInData.password,
|
|
||||||
rememberMe: signInData.rememberMe,
|
|
||||||
callbackURL: '/',
|
|
||||||
})
|
|
||||||
|
|
||||||
if (data) {
|
|
||||||
if (signInData.rememberMe) {
|
|
||||||
localStorage.setItem(REMEMBERED_EMAIL_KEY, signInData.email)
|
|
||||||
} else {
|
|
||||||
localStorage.removeItem(REMEMBERED_EMAIL_KEY)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<v-row>
|
<v-row justify="center">
|
||||||
<v-col cols="12" md="4" sm="8" offset-sm="2" offset-md="4" offset="0">
|
<v-col cols="12" lg="4" md="4" sm="8">
|
||||||
<div class="d-flex flex-column ga-2">
|
<v-sheet>
|
||||||
<div class="text-uppercase">sign in</div>
|
<v-tabs v-model="tab" color="primary" density="compact" align-tabs="center">
|
||||||
<v-text-field prepend-inner-icon="mdi-email" placeholder="E-mail" v-model="signInData.email" />
|
<v-tab value="otp">OTP</v-tab>
|
||||||
<v-text-field prepend-inner-icon="mdi-lock" placeholder="Password" v-model="signInData.password" />
|
<v-tab value="email">Email</v-tab>
|
||||||
<div class="d-flex ga-2 align-center">
|
</v-tabs>
|
||||||
<v-switch color="info" v-model="signInData.rememberMe" label="Remember me" />
|
|
||||||
<v-spacer />
|
<v-tabs-window v-model="tab">
|
||||||
<div>
|
<v-tabs-window-item value="otp">
|
||||||
<v-btn prepend-icon="mdi-login" density="comfortable" color="primary" @click="signIn">SIGN IN</v-btn>
|
<v-sheet class="pa-4">
|
||||||
</div>
|
<sign-in-otp />
|
||||||
</div>
|
</v-sheet>
|
||||||
</div>
|
</v-tabs-window-item>
|
||||||
|
<v-tabs-window-item value="email">
|
||||||
|
<v-sheet class="pa-4">
|
||||||
|
<sign-in-email />
|
||||||
|
</v-sheet>
|
||||||
|
</v-tabs-window-item>
|
||||||
|
</v-tabs-window>
|
||||||
|
</v-sheet>
|
||||||
</v-col>
|
</v-col>
|
||||||
</v-row>
|
</v-row>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -1,76 +0,0 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
import { computed, reactive } from 'vue'
|
|
||||||
import { authClient } from '@/lib/auth-client.js'
|
|
||||||
import { useRouter } from 'vue-router'
|
|
||||||
|
|
||||||
const REMEMBERED_EMAIL_KEY = 'rememberedEmail'
|
|
||||||
const router = useRouter()
|
|
||||||
|
|
||||||
const signInData = reactive({
|
|
||||||
email: localStorage.getItem(REMEMBERED_EMAIL_KEY) ?? '',
|
|
||||||
OTP: '',
|
|
||||||
rememberMe: true,
|
|
||||||
showOTP: false,
|
|
||||||
})
|
|
||||||
|
|
||||||
const sendOTP = async () => {
|
|
||||||
const { data, error } = await authClient.emailOtp.sendVerificationOtp({
|
|
||||||
email: signInData.email,
|
|
||||||
type: 'sign-in',
|
|
||||||
})
|
|
||||||
|
|
||||||
if (data?.success) {
|
|
||||||
if (signInData.rememberMe) localStorage.setItem(REMEMBERED_EMAIL_KEY, signInData.email)
|
|
||||||
signInData.showOTP = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if (error) {
|
|
||||||
localStorage.removeItem(REMEMBERED_EMAIL_KEY)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const checkOTP = async () => {
|
|
||||||
const { data, error } = await authClient.signIn.emailOtp({
|
|
||||||
email: signInData.email,
|
|
||||||
otp: signInData.OTP,
|
|
||||||
})
|
|
||||||
console.log({ data, error })
|
|
||||||
if (data) {
|
|
||||||
router.push('/')
|
|
||||||
}
|
|
||||||
|
|
||||||
if (error) {
|
|
||||||
console.log(error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<v-row justify="center">
|
|
||||||
<v-col cols="12" lg="3" md="4" sm="8">
|
|
||||||
<div class="d-flex flex-column ga-2">
|
|
||||||
<div class="text-uppercase">sign in</div>
|
|
||||||
<v-text-field
|
|
||||||
prepend-inner-icon="mdi-email"
|
|
||||||
density="comfortable"
|
|
||||||
placeholder="E-mail"
|
|
||||||
v-model="signInData.email"
|
|
||||||
/>
|
|
||||||
<v-otp-input
|
|
||||||
v-if="signInData.showOTP"
|
|
||||||
density="comfortable"
|
|
||||||
autofocus
|
|
||||||
pattern="numeric"
|
|
||||||
v-model="signInData.OTP"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<v-btn v-if="signInData.showOTP" prepend-icon="mdi-login" variant="flat" @click="checkOTP" color="primary">
|
|
||||||
Sign in
|
|
||||||
</v-btn>
|
|
||||||
<v-btn v-else prepend-icon="mdi-email-fast-outline" variant="flat" @click="sendOTP"> Send Code </v-btn>
|
|
||||||
</div>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style scoped lang="scss"></style>
|
|
||||||
Reference in new issue
Block a user