101 lines
3.7 KiB
Vue
101 lines
3.7 KiB
Vue
<script setup lang="ts">
|
|
import Button from '@/components/ui/Button.vue';
|
|
import Checkbox from '@/components/ui/Checkbox.vue';
|
|
import Input from '@/components/ui/Input.vue';
|
|
import PasswordInput from '@/components/ui/PasswordInput.vue';
|
|
import { useTranslations } from '@/composables/useVanguard';
|
|
import type { LoginDetailsFormData } from '@/types';
|
|
|
|
const props = defineProps<{
|
|
errors: Record<string, string>;
|
|
/** Editing an existing user, which makes the password fields optional. */
|
|
edit?: boolean;
|
|
/** The admin-only "force password change" toggle. */
|
|
showForcePasswordChange?: boolean;
|
|
submitLabel?: string;
|
|
processing?: boolean;
|
|
}>();
|
|
|
|
const form = defineModel<LoginDetailsFormData>({ required: true });
|
|
|
|
const { __ } = useTranslations();
|
|
|
|
/**
|
|
* Declared here rather than inline so the string handed to __() matches the
|
|
* language file key exactly, apostrophe included.
|
|
*/
|
|
const optionalHint = __("Leave field blank if you don't want to change it");
|
|
</script>
|
|
|
|
<template>
|
|
<div class="space-y-4">
|
|
<div>
|
|
<label for="email" class="mb-1 block text-slate-700">{{ __('Email') }}</label>
|
|
<Input
|
|
id="email"
|
|
v-model="form.email"
|
|
type="email"
|
|
class="w-full"
|
|
:placeholder="__('Email')"
|
|
:invalid="Boolean(errors.email)"
|
|
/>
|
|
<small v-if="errors.email" class="text-red-600">{{ errors.email }}</small>
|
|
</div>
|
|
|
|
<div>
|
|
<label for="username" class="mb-1 block text-slate-700">{{ __('Username') }}</label>
|
|
<Input
|
|
id="username"
|
|
v-model="form.username"
|
|
class="w-full"
|
|
:placeholder="`(${__('optional')})`"
|
|
:invalid="Boolean(errors.username)"
|
|
/>
|
|
<small v-if="errors.username" class="text-red-600">{{ errors.username }}</small>
|
|
</div>
|
|
|
|
<div>
|
|
<label for="password" class="mb-1 block text-slate-700">
|
|
{{ edit ? __('New Password') : __('Password') }}
|
|
</label>
|
|
<PasswordInput
|
|
id="password"
|
|
v-model="form.password"
|
|
class="w-full"
|
|
:placeholder="edit ? optionalHint : undefined"
|
|
:invalid="Boolean(errors.password)"
|
|
autocomplete="new-password"
|
|
/>
|
|
<small v-if="errors.password" class="text-red-600">{{ errors.password }}</small>
|
|
</div>
|
|
|
|
<div>
|
|
<label for="password_confirmation" class="mb-1 block text-slate-700">
|
|
{{ edit ? __('Confirm New Password') : __('Confirm Password') }}
|
|
</label>
|
|
<PasswordInput
|
|
id="password_confirmation"
|
|
v-model="form.password_confirmation"
|
|
class="w-full"
|
|
:placeholder="edit ? optionalHint : undefined"
|
|
:invalid="Boolean(errors.password_confirmation)"
|
|
autocomplete="new-password"
|
|
/>
|
|
<small v-if="errors.password_confirmation" class="text-red-600">
|
|
{{ errors.password_confirmation }}
|
|
</small>
|
|
</div>
|
|
|
|
<div v-if="showForcePasswordChange" class="flex items-center gap-2">
|
|
<Checkbox id="force_password_change" v-model="form.force_password_change" />
|
|
<label for="force_password_change" class="cursor-pointer text-slate-600">
|
|
{{ __('Force Password Change on next login') }}
|
|
</label>
|
|
</div>
|
|
|
|
<div v-if="submitLabel">
|
|
<Button type="submit" icon="fa fa-refresh" :label="submitLabel" :loading="processing" />
|
|
</div>
|
|
</div>
|
|
</template>
|