- Add local AxiosResponse/AxiosError interfaces to models.ts as workaround for bundler moduleResolution issues with axios types - Update 7 payment Vue files to import axios types from local models - Convert axios.get<T>() generic calls to typed .then() response callbacks - Fix type narrowing in getTypeColor(), getEmployeeTypeName() functions - Add Number() conversion for tank_size arithmetic in auto preauth - Use 'as unknown as' for Delivery to DeliveryFormData type assertions - Fix incorrect import paths for sidebar/footer in delivery/create.vue Production build (npm run build) now completes successfully. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
196 lines
6.7 KiB
Vue
196 lines
6.7 KiB
Vue
<!-- src/pages/employee/changepassword.vue -->
|
|
<template>
|
|
<div class="WrapperPlain">
|
|
<div class="container max-w-3xl mx-auto text-white">
|
|
|
|
<!-- Employee Info Section -->
|
|
<div class="mx-auto max-w-lg mb-6 px-5">
|
|
<div class="bg-neutral rounded-md px-8 pt-6 pb-6 mb-4 w-full">
|
|
<h2 class="text-xl font-bold mb-4">Employee Information</h2>
|
|
<div v-if="employee">
|
|
<p><strong>Name:</strong> {{ employee.employee_first_name }} {{ employee.employee_last_name }}</p>
|
|
<p><strong>ID:</strong> {{ employee.id }}</p>
|
|
<p><strong>Role:</strong> {{ getEmployeeTypeName(employee.employee_type) }}</p>
|
|
<p><strong>Town:</strong> {{ employee.employee_town }}</p>
|
|
<p><strong>Phone:</strong> {{ employee.employee_phone_number }}</p>
|
|
</div>
|
|
<div v-else>
|
|
<p>Loading employee data...</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mx-auto max-w-lg flex items-center justify-center mb-10 mt-20 px-5">
|
|
<form class="bg-neutral rounded-md px-8 pt-6 pb-8 mb-4 w-full" @submit.prevent="onSubmit">
|
|
<div class="mb-4 text-center text-[28px] ">
|
|
Change Password
|
|
</div>
|
|
<div class="mb-4">
|
|
<label class="block text-white text-sm font-bold mb-2">Enter New Password</label>
|
|
<input v-model="ChangePasswordForm.new_password" class="rounded w-full py-2 px-3 input-primary text-black"
|
|
id="password" type="password" placeholder="Password" />
|
|
<span v-if="v$.ChangePasswordForm.new_password.$error" class="text-red-600 text-center">
|
|
{{ v$.ChangePasswordForm.new_password.$errors[0].$message }}
|
|
</span>
|
|
</div>
|
|
<div class="mb-6">
|
|
<label class="block text-white text-sm font-bold mb-2">Confirm New Password</label>
|
|
<input v-model="ChangePasswordForm.password_confirm" class="rounded w-full py-2 px-3 input-primary text-black"
|
|
id="passwordtwo" type="password" autocomplete="off" placeholder="Confirm Password" />
|
|
<span v-if="v$.ChangePasswordForm.password_confirm.$error" class="text-red-600 text-center">
|
|
{{ v$.ChangePasswordForm.password_confirm.$errors[0].$message }}
|
|
</span>
|
|
</div>
|
|
<div class="flex items-center justify-center mb-6">
|
|
<button
|
|
class="bg-primary hover:bg-zinc-400 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline"
|
|
type="submit">
|
|
Update
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script lang="ts">
|
|
import { defineComponent } from "vue";
|
|
import axios from "axios";
|
|
import { notify } from "@kyvg/vue3-notification";
|
|
import useValidate from "@vuelidate/core";
|
|
import { required, minLength, helpers } from "@vuelidate/validators";
|
|
import Header from "../../layouts/headers/headerauth.vue";
|
|
import authHeader from "../../services/auth.header";
|
|
import {Employee} from '../../types/models';
|
|
|
|
export default defineComponent({
|
|
name: "EmployeeChangePassword",
|
|
components: {
|
|
Header,
|
|
},
|
|
data() {
|
|
return {
|
|
v$: useValidate(),
|
|
user: null,
|
|
user_admin: 0,
|
|
loaded: false,
|
|
employee: {} as Employee,
|
|
ChangePasswordForm: {
|
|
new_password: "",
|
|
password_confirm: "",
|
|
},
|
|
};
|
|
},
|
|
validations() {
|
|
return {
|
|
ChangePasswordForm: {
|
|
new_password: { required, minLength: minLength(6) },
|
|
password_confirm: { required, minLength: minLength(6), sameAsPassword: helpers.withMessage('Passwords must match', (value: string) => value === this.ChangePasswordForm.new_password) },
|
|
},
|
|
};
|
|
},
|
|
created() {
|
|
this.userStatus();
|
|
},
|
|
mounted() {
|
|
this.getEmployee();
|
|
},
|
|
methods: {
|
|
userStatus() {
|
|
let path = import.meta.env.VITE_BASE_URL + '/auth/whoami';
|
|
axios({
|
|
method: "get",
|
|
url: path,
|
|
withCredentials: true,
|
|
headers: authHeader(),
|
|
})
|
|
.then((response: any) => {
|
|
if (response.data.ok) {
|
|
this.user = response.data.user;
|
|
}
|
|
})
|
|
.catch(() => {
|
|
this.$router.push({ name: "login" });
|
|
});
|
|
},
|
|
getEmployee() {
|
|
const employeeId = this.$route.params.id;
|
|
const path = `${import.meta.env.VITE_BASE_URL}/employee/byid/${employeeId}`;
|
|
axios.get(path, { headers: authHeader() })
|
|
.then((response: any) => {
|
|
this.employee = response.data;
|
|
})
|
|
.catch((error: any) => {
|
|
console.error("Failed to fetch employee:", error);
|
|
notify({
|
|
title: "Error",
|
|
text: "Failed to load employee data",
|
|
type: "error",
|
|
});
|
|
});
|
|
},
|
|
getEmployeeTypeName(typeId: number | string | undefined): string {
|
|
if (typeId === undefined) return 'Unknown Role';
|
|
const typeMap: { [key: string]: string } = {
|
|
'0': 'Owner', '1': 'Manager', '2': 'Secretary', '3': 'Office',
|
|
'4': 'Driver', '5': 'Service Tech', '6': 'Contractor', '7': 'Cash Driver', '8': 'Driver/Tech'
|
|
};
|
|
return typeMap[String(typeId)] || 'Unknown Role';
|
|
},
|
|
sendWordRequest(payLoad: { employee_id: string; new_password: string; password_confirm: string }) {
|
|
let path = import.meta.env.VITE_BASE_URL + "/auth/admin-change-password";
|
|
axios({
|
|
method: "post",
|
|
url: path,
|
|
data: payLoad,
|
|
withCredentials: true,
|
|
headers: authHeader(),
|
|
}).then((response: any) => {
|
|
console.log(response)
|
|
if (response.data.ok) {
|
|
notify({
|
|
title: "Authorization",
|
|
text: "Password changed successfully",
|
|
type: "success",
|
|
});
|
|
this.$router.push({ name: "employee" });
|
|
}
|
|
if (response.data.error) {
|
|
notify({
|
|
title: "Authorization Error",
|
|
text: response.data.error,
|
|
type: "error",
|
|
});
|
|
}
|
|
})
|
|
.catch(() => {
|
|
notify({
|
|
title: "Authorization",
|
|
text: "Invalid Credentials.",
|
|
type: "error",
|
|
});
|
|
});
|
|
},
|
|
onSubmit() {
|
|
const payLoad = {
|
|
employee_id: this.$route.params.id as string,
|
|
new_password: this.ChangePasswordForm.new_password,
|
|
password_confirm: this.ChangePasswordForm.password_confirm,
|
|
};
|
|
|
|
this.v$.$validate(); // checks all inputs
|
|
if (this.v$.$invalid) {
|
|
notify({
|
|
title: "Authorization",
|
|
text: "Form Failure",
|
|
type: "error",
|
|
});
|
|
} else {
|
|
this.sendWordRequest(payLoad);
|
|
}
|
|
},
|
|
},
|
|
});
|
|
</script>
|