diff --git a/thanasoft-front/src/components/Organism/CRM/EmployeeDetailPresentation.vue b/thanasoft-front/src/components/Organism/CRM/EmployeeDetailPresentation.vue new file mode 100644 index 0000000..b6eb2a0 --- /dev/null +++ b/thanasoft-front/src/components/Organism/CRM/EmployeeDetailPresentation.vue @@ -0,0 +1,164 @@ + + + diff --git a/thanasoft-front/src/components/Organism/CRM/employee/EmployeeDetailContent.vue b/thanasoft-front/src/components/Organism/CRM/employee/EmployeeDetailContent.vue new file mode 100644 index 0000000..cf0fb5a --- /dev/null +++ b/thanasoft-front/src/components/Organism/CRM/employee/EmployeeDetailContent.vue @@ -0,0 +1,105 @@ + + + diff --git a/thanasoft-front/src/components/Organism/CRM/employee/EmployeeDetailSidebar.vue b/thanasoft-front/src/components/Organism/CRM/employee/EmployeeDetailSidebar.vue new file mode 100644 index 0000000..d97414f --- /dev/null +++ b/thanasoft-front/src/components/Organism/CRM/employee/EmployeeDetailSidebar.vue @@ -0,0 +1,85 @@ + + + + + diff --git a/thanasoft-front/src/components/Organism/Employee/EmployeePresentation.vue b/thanasoft-front/src/components/Organism/Employee/EmployeePresentation.vue index b1c50eb..3a3e628 100644 --- a/thanasoft-front/src/components/Organism/Employee/EmployeePresentation.vue +++ b/thanasoft-front/src/components/Organism/Employee/EmployeePresentation.vue @@ -13,62 +13,11 @@ - -
- - - -
- - Affichage de {{ pagination.from }} à {{ pagination.to }} sur - {{ pagination.total }} employés - -
-
@@ -78,13 +27,12 @@ import EmployeeTable from "@/components/molecules/Employees/EmployeeTable.vue"; import addButton from "@/components/molecules/new-button/addButton.vue"; import FilterTable from "@/components/molecules/Tables/FilterTable.vue"; import TableAction from "@/components/molecules/Tables/TableAction.vue"; -import { computed } from "vue"; import { defineProps, defineEmits } from "vue"; import { useRouter } from "vue-router"; const router = useRouter(); -const emit = defineEmits(["pushDetails", "deleteEmployee"]); +const emit = defineEmits(["pushDetails", "deleteEmployee", "changePage"]); const props = defineProps({ employeeData: { @@ -112,117 +60,25 @@ const goToDetails = (employeeId) => { }; const deleteEmployee = (employeeId) => { + console.log( + "deleteEmployee called in EmployeePresentation with ID:", + employeeId + ); emit("deleteEmployee", employeeId); }; -// Computed property for visible page numbers -const visiblePages = computed(() => { - if (!props.pagination) return []; - - const current = props.pagination.current_page; - const last = props.pagination.last_page; - const delta = 2; // Number of pages to show on each side of current page - - const range = []; - const rangeWithDots = []; - - // Calculate range around current page - for ( - let i = Math.max(2, current - delta); - i <= Math.min(last - 1, current + delta); - i++ - ) { - range.push(i); - } - - // Add first page - if (current - delta > 2) { - rangeWithDots.push(1, "..."); - } else { - rangeWithDots.push(1); - } - - // Add calculated range - rangeWithDots.push(...range); - - // Add last page - if (current + delta < last - 1) { - rangeWithDots.push("...", last); - } else if (last > 1) { - rangeWithDots.push(last); - } - - return rangeWithDots; -}); - -const changePage = (page) => { - if (page >= 1 && page <= props.pagination.last_page) { - // Emit event for parent component to handle page change +const handleChangePage = (page) => { + console.log( + "handleChangePage called in EmployeePresentation with page:", + page + ); + if (page >= 1 && page <= (props.pagination?.last_page || 1)) { + console.log("Emitting changePage event from EmployeePresentation:", page); emit("changePage", page); } }; diff --git a/thanasoft-front/src/components/Organism/Thanatopractitioner/AddThanatopractitionerPresentation.vue b/thanasoft-front/src/components/Organism/Thanatopractitioner/AddThanatopractitionerPresentation.vue new file mode 100644 index 0000000..c169c3f --- /dev/null +++ b/thanasoft-front/src/components/Organism/Thanatopractitioner/AddThanatopractitionerPresentation.vue @@ -0,0 +1,501 @@ + + + + + diff --git a/thanasoft-front/src/components/Organism/Thanatopractitioner/ThanatopractitionerPresentation.vue b/thanasoft-front/src/components/Organism/Thanatopractitioner/ThanatopractitionerPresentation.vue new file mode 100644 index 0000000..a3de91f --- /dev/null +++ b/thanasoft-front/src/components/Organism/Thanatopractitioner/ThanatopractitionerPresentation.vue @@ -0,0 +1,92 @@ + + + + + diff --git a/thanasoft-front/src/components/molecules/Employees/EmployeeTable.vue b/thanasoft-front/src/components/molecules/Employees/EmployeeTable.vue index 5a56c33..aca98aa 100644 --- a/thanasoft-front/src/components/molecules/Employees/EmployeeTable.vue +++ b/thanasoft-front/src/components/molecules/Employees/EmployeeTable.vue @@ -78,133 +78,192 @@ -
- - - - - - - - - - - - - - - - - +
+
+
IDNom & PrénomEmailTéléphonePosteDate d'embaucheStatusAction
-
- -

- {{ employee.id }} -

-
-
+ + + + + + + + + + + + + + + + - - + - - + + - - + + - - + + - - + + - - + + - - - -
IDNom & PrénomEmailTéléphonePosteDate d'embaucheStatusAction
+
+ +

+ {{ employee.id }} +

+
+
-
- -
- {{ employee.last_name }} {{ employee.first_name }} -
- Thanatopractitioner + +
+
+ +
+ {{ employee.last_name }} {{ employee.first_name }} +
+ Thanatopractitioner +
- -
- {{ employee.email || "N/A" }} - + {{ employee.email || "N/A" }} + - {{ employee.phone || "N/A" }} - + {{ employee.phone || "N/A" }} + -
- - - - {{ employee.job_title || "N/A" }} -
-
+
+ + + + {{ employee.job_title || "N/A" }} +
+
- {{ formatDate(employee.hire_date) }} - + {{ + formatDate(employee.hire_date) + }} + -
- - - - {{ employee.active ? "Actif" : "Inactif" }} -
-
+
+ + + + {{ employee.active ? "Actif" : "Inactif" }} +
+
-
- - - - +
+
+ + + + - - - - -
-
+ + + + +
+ + + + + + + +
+
+ Affichage de {{ pagination.from }} à {{ pagination.to }} sur + {{ pagination.total }} employés +
+
+ + + + Précédent + + + +
+ + {{ page }} + +
+ + + + Suivant + + +
+
@@ -222,13 +281,13 @@ diff --git a/thanasoft-front/src/components/molecules/Thanatopractitioners/ThanatopractitionerTable.vue b/thanasoft-front/src/components/molecules/Thanatopractitioners/ThanatopractitionerTable.vue new file mode 100644 index 0000000..e63cfc6 --- /dev/null +++ b/thanasoft-front/src/components/molecules/Thanatopractitioners/ThanatopractitionerTable.vue @@ -0,0 +1,632 @@ + + + + + diff --git a/thanasoft-front/src/components/molecules/common/ConfirmModal.vue b/thanasoft-front/src/components/molecules/common/ConfirmModal.vue new file mode 100644 index 0000000..5e7bd4e --- /dev/null +++ b/thanasoft-front/src/components/molecules/common/ConfirmModal.vue @@ -0,0 +1,431 @@ + + + + + diff --git a/thanasoft-front/src/components/molecules/employee/EmployeeActivityTab.vue b/thanasoft-front/src/components/molecules/employee/EmployeeActivityTab.vue new file mode 100644 index 0000000..9698e25 --- /dev/null +++ b/thanasoft-front/src/components/molecules/employee/EmployeeActivityTab.vue @@ -0,0 +1,363 @@ + + + + + diff --git a/thanasoft-front/src/components/molecules/employee/EmployeeDocumentsTab.vue b/thanasoft-front/src/components/molecules/employee/EmployeeDocumentsTab.vue new file mode 100644 index 0000000..fac36db --- /dev/null +++ b/thanasoft-front/src/components/molecules/employee/EmployeeDocumentsTab.vue @@ -0,0 +1,456 @@ + + + + + diff --git a/thanasoft-front/src/components/molecules/employee/EmployeeInfoTab.vue b/thanasoft-front/src/components/molecules/employee/EmployeeInfoTab.vue new file mode 100644 index 0000000..9923b00 --- /dev/null +++ b/thanasoft-front/src/components/molecules/employee/EmployeeInfoTab.vue @@ -0,0 +1,332 @@ + + + + + diff --git a/thanasoft-front/src/components/molecules/employee/EmployeeOverview.vue b/thanasoft-front/src/components/molecules/employee/EmployeeOverview.vue new file mode 100644 index 0000000..37e11bc --- /dev/null +++ b/thanasoft-front/src/components/molecules/employee/EmployeeOverview.vue @@ -0,0 +1,346 @@ + + + + + diff --git a/thanasoft-front/src/components/molecules/employee/EmployeePractitionerTab.vue b/thanasoft-front/src/components/molecules/employee/EmployeePractitionerTab.vue new file mode 100644 index 0000000..5964d98 --- /dev/null +++ b/thanasoft-front/src/components/molecules/employee/EmployeePractitionerTab.vue @@ -0,0 +1,420 @@ + + + + + diff --git a/thanasoft-front/src/components/molecules/employee/EmployeeProfileCard.vue b/thanasoft-front/src/components/molecules/employee/EmployeeProfileCard.vue new file mode 100644 index 0000000..d91f532 --- /dev/null +++ b/thanasoft-front/src/components/molecules/employee/EmployeeProfileCard.vue @@ -0,0 +1,140 @@ + + + + + diff --git a/thanasoft-front/src/components/molecules/employee/EmployeeTabNavigation.vue b/thanasoft-front/src/components/molecules/employee/EmployeeTabNavigation.vue new file mode 100644 index 0000000..af5bad3 --- /dev/null +++ b/thanasoft-front/src/components/molecules/employee/EmployeeTabNavigation.vue @@ -0,0 +1,54 @@ + + + diff --git a/thanasoft-front/src/components/templates/CRM/EmployeeDetailTemplate.vue b/thanasoft-front/src/components/templates/CRM/EmployeeDetailTemplate.vue new file mode 100644 index 0000000..f51d18a --- /dev/null +++ b/thanasoft-front/src/components/templates/CRM/EmployeeDetailTemplate.vue @@ -0,0 +1,21 @@ + + + diff --git a/thanasoft-front/src/components/templates/CRM/ThanatopractitionerTemplate.vue b/thanasoft-front/src/components/templates/CRM/ThanatopractitionerTemplate.vue new file mode 100644 index 0000000..f6c0a28 --- /dev/null +++ b/thanasoft-front/src/components/templates/CRM/ThanatopractitionerTemplate.vue @@ -0,0 +1,24 @@ + + + diff --git a/thanasoft-front/src/examples/ConfirmModalUsage.vue b/thanasoft-front/src/examples/ConfirmModalUsage.vue new file mode 100644 index 0000000..48aa50c --- /dev/null +++ b/thanasoft-front/src/examples/ConfirmModalUsage.vue @@ -0,0 +1,271 @@ + + + + + diff --git a/thanasoft-front/src/examples/Sidenav/SidenavList.vue b/thanasoft-front/src/examples/Sidenav/SidenavList.vue index 7539f90..5c99d18 100644 --- a/thanasoft-front/src/examples/Sidenav/SidenavList.vue +++ b/thanasoft-front/src/examples/Sidenav/SidenavList.vue @@ -308,7 +308,7 @@ export default { }, { id: "employes-thanatopracteurs", - route: { name: "Employés Thanatopracteurs" }, + route: { name: "Gestion thanatopractitioners" }, miniIcon: "T", text: "Employés & Thanatopracteurs", }, diff --git a/thanasoft-front/src/router/index.js b/thanasoft-front/src/router/index.js index a72549f..4d016b4 100644 --- a/thanasoft-front/src/router/index.js +++ b/thanasoft-front/src/router/index.js @@ -529,6 +529,11 @@ const routes = [ name: "Creation employé", component: () => import("@/views/pages/CRM/AddEmployee.vue"), }, + { + path: "/employes/:id", + name: "Employee details", + component: () => import("@/views/pages/CRM/EmployeeDetails.vue"), + }, { path: "/employes/ndf", name: "NDF", @@ -546,10 +551,24 @@ const routes = [ }, { path: "/employes/thanatopracteurs", - name: "Employés Thanatopracteurs", + name: "Gestion thanatopractitioners", component: () => - import("@/views/pages/Employes/EmployesThanatopracteurs.vue"), + import("@/views/pages/Thanatopractitioners/Thanatopractitioners.vue"), }, + { + path: "/employes/thanatopracteurs/new", + name: "Creation thanatopractitioner", + component: () => + import("@/views/pages/Thanatopractitioners/AddThanatopractitioner.vue"), + }, + // { + // path: "/employes/thanatopracteurs/:id", + // name: "Thanatopractitioner details", + // component: () => + // import( + // "@/views/pages/Thanatopractitioners/ThanatopractitionerDetails.vue" + // ), + // }, // Paramétrage { path: "/parametrage/droits", diff --git a/thanasoft-front/src/services/thanatopractitioner.ts b/thanasoft-front/src/services/thanatopractitioner.ts new file mode 100644 index 0000000..244e3e1 --- /dev/null +++ b/thanasoft-front/src/services/thanatopractitioner.ts @@ -0,0 +1,286 @@ +import { request } from "./http"; + +export interface Thanatopractitioner { + id: number; + employee_id: number; + diploma_number: string; + diploma_date: string; + authorization_number: string; + authorization_issue_date: string; + authorization_expiry_date: string; + notes: string | null; + active: boolean; + created_at: string; + updated_at: string; + // Relations + employee?: { + id: number; + first_name: string; + last_name: string; + full_name: string; + email: string | null; + phone: string | null; + job_title: string | null; + active: boolean; + } | null; +} + +export interface ThanatopractitionerListResponse { + data: Thanatopractitioner[]; + pagination: { + current_page: number; + per_page: number; + total: number; + last_page: number; + from: number; + to: number; + }; + message: string; +} + +// For nested response structure +export interface NestedThanatopractitionerListResponse { + data: { + data: Thanatopractitioner[]; + pagination: { + current_page: number; + per_page: number; + total: number; + last_page: number; + from: number; + to: number; + }; + message: string; + }; +} + +export interface ThanatopractitionerResponse { + data: Thanatopractitioner; + message: string; +} + +export interface CreateThanatopractitionerPayload { + employee_id: number; + diploma_number: string; + diploma_date: string; + authorization_number: string; + authorization_issue_date: string; + authorization_expiry_date: string; + notes?: string | null; + active?: boolean; +} + +export interface UpdateThanatopractitionerPayload + extends Partial { + id: number; +} + +export const ThanatopractitionerService = { + /** + * Get all thanatopractitioners with pagination and filtering + */ + async getAllThanatopractitioners(params?: { + page?: number; + per_page?: number; + search?: string; + active?: boolean; + sort_by?: string; + sort_direction?: string; + }): Promise { + const response = await request({ + url: "/api/thanatopractitioners", + method: "get", + params, + }); + + return response; + }, + + /** + * Get a specific thanatopractitioner by ID + */ + async getThanatopractitioner( + id: number + ): Promise { + const response = await request({ + url: `/api/thanatopractitioners/${id}`, + method: "get", + }); + + return response; + }, + + /** + * Create a new thanatopractitioner + */ + async createThanatopractitioner( + payload: CreateThanatopractitionerPayload + ): Promise { + const formattedPayload = this.transformThanatopractitionerPayload(payload); + + const response = await request({ + url: "/api/thanatopractitioners", + method: "post", + data: formattedPayload, + }); + + return response; + }, + + /** + * Update an existing thanatopractitioner + */ + async updateThanatopractitioner( + payload: UpdateThanatopractitionerPayload + ): Promise { + const { id, ...updateData } = payload; + const formattedPayload = this.transformThanatopractitionerPayload( + updateData + ); + + const response = await request({ + url: `/api/thanatopractitioners/${id}`, + method: "put", + data: formattedPayload, + }); + + return response; + }, + + /** + * Delete a thanatopractitioner + */ + async deleteThanatopractitioner( + id: number + ): Promise<{ success: boolean; message: string }> { + const response = await request<{ success: boolean; message: string }>({ + url: `/api/thanatopractitioners/${id}`, + method: "delete", + }); + + return response; + }, + + /** + * Get active thanatopractitioners only + */ + async getActiveThanatopractitioners(params?: { + page?: number; + per_page?: number; + }): Promise { + const response = await request({ + url: "/api/thanatopractitioners", + method: "get", + params: { + active: true, + ...params, + }, + }); + + return response; + }, + + /** + * Get thanatopractitioner statistics + */ + async getStatistics(): Promise<{ + data: { + total_thanatopractitioners: number; + active_thanatopractitioners: number; + inactive_thanatopractitioners: number; + authorizations_expiring_soon: number; + }; + }> { + const response = await request<{ + data: { + total_thanatopractitioners: number; + active_thanatopractitioners: number; + inactive_thanatopractitioners: number; + authorizations_expiring_soon: number; + }; + }>({ + url: "/api/thanatopractitioners/statistics", + method: "get", + }); + + return response; + }, + + /** + * Transform thanatopractitioner payload to match Laravel form request structure + */ + transformThanatopractitionerPayload( + payload: Partial + ): any { + const transformed: any = { ...payload }; + + // Ensure boolean values are properly formatted + if (typeof transformed.active === "boolean") { + transformed.active = transformed.active ? 1 : 0; + } + + // Validate and format dates + const dateFields = [ + "diploma_date", + "authorization_issue_date", + "authorization_expiry_date", + ]; + dateFields.forEach((field) => { + if (transformed[field]) { + const date = new Date(transformed[field]); + if (!isNaN(date.getTime())) { + transformed[field] = date.toISOString().split("T")[0]; + } + } + }); + + // Remove undefined values to avoid sending them + Object.keys(transformed).forEach((key) => { + if (transformed[key] === undefined) { + delete transformed[key]; + } + }); + + return transformed; + }, + + /** + * Search thanatopractitioners by name, email, or other criteria + */ + async searchThanatopractitioners( + query: string + ): Promise { + const response = await request<{ + data: { + data: Thanatopractitioner[]; + }; + }>({ + url: "/api/thanatopractitioners", + method: "get", + params: { + search: query, + }, + }); + return response.data.data; + }, + + /** + * Toggle thanatopractitioner active status + */ + async toggleThanatopractitionerStatus( + id: number, + isActive: boolean + ): Promise { + const response = await request({ + url: `/api/thanatopractitioners/${id}`, + method: "put", + data: { + active: isActive, + }, + }); + + return response; + }, +}; + +export default ThanatopractitionerService; diff --git a/thanasoft-front/src/stores/employeeStore.ts b/thanasoft-front/src/stores/employeeStore.ts index 44280f3..21314c4 100644 --- a/thanasoft-front/src/stores/employeeStore.ts +++ b/thanasoft-front/src/stores/employeeStore.ts @@ -79,6 +79,16 @@ export const useEmployeeStore = defineStore("employee", () => { from: meta.from || 0, to: meta.to || 0, }; + } else { + // Reset pagination if no meta provided + pagination.value = { + current_page: 1, + last_page: 1, + per_page: 10, + total: 0, + from: 0, + to: 0, + }; } }; diff --git a/thanasoft-front/src/stores/thanatopractitionerStore.ts b/thanasoft-front/src/stores/thanatopractitionerStore.ts new file mode 100644 index 0000000..bdc66c7 --- /dev/null +++ b/thanasoft-front/src/stores/thanatopractitionerStore.ts @@ -0,0 +1,421 @@ +import { defineStore } from "pinia"; +import { ref, computed } from "vue"; +import ThanatopractitionerService from "@/services/thanatopractitioner"; + +import type { + Thanatopractitioner, + CreateThanatopractitionerPayload, + UpdateThanatopractitionerPayload, + ThanatopractitionerListResponse, + NestedThanatopractitionerListResponse, +} from "@/services/thanatopractitioner"; + +export const useThanatopractitionerStore = defineStore( + "thanatopractitioner", + () => { + // State + const thanatopractitioners = ref([]); + const currentThanatopractitioner = ref(null); + const loading = ref(false); + const error = ref(null); + const searchResults = ref([]); + + // Pagination state + const pagination = ref({ + current_page: 1, + last_page: 1, + per_page: 10, + total: 0, + from: 0, + to: 0, + }); + + // Getters + const allThanatopractitioners = computed(() => thanatopractitioners.value); + const activeThanatopractitioners = computed(() => + thanatopractitioners.value.filter( + (thanatopractitioner: Thanatopractitioner) => thanatopractitioner.active + ) + ); + const inactiveThanatopractitioners = computed(() => + thanatopractitioners.value.filter( + (thanatopractitioner: Thanatopractitioner) => + !thanatopractitioner.active + ) + ); + const isLoading = computed(() => loading.value); + const hasError = computed(() => error.value !== null); + const getError = computed(() => error.value); + const getThanatopractitionerById = computed(() => (id: number) => + thanatopractitioners.value.find( + (thanatopractitioner: Thanatopractitioner) => + thanatopractitioner.id === id + ) + ); + const getPagination = computed(() => pagination.value); + + // Actions + const setLoading = (isLoading: boolean) => { + loading.value = isLoading; + }; + + const setError = (err: string | null) => { + error.value = err; + }; + + const clearError = () => { + error.value = null; + }; + + const setThanatopractitioners = ( + newThanatopractitioners: Thanatopractitioner[] + ) => { + thanatopractitioners.value = newThanatopractitioners; + }; + + const setCurrentThanatopractitioner = ( + thanatopractitioner: Thanatopractitioner | null + ) => { + currentThanatopractitioner.value = thanatopractitioner; + }; + + const setSearchThanatopractitioner = ( + searchThanatopractitioner: Thanatopractitioner[] + ) => { + searchResults.value = searchThanatopractitioner; + }; + + const setPagination = (meta: any) => { + if (meta) { + pagination.value = { + current_page: meta.current_page || 1, + last_page: meta.last_page || 1, + per_page: meta.per_page || 10, + total: meta.total || 0, + from: meta.from || 0, + to: meta.to || 0, + }; + } + }; + + /** + * Fetch all thanatopractitioners with optional pagination and filters + */ + const fetchThanatopractitioners = async (params?: { + page?: number; + per_page?: number; + search?: string; + active?: boolean; + sort_by?: string; + sort_direction?: string; + }) => { + setLoading(true); + setError(null); + + try { + const response = await ThanatopractitionerService.getAllThanatopractitioners( + params + ); + setThanatopractitioners(response.data.data); + setPagination(response.data.pagination); + return response; + } catch (err: any) { + const errorMessage = + err.response?.data?.message || + err.message || + "Failed to fetch thanatopractitioners"; + setError(errorMessage); + throw err; + } finally { + setLoading(false); + } + }; + + /** + * Fetch a single thanatopractitioner by ID + */ + const fetchThanatopractitioner = async (id: number) => { + setLoading(true); + setError(null); + + try { + const response = await ThanatopractitionerService.getThanatopractitioner( + id + ); + setCurrentThanatopractitioner(response.data); + return response.data; + } catch (err: any) { + const errorMessage = + err.response?.data?.message || + err.message || + "Failed to fetch thanatopractitioner"; + setError(errorMessage); + throw err; + } finally { + setLoading(false); + } + }; + + /** + * Create a new thanatopractitioner + */ + const createThanatopractitioner = async ( + payload: CreateThanatopractitionerPayload + ) => { + setLoading(true); + setError(null); + + try { + const response = await ThanatopractitionerService.createThanatopractitioner( + payload + ); + // Add the new thanatopractitioner to the list + thanatopractitioners.value.push(response.data); + setCurrentThanatopractitioner(response.data); + return response.data; + } catch (err: any) { + const errorMessage = + err.response?.data?.message || + err.message || + "Failed to create thanatopractitioner"; + setError(errorMessage); + throw err; + } finally { + setLoading(false); + } + }; + + /** + * Update an existing thanatopractitioner + */ + const updateThanatopractitioner = async ( + payload: UpdateThanatopractitionerPayload + ) => { + setLoading(true); + setError(null); + + try { + console.log(payload); + const response = await ThanatopractitionerService.updateThanatopractitioner( + payload + ); + const updatedThanatopractitioner = response.data; + + // Update in the thanatopractitioners list + const index = thanatopractitioners.value.findIndex( + (thanatopractitioner: Thanatopractitioner) => + thanatopractitioner.id === updatedThanatopractitioner.id + ); + if (index !== -1) { + thanatopractitioners.value[index] = updatedThanatopractitioner; + } + + // Update current thanatopractitioner if it's the one being edited + if ( + currentThanatopractitioner.value && + currentThanatopractitioner.value.id === updatedThanatopractitioner.id + ) { + setCurrentThanatopractitioner(updatedThanatopractitioner); + } + + return updatedThanatopractitioner; + } catch (err: any) { + const errorMessage = + err.response?.data?.message || + err.message || + "Failed to update thanatopractitioner"; + setError(errorMessage); + throw err; + } finally { + setLoading(false); + } + }; + + /** + * Delete a thanatopractitioner + */ + const deleteThanatopractitioner = async (id: number) => { + setLoading(true); + setError(null); + + try { + const response = await ThanatopractitionerService.deleteThanatopractitioner( + id + ); + + // Remove from the thanatopractitioners list + thanatopractitioners.value = thanatopractitioners.value.filter( + (thanatopractitioner: Thanatopractitioner) => + thanatopractitioner.id !== id + ); + + // Clear current thanatopractitioner if it's the one being deleted + if ( + currentThanatopractitioner.value && + currentThanatopractitioner.value.id === id + ) { + setCurrentThanatopractitioner(null); + } + + return response; + } catch (err: any) { + const errorMessage = + err.response?.data?.message || + err.message || + "Failed to delete thanatopractitioner"; + setError(errorMessage); + throw err; + } finally { + setLoading(false); + } + }; + + /** + * Search thanatopractitioners + */ + const searchThanatopractitioners = async (query: string) => { + setLoading(true); + error.value = null; + + try { + const results = await ThanatopractitionerService.searchThanatopractitioners( + query + ); + setSearchThanatopractitioner(results); + return results; + } catch (err) { + error.value = "Erreur lors de la recherche des thanatopractitioners"; + console.error("Error searching thanatopractitioners:", err); + setSearchThanatopractitioner([]); + throw err; + } finally { + setLoading(false); + } + }; + + /** + * Toggle thanatopractitioner active status + */ + const toggleThanatopractitionerStatus = async ( + id: number, + isActive: boolean + ) => { + setLoading(true); + setError(null); + + try { + const response = await ThanatopractitionerService.toggleThanatopractitionerStatus( + id, + isActive + ); + const updatedThanatopractitioner = response.data; + + // Update in the thanatopractitioners list + const index = thanatopractitioners.value.findIndex( + (thanatopractitioner: Thanatopractitioner) => + thanatopractitioner.id === id + ); + if (index !== -1) { + thanatopractitioners.value[index] = updatedThanatopractitioner; + } + + // Update current thanatopractitioner if it's the one being toggled + if ( + currentThanatopractitioner.value && + currentThanatopractitioner.value.id === id + ) { + setCurrentThanatopractitioner(updatedThanatopractitioner); + } + + return updatedThanatopractitioner; + } catch (err: any) { + const errorMessage = + err.response?.data?.message || + err.message || + "Failed to toggle thanatopractitioner status"; + setError(errorMessage); + throw err; + } finally { + setLoading(false); + } + }; + + /** + * Get thanatopractitioner statistics + */ + const fetchStatistics = async () => { + setLoading(true); + setError(null); + + try { + const response = await ThanatopractitionerService.getStatistics(); + return response.data; + } catch (err: any) { + const errorMessage = + err.response?.data?.message || + err.message || + "Failed to fetch statistics"; + setError(errorMessage); + throw err; + } finally { + setLoading(false); + } + }; + + /** + * Clear current thanatopractitioner + */ + const clearCurrentThanatopractitioner = () => { + setCurrentThanatopractitioner(null); + }; + + /** + * Clear all state + */ + const clearStore = () => { + thanatopractitioners.value = []; + currentThanatopractitioner.value = null; + error.value = null; + pagination.value = { + current_page: 1, + last_page: 1, + per_page: 10, + total: 0, + from: 0, + to: 0, + }; + }; + + return { + // State + thanatopractitioners, + currentThanatopractitioner, + loading, + error, + searchResults, + + // Getters + allThanatopractitioners, + activeThanatopractitioners, + inactiveThanatopractitioners, + isLoading, + hasError, + getError, + getThanatopractitionerById, + getPagination, + + // Actions + fetchThanatopractitioners, + fetchThanatopractitioner, + createThanatopractitioner, + updateThanatopractitioner, + deleteThanatopractitioner, + searchThanatopractitioners, + toggleThanatopractitionerStatus, + fetchStatistics, + clearCurrentThanatopractitioner, + clearStore, + clearError, + }; + } +); diff --git a/thanasoft-front/src/views/pages/CRM/EmployeeDetails.vue b/thanasoft-front/src/views/pages/CRM/EmployeeDetails.vue new file mode 100644 index 0000000..87be382 --- /dev/null +++ b/thanasoft-front/src/views/pages/CRM/EmployeeDetails.vue @@ -0,0 +1,107 @@ + + + diff --git a/thanasoft-front/src/views/pages/Employes/Employees.vue b/thanasoft-front/src/views/pages/Employes/Employees.vue index 250d38d..5c37ad8 100644 --- a/thanasoft-front/src/views/pages/Employes/Employees.vue +++ b/thanasoft-front/src/views/pages/Employes/Employees.vue @@ -2,21 +2,55 @@ + + + diff --git a/thanasoft-front/src/views/pages/Thanatopractitioners/AddThanatopractitioner.vue b/thanasoft-front/src/views/pages/Thanatopractitioners/AddThanatopractitioner.vue new file mode 100644 index 0000000..ee7781c --- /dev/null +++ b/thanasoft-front/src/views/pages/Thanatopractitioners/AddThanatopractitioner.vue @@ -0,0 +1,70 @@ + + + diff --git a/thanasoft-front/src/views/pages/Thanatopractitioners/Thanatopractitioners.vue b/thanasoft-front/src/views/pages/Thanatopractitioners/Thanatopractitioners.vue new file mode 100644 index 0000000..a593e69 --- /dev/null +++ b/thanasoft-front/src/views/pages/Thanatopractitioners/Thanatopractitioners.vue @@ -0,0 +1,174 @@ + + +