forked from noxious/client
Added reset password modal form
This commit is contained in:
parent
a71890ab68
commit
be854a79b8
50
src/components/gui/ResetPassword.vue
Normal file
50
src/components/gui/ResetPassword.vue
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
<template>
|
||||||
|
<Modal :is-modal-open="gameStore.uiSettings.isPasswordResetOpen" @modal:close="() => gameStore.togglePasswordReset()" :modal-width="400" :modal-height="300" :is-resizable="false">
|
||||||
|
<template #modalHeader>
|
||||||
|
<h3 class="m-0 font-medium shrink-0 text-white">Reset Password</h3>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #modalBody>
|
||||||
|
<div class="h-[calc(100%_-_32px)] p-4">
|
||||||
|
<form class="h-full flex flex-col justify-between" @submit.prevent="resetPasswordFunc">
|
||||||
|
<div class="flex flex-col relative">
|
||||||
|
<p>Fill in your email to receive a password reset request.</p>
|
||||||
|
<input type="email" name="email" class="input-field" v-model="email" placeholder="E-mail" />
|
||||||
|
<span v-if="resetPasswordError" class="text-red-200 text-xs absolute top-full mt-1">{{ resetPasswordError }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="grid grid-flow-col justify-stretch gap-4">
|
||||||
|
<button class="btn-empty py-1.5 px-4 min-w-24 inline-block" @click.stop="gameStore.togglePasswordReset">Cancel</button>
|
||||||
|
<button class="btn-cyan py-1.5 px-4 min-w-24 inline-block" type="submit">Send mail</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</Modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onMounted, ref } from 'vue'
|
||||||
|
import { resetPassword } from '@/services/authentication'
|
||||||
|
import { useGameStore } from '@/stores/gameStore'
|
||||||
|
import Modal from '@/components/utilities/Modal.vue'
|
||||||
|
|
||||||
|
const gameStore = useGameStore()
|
||||||
|
const email = ref('')
|
||||||
|
const resetPasswordError = ref('')
|
||||||
|
|
||||||
|
async function resetPasswordFunc() {
|
||||||
|
// check if email is valid
|
||||||
|
if (email.value === '') {
|
||||||
|
resetPasswordError.value = 'Please enter an email'
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// send reset password event to server
|
||||||
|
const response = await resetPassword(email.value)
|
||||||
|
|
||||||
|
if (response.success === undefined) {
|
||||||
|
resetPasswordError.value = response.error
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
@ -2,7 +2,7 @@
|
|||||||
<Teleport to="body">
|
<Teleport to="body">
|
||||||
<div v-if="isModalOpenRef" class="fixed border-solid border-2 border-gray-500 z-50 flex flex-col backdrop-blur-sm shadow-lg" :style="modalStyle">
|
<div v-if="isModalOpenRef" class="fixed border-solid border-2 border-gray-500 z-50 flex flex-col backdrop-blur-sm shadow-lg" :style="modalStyle">
|
||||||
<div @mousedown="startDrag" class="cursor-move p-2.5 flex justify-between items-center border-solid border-0 border-b border-gray-500 relative">
|
<div @mousedown="startDrag" class="cursor-move p-2.5 flex justify-between items-center border-solid border-0 border-b border-gray-500 relative">
|
||||||
<div class="rounded-t-md absolute w-full h-full top-0 left-0 bg-[url('/assets/ui-texture.png')] bg-no-repeat bg-center bg-cover opacity-90"></div>
|
<div class="rounded-t absolute w-full h-full top-0 left-0 bg-[url('/assets/ui-texture.png')] bg-no-repeat bg-center bg-cover opacity-90"></div>
|
||||||
<div class="relative z-10">
|
<div class="relative z-10">
|
||||||
<slot name="modalHeader" />
|
<slot name="modalHeader" />
|
||||||
</div>
|
</div>
|
||||||
@ -16,7 +16,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="overflow-hidden grow relative">
|
<div class="overflow-hidden grow relative">
|
||||||
<div class="rounded-b-md absolute w-full h-full top-0 left-0 bg-[url('/assets/ui-texture.png')] bg-no-repeat bg-cover bg-center opacity-90"></div>
|
<div class="rounded-b absolute w-full h-full top-0 left-0 bg-[url('/assets/ui-texture.png')] bg-no-repeat bg-cover bg-center opacity-90"></div>
|
||||||
<div class="relative z-10 h-full">
|
<div class="relative z-10 h-full">
|
||||||
<slot name="modalBody" />
|
<slot name="modalBody" />
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="relative max-lg:h-dvh flex flex-row-reverse">
|
<div class="relative max-lg:h-dvh flex flex-row-reverse">
|
||||||
|
<ResetPassword />
|
||||||
<div class="lg:bg-gradient-to-l bg-gradient-to-b from-gray-900 to-transparent w-full lg:w-1/2 h-[35dvh] lg:h-dvh absolute left-0 max-lg:bottom-0 lg:top-0 z-10"></div>
|
<div class="lg:bg-gradient-to-l bg-gradient-to-b from-gray-900 to-transparent w-full lg:w-1/2 h-[35dvh] lg:h-dvh absolute left-0 max-lg:bottom-0 lg:top-0 z-10"></div>
|
||||||
<div class="bg-[url('/assets/login/login-bg.png')] w-full lg:w-1/2 h-[35dvh] lg:h-dvh absolute left-0 max-lg:bottom-0 lg:top-0 bg-no-repeat bg-cover bg-center"></div>
|
<div class="bg-[url('/assets/login/login-bg.png')] w-full lg:w-1/2 h-[35dvh] lg:h-dvh absolute left-0 max-lg:bottom-0 lg:top-0 bg-no-repeat bg-cover bg-center"></div>
|
||||||
<div class="bg-gray-900 z-20 w-full lg:w-1/2 h-[65dvh] lg:h-dvh relative">
|
<div class="bg-gray-900 z-20 w-full lg:w-1/2 h-[65dvh] lg:h-dvh relative">
|
||||||
@ -20,7 +21,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<span v-if="loginError" class="text-red-200 text-xs absolute top-full mt-1">{{ loginError }}</span>
|
<span v-if="loginError" class="text-red-200 text-xs absolute top-full mt-1">{{ loginError }}</span>
|
||||||
</div>
|
</div>
|
||||||
<button class="inline-flex self-end p-0 text-cyan-300 text-base">Forgot password?</button>
|
<button @click.stop="gameStore.togglePasswordReset" type="button" class="inline-flex self-end p-0 text-cyan-300 text-base">Forgot password?</button>
|
||||||
<button class="btn-cyan px-0 xs:w-full" type="submit">Play now</button>
|
<button class="btn-cyan px-0 xs:w-full" type="submit">Play now</button>
|
||||||
|
|
||||||
<!-- Divider shape -->
|
<!-- Divider shape -->
|
||||||
@ -71,6 +72,7 @@ import { onMounted, ref } from 'vue'
|
|||||||
import { login, register } from '@/services/authentication'
|
import { login, register } from '@/services/authentication'
|
||||||
import { useGameStore } from '@/stores/gameStore'
|
import { useGameStore } from '@/stores/gameStore'
|
||||||
import { useCookies } from '@vueuse/integrations/useCookies'
|
import { useCookies } from '@vueuse/integrations/useCookies'
|
||||||
|
import ResetPassword from '@/components/gui/ResetPassword.vue'
|
||||||
|
|
||||||
const gameStore = useGameStore()
|
const gameStore = useGameStore()
|
||||||
const username = ref('')
|
const username = ref('')
|
||||||
@ -115,6 +117,11 @@ async function registerFunc() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (email.value === '') {
|
||||||
|
loginError.value = 'Please enter an email'
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// send register event to server
|
// send register event to server
|
||||||
const response = await register(username.value, email.value, password.value)
|
const response = await register(username.value, email.value, password.value)
|
||||||
|
|
||||||
|
@ -25,3 +25,12 @@ export async function login(username: string, password: string) {
|
|||||||
return { error: error.response.data.message }
|
return { error: error.response.data.message }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function resetPassword(email: string) {
|
||||||
|
try {
|
||||||
|
const response = await axios.post(`${config.server_endpoint}/reset-password`, { email })
|
||||||
|
return { success: true, token: response.data.token }
|
||||||
|
} catch (error: any) {
|
||||||
|
return { error: error.response.data.message }
|
||||||
|
}
|
||||||
|
}
|
@ -27,7 +27,8 @@ export const useGameStore = defineStore('game', {
|
|||||||
uiSettings: {
|
uiSettings: {
|
||||||
isChatOpen: false,
|
isChatOpen: false,
|
||||||
isCharacterProfileOpen: false,
|
isCharacterProfileOpen: false,
|
||||||
isGmPanelOpen: false
|
isGmPanelOpen: false,
|
||||||
|
isPasswordResetOpen: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -71,6 +72,9 @@ export const useGameStore = defineStore('game', {
|
|||||||
toggleCharacterProfile() {
|
toggleCharacterProfile() {
|
||||||
this.uiSettings.isCharacterProfileOpen = !this.uiSettings.isCharacterProfileOpen
|
this.uiSettings.isCharacterProfileOpen = !this.uiSettings.isCharacterProfileOpen
|
||||||
},
|
},
|
||||||
|
togglePasswordReset() {
|
||||||
|
this.uiSettings.isPasswordResetOpen = !this.uiSettings.isPasswordResetOpen
|
||||||
|
},
|
||||||
initConnection() {
|
initConnection() {
|
||||||
this.connection = io(config.server_endpoint, {
|
this.connection = io(config.server_endpoint, {
|
||||||
secure: !config.development,
|
secure: !config.development,
|
||||||
@ -116,6 +120,7 @@ export const useGameStore = defineStore('game', {
|
|||||||
this.gameSettings.isCameraFollowingCharacter = false
|
this.gameSettings.isCameraFollowingCharacter = false
|
||||||
this.uiSettings.isChatOpen = false
|
this.uiSettings.isChatOpen = false
|
||||||
this.uiSettings.isCharacterProfileOpen = false
|
this.uiSettings.isCharacterProfileOpen = false
|
||||||
|
this.uiSettings.isPasswordResetOpen = false
|
||||||
|
|
||||||
this.world.date = new Date()
|
this.world.date = new Date()
|
||||||
this.world.isRainEnabled = false
|
this.world.isRainEnabled = false
|
||||||
|
Loading…
x
Reference in New Issue
Block a user