| 
									
										
										
										
											2021-10-07 09:39:47 -08:00
										 |  |  | <template> | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |   <v-container | 
					
						
							|  |  |  |     fill-height | 
					
						
							|  |  |  |     fluid | 
					
						
							|  |  |  |     class="d-flex justify-center align-center" | 
					
						
							|  |  |  |   > | 
					
						
							|  |  |  |     <v-card | 
					
						
							|  |  |  |       color="background d-flex flex-column align-center" | 
					
						
							|  |  |  |       flat | 
					
						
							|  |  |  |       width="600px" | 
					
						
							|  |  |  |     > | 
					
						
							|  |  |  |       <v-card-title class="text-h5 justify-center"> | 
					
						
							|  |  |  |         {{ $t("user.reset-password") }} | 
					
						
							|  |  |  |       </v-card-title> | 
					
						
							| 
									
										
										
										
											2021-10-07 09:39:47 -08:00
										 |  |  |       <BaseDivider /> | 
					
						
							|  |  |  |       <v-card-text> | 
					
						
							|  |  |  |         <v-form @submit.prevent="requestLink()"> | 
					
						
							|  |  |  |           <v-text-field | 
					
						
							|  |  |  |             v-model="email" | 
					
						
							| 
									
										
										
										
											2025-06-28 15:59:58 +02:00
										 |  |  |             :prepend-inner-icon="$globals.icons.email" | 
					
						
							|  |  |  |             variant="solo-filled" | 
					
						
							|  |  |  |             flat | 
					
						
							| 
									
										
										
										
											2021-10-07 09:39:47 -08:00
										 |  |  |             autofocus | 
					
						
							|  |  |  |             name="login" | 
					
						
							|  |  |  |             :label="$t('user.email')" | 
					
						
							|  |  |  |             type="text" | 
					
						
							|  |  |  |           /> | 
					
						
							|  |  |  |           <v-text-field | 
					
						
							|  |  |  |             v-model="password" | 
					
						
							| 
									
										
										
										
											2025-06-28 15:59:58 +02:00
										 |  |  |             variant="solo-filled" | 
					
						
							|  |  |  |             flat | 
					
						
							|  |  |  |             :prepend-inner-icon="$globals.icons.lock" | 
					
						
							| 
									
										
										
										
											2021-10-07 09:39:47 -08:00
										 |  |  |             name="password" | 
					
						
							| 
									
										
										
										
											2023-10-26 15:26:14 +02:00
										 |  |  |             :label="$t('user.password')" | 
					
						
							| 
									
										
										
										
											2021-10-07 09:39:47 -08:00
										 |  |  |             type="password" | 
					
						
							|  |  |  |             :rules="[validators.required]" | 
					
						
							|  |  |  |           /> | 
					
						
							|  |  |  |           <v-text-field | 
					
						
							|  |  |  |             v-model="passwordConfirm" | 
					
						
							| 
									
										
										
										
											2025-06-28 15:59:58 +02:00
										 |  |  |             variant="solo-filled" | 
					
						
							|  |  |  |             flat | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |             validate-on="blur" | 
					
						
							| 
									
										
										
										
											2025-06-28 15:59:58 +02:00
										 |  |  |             :prepend-inner-icon="$globals.icons.lock" | 
					
						
							| 
									
										
										
										
											2021-10-07 09:39:47 -08:00
										 |  |  |             name="password" | 
					
						
							| 
									
										
										
										
											2023-10-26 15:26:14 +02:00
										 |  |  |             :label="$t('user.confirm-password')" | 
					
						
							| 
									
										
										
										
											2021-10-07 09:39:47 -08:00
										 |  |  |             type="password" | 
					
						
							|  |  |  |             :rules="[validators.required, passwordMatch]" | 
					
						
							|  |  |  |           /> | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |           <p class="text-center"> | 
					
						
							|  |  |  |             {{ $t("user.please-enter-password") }} | 
					
						
							|  |  |  |           </p> | 
					
						
							| 
									
										
										
										
											2021-10-07 09:39:47 -08:00
										 |  |  |           <v-card-actions class="justify-center"> | 
					
						
							|  |  |  |             <div class="max-button"> | 
					
						
							|  |  |  |               <v-btn | 
					
						
							|  |  |  |                 :loading="loading" | 
					
						
							|  |  |  |                 color="primary" | 
					
						
							|  |  |  |                 :disabled="token === ''" | 
					
						
							|  |  |  |                 type="submit" | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |                 size="large" | 
					
						
							| 
									
										
										
										
											2021-10-07 09:39:47 -08:00
										 |  |  |                 rounded | 
					
						
							|  |  |  |                 class="rounded-xl" | 
					
						
							|  |  |  |                 block | 
					
						
							|  |  |  |               > | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |                 <v-icon start> | 
					
						
							| 
									
										
										
										
											2021-10-07 09:39:47 -08:00
										 |  |  |                   {{ $globals.icons.lock }} | 
					
						
							|  |  |  |                 </v-icon> | 
					
						
							|  |  |  |                 {{ token === "" ? "Token Required" : $t("user.reset-password") }} | 
					
						
							|  |  |  |               </v-btn> | 
					
						
							|  |  |  |             </div> | 
					
						
							|  |  |  |           </v-card-actions> | 
					
						
							|  |  |  |         </v-form> | 
					
						
							|  |  |  |       </v-card-text> | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |       <v-btn | 
					
						
							|  |  |  |         class="mx-auto" | 
					
						
							|  |  |  |         variant="text" | 
					
						
							|  |  |  |         to="/login" | 
					
						
							|  |  |  |       > | 
					
						
							|  |  |  |         {{ $t("user.login") }} | 
					
						
							|  |  |  |       </v-btn> | 
					
						
							| 
									
										
										
										
											2021-10-07 09:39:47 -08:00
										 |  |  |     </v-card> | 
					
						
							|  |  |  |   </v-container> | 
					
						
							|  |  |  | </template> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <script lang="ts"> | 
					
						
							| 
									
										
										
										
											2021-11-06 11:28:47 -08:00
										 |  |  | import { useUserApi } from "~/composables/api"; | 
					
						
							| 
									
										
										
										
											2021-10-07 09:39:47 -08:00
										 |  |  | import { alert } from "~/composables/use-toast"; | 
					
						
							|  |  |  | import { validators } from "@/composables/use-validators"; | 
					
						
							|  |  |  | import { useRouteQuery } from "~/composables/use-router"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  | export default defineNuxtComponent({ | 
					
						
							| 
									
										
										
										
											2021-10-07 09:39:47 -08:00
										 |  |  |   setup() { | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |     definePageMeta({ | 
					
						
							|  |  |  |       layout: "basic", | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-07 09:39:47 -08:00
										 |  |  |     const state = reactive({ | 
					
						
							|  |  |  |       email: "", | 
					
						
							|  |  |  |       password: "", | 
					
						
							|  |  |  |       passwordConfirm: "", | 
					
						
							|  |  |  |       loading: false, | 
					
						
							|  |  |  |       error: false, | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |     const i18n = useI18n(); | 
					
						
							|  |  |  |     const passwordMatch = () => state.password === state.passwordConfirm || i18n.t("user.password-must-match"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Set page title
 | 
					
						
							|  |  |  |     useSeoMeta({ | 
					
						
							|  |  |  |       title: i18n.t("user.login"), | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2021-10-07 09:39:47 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // ===================
 | 
					
						
							|  |  |  |     // Token Getter
 | 
					
						
							|  |  |  |     const token = useRouteQuery("token", ""); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // ===================
 | 
					
						
							|  |  |  |     // API
 | 
					
						
							| 
									
										
										
										
											2021-11-06 11:28:47 -08:00
										 |  |  |     const api = useUserApi(); | 
					
						
							| 
									
										
										
										
											2021-10-07 09:39:47 -08:00
										 |  |  |     async function requestLink() { | 
					
						
							|  |  |  |       state.loading = true; | 
					
						
							|  |  |  |       // TODO: Fix Response to send meaningful error
 | 
					
						
							|  |  |  |       const { response } = await api.users.resetPassword({ | 
					
						
							|  |  |  |         token: token.value, | 
					
						
							|  |  |  |         email: state.email, | 
					
						
							|  |  |  |         password: state.password, | 
					
						
							|  |  |  |         passwordConfirm: state.passwordConfirm, | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       state.loading = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (response?.status === 200) { | 
					
						
							|  |  |  |         state.loading = false; | 
					
						
							|  |  |  |         state.error = false; | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |         alert.success(i18n.t("user.password-updated")); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							| 
									
										
										
										
											2021-10-07 09:39:47 -08:00
										 |  |  |         state.loading = false; | 
					
						
							|  |  |  |         state.error = true; | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |         alert.error(i18n.t("events.something-went-wrong")); | 
					
						
							| 
									
										
										
										
											2021-10-07 09:39:47 -08:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return { | 
					
						
							|  |  |  |       passwordMatch, | 
					
						
							|  |  |  |       token, | 
					
						
							|  |  |  |       requestLink, | 
					
						
							|  |  |  |       validators, | 
					
						
							|  |  |  |       ...toRefs(state), | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | </script> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <style lang="css"> | 
					
						
							|  |  |  | .max-button { | 
					
						
							|  |  |  |   width: 300px; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2023-10-26 15:26:14 +02:00
										 |  |  | </style> |