137 lines
4.0 KiB
Vue
137 lines
4.0 KiB
Vue
<script lang="ts" setup>
|
|
import { reactive, ref } from 'vue'
|
|
import Swal from 'sweetalert2'
|
|
import { Box } from '@/components/ui/box'
|
|
import { Button } from '@/components/ui/button'
|
|
import { Field, FieldGroup, FieldLabel } from '@/components/ui/field'
|
|
import { PasswordInput } from '@/components/ui/password-input'
|
|
import { getApiErrorMessage } from '@/core/utils/getApiErrorMessage'
|
|
import { updatePassword } from '@/modules/profile/services/profile.service'
|
|
|
|
defineProps<{
|
|
embedded?: boolean
|
|
}>()
|
|
|
|
const saving = ref(false)
|
|
|
|
const form = reactive({
|
|
current_password: '',
|
|
password: '',
|
|
password_confirmation: '',
|
|
})
|
|
|
|
function resetForm() {
|
|
form.current_password = ''
|
|
form.password = ''
|
|
form.password_confirmation = ''
|
|
}
|
|
|
|
async function onSubmit() {
|
|
if (form.password !== form.password_confirmation) {
|
|
await Swal.fire({
|
|
icon: 'warning',
|
|
title: 'Kata laluan tidak sepadan',
|
|
text: 'Kata laluan baharu dan pengesahan mesti sama.',
|
|
})
|
|
return
|
|
}
|
|
|
|
saving.value = true
|
|
|
|
try {
|
|
const res = await updatePassword({
|
|
current_password: form.current_password,
|
|
password: form.password,
|
|
password_confirmation: form.password_confirmation,
|
|
})
|
|
|
|
if (!res.success) {
|
|
throw new Error(res.message ?? 'Gagal menukar kata laluan.')
|
|
}
|
|
|
|
resetForm()
|
|
|
|
await Swal.fire({
|
|
toast: true,
|
|
position: 'top-end',
|
|
icon: 'success',
|
|
title: res.message || 'Kata laluan berjaya dikemas kini.',
|
|
showConfirmButton: false,
|
|
timer: 3000,
|
|
})
|
|
} catch (error) {
|
|
await Swal.fire({
|
|
icon: 'error',
|
|
title: 'Ralat',
|
|
text: getApiErrorMessage(error, 'Gagal menukar kata laluan.'),
|
|
})
|
|
} finally {
|
|
saving.value = false
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div>
|
|
<div v-if="!embedded" class="mb-6 flex items-center">
|
|
<h2 class="mr-auto text-lg font-medium">Tukar Kata Laluan</h2>
|
|
</div>
|
|
<Box raised="single" :class="embedded ? 'p-0' : 'p-0 lg:mt-5'">
|
|
<form @submit.prevent="onSubmit">
|
|
<div class="flex items-center border-b border-foreground/15 p-5">
|
|
<h3 class="mr-auto text-base font-medium">Tukar Kata Laluan</h3>
|
|
</div>
|
|
<div class="p-5">
|
|
<FieldGroup>
|
|
<FieldGroup>
|
|
<Field>
|
|
<FieldLabel for="password-current">Kata Laluan Semasa</FieldLabel>
|
|
<PasswordInput
|
|
id="password-current"
|
|
v-model="form.current_password"
|
|
placeholder="Kata laluan semasa"
|
|
autocomplete="current-password"
|
|
required
|
|
:disabled="saving"
|
|
/>
|
|
</Field>
|
|
<Field>
|
|
<FieldLabel for="password-new">Kata Laluan Baharu</FieldLabel>
|
|
<PasswordInput
|
|
id="password-new"
|
|
v-model="form.password"
|
|
placeholder="Kata laluan baharu"
|
|
minlength="8"
|
|
autocomplete="new-password"
|
|
required
|
|
:disabled="saving"
|
|
/>
|
|
</Field>
|
|
<Field>
|
|
<FieldLabel for="password-confirm">Sahkan Kata Laluan Baharu</FieldLabel>
|
|
<PasswordInput
|
|
id="password-confirm"
|
|
v-model="form.password_confirmation"
|
|
placeholder="Sahkan kata laluan baharu"
|
|
minlength="8"
|
|
autocomplete="new-password"
|
|
required
|
|
:disabled="saving"
|
|
/>
|
|
</Field>
|
|
</FieldGroup>
|
|
<Field orientation="horizontal">
|
|
<Button type="submit" variant="primary" :disabled="saving">
|
|
{{ saving ? 'Menyimpan...' : 'Tukar Kata Laluan' }}
|
|
</Button>
|
|
<Button look="outline" type="button" :disabled="saving" @click="resetForm">
|
|
Set Semula
|
|
</Button>
|
|
</Field>
|
|
</FieldGroup>
|
|
</div>
|
|
</form>
|
|
</Box>
|
|
</div>
|
|
</template>
|