diff --git a/thanasoft-back/app/Http/Controllers/Api/DeceasedDocumentController.php b/thanasoft-back/app/Http/Controllers/Api/DeceasedDocumentController.php new file mode 100644 index 0000000..d281e10 --- /dev/null +++ b/thanasoft-back/app/Http/Controllers/Api/DeceasedDocumentController.php @@ -0,0 +1,283 @@ +get('per_page', 15); + $filters = [ + 'search' => $request->get('search'), + 'deceased_id' => $request->get('deceased_id'), + 'doc_type' => $request->get('doc_type'), + 'file_id' => $request->get('file_id'), + 'sort_by' => $request->get('sort_by', 'created_at'), + 'sort_direction' => $request->get('sort_direction', 'desc'), + ]; + + // Remove null filters + $filters = array_filter($filters, function ($value) { + return $value !== null && $value !== ''; + }); + + $documents = $this->deceasedDocumentRepository->paginate($perPage, $filters); + + return new DeceasedDocumentCollection($documents); + + } catch (\Exception $e) { + Log::error('Erreur lors de la récupération des documents du défunt: ' . $e->getMessage(), [ + 'exception' => $e, + 'trace' => $e->getTraceAsString(), + ]); + + return response()->json([ + 'message' => 'Une erreur est survenue lors de la récupération des documents du défunt.', + 'error' => config('app.debug') ? $e->getMessage() : null, + ], 500); + } + } + + /** + * Get documents by deceased ID. + */ + public function byDeceased(string $deceasedId): DeceasedDocumentCollection|JsonResponse + { + try { + $documents = $this->deceasedDocumentRepository->getByDeceasedId((int) $deceasedId); + return new DeceasedDocumentCollection($documents); + } catch (\Exception $e) { + Log::error('Erreur lors de la récupération des documents par défunt: ' . $e->getMessage(), [ + 'exception' => $e, + 'trace' => $e->getTraceAsString(), + 'deceased_id' => $deceasedId, + ]); + + return response()->json([ + 'message' => 'Une erreur est survenue lors de la récupération des documents du défunt.', + 'error' => config('app.debug') ? $e->getMessage() : null, + ], 500); + } + } + + /** + * Get documents by document type. + */ + public function byDocType(Request $request): DeceasedDocumentCollection|JsonResponse + { + try { + $docType = $request->get('doc_type'); + + if (!$docType) { + return response()->json([ + 'message' => 'Le paramètre doc_type est requis.', + ], 400); + } + + $documents = $this->deceasedDocumentRepository->getByDocType($docType); + return new DeceasedDocumentCollection($documents); + } catch (\Exception $e) { + Log::error('Erreur lors de la récupération des documents par type: ' . $e->getMessage(), [ + 'exception' => $e, + 'trace' => $e->getTraceAsString(), + 'doc_type' => $request->get('doc_type'), + ]); + + return response()->json([ + 'message' => 'Une erreur est survenue lors de la récupération des documents par type.', + 'error' => config('app.debug') ? $e->getMessage() : null, + ], 500); + } + } + + /** + * Get documents by file ID. + */ + public function byFile(string $fileId): DeceasedDocumentCollection|JsonResponse + { + try { + $documents = $this->deceasedDocumentRepository->getByFileId((int) $fileId); + return new DeceasedDocumentCollection($documents); + } catch (\Exception $e) { + Log::error('Erreur lors de la récupération des documents par fichier: ' . $e->getMessage(), [ + 'exception' => $e, + 'trace' => $e->getTraceAsString(), + 'file_id' => $fileId, + ]); + + return response()->json([ + 'message' => 'Une erreur est survenue lors de la récupération des documents par fichier.', + 'error' => config('app.debug') ? $e->getMessage() : null, + ], 500); + } + } + + /** + * Search documents by various criteria. + */ + public function search(Request $request): DeceasedDocumentCollection|JsonResponse + { + try { + $criteria = [ + 'deceased_id' => $request->get('deceased_id'), + 'doc_type' => $request->get('doc_type'), + 'file_id' => $request->get('file_id'), + 'generated_from' => $request->get('generated_from'), + 'generated_to' => $request->get('generated_to'), + ]; + + // Remove null criteria + $criteria = array_filter($criteria, function ($value) { + return $value !== null && $value !== ''; + }); + + $documents = $this->deceasedDocumentRepository->search($criteria); + return new DeceasedDocumentCollection($documents); + } catch (\Exception $e) { + Log::error('Erreur lors de la recherche de documents: ' . $e->getMessage(), [ + 'exception' => $e, + 'trace' => $e->getTraceAsString(), + 'criteria' => $request->all(), + ]); + + return response()->json([ + 'message' => 'Une erreur est survenue lors de la recherche de documents.', + 'error' => config('app.debug') ? $e->getMessage() : null, + ], 500); + } + } + + /** + * Store a newly created deceased document. + */ + public function store(StoreDeceasedDocumentRequest $request): DeceasedDocumentResource|JsonResponse + { + try { + $document = $this->deceasedDocumentRepository->create($request->validated()); + return new DeceasedDocumentResource($document); + } catch (\Exception $e) { + Log::error('Erreur lors de la création du document du défunt: ' . $e->getMessage(), [ + 'exception' => $e, + 'trace' => $e->getTraceAsString(), + 'data' => $request->validated(), + ]); + + return response()->json([ + 'message' => 'Une erreur est survenue lors de la création du document du défunt.', + 'error' => config('app.debug') ? $e->getMessage() : null, + ], 500); + } + } + + /** + * Display the specified deceased document. + */ + public function show(string $id): DeceasedDocumentResource|JsonResponse + { + try { + $document = $this->deceasedDocumentRepository->find($id); + + if (!$document) { + return response()->json([ + 'message' => 'Document du défunt non trouvé.', + ], 404); + } + + return new DeceasedDocumentResource($document); + } catch (\Exception $e) { + Log::error('Erreur lors de la récupération du document du défunt: ' . $e->getMessage(), [ + 'exception' => $e, + 'trace' => $e->getTraceAsString(), + 'document_id' => $id, + ]); + + return response()->json([ + 'message' => 'Une erreur est survenue lors de la récupération du document du défunt.', + 'error' => config('app.debug') ? $e->getMessage() : null, + ], 500); + } + } + + /** + * Update the specified deceased document. + */ + public function update(UpdateDeceasedDocumentRequest $request, string $id): DeceasedDocumentResource|JsonResponse + { + try { + $updated = $this->deceasedDocumentRepository->update($id, $request->validated()); + + if (!$updated) { + return response()->json([ + 'message' => 'Document du défunt non trouvé ou échec de la mise à jour.', + ], 404); + } + + $document = $this->deceasedDocumentRepository->find($id); + return new DeceasedDocumentResource($document); + } catch (\Exception $e) { + Log::error('Erreur lors de la mise à jour du document du défunt: ' . $e->getMessage(), [ + 'exception' => $e, + 'trace' => $e->getTraceAsString(), + 'document_id' => $id, + 'data' => $request->validated(), + ]); + + return response()->json([ + 'message' => 'Une erreur est survenue lors de la mise à jour du document du défunt.', + 'error' => config('app.debug') ? $e->getMessage() : null, + ], 500); + } + } + + /** + * Remove the specified deceased document. + */ + public function destroy(string $id): JsonResponse + { + try { + $deleted = $this->deceasedDocumentRepository->delete($id); + + if (!$deleted) { + return response()->json([ + 'message' => 'Document du défunt non trouvé ou échec de la suppression.', + ], 404); + } + + return response()->json([ + 'message' => 'Document du défunt supprimé avec succès.', + ], 200); + } catch (\Exception $e) { + Log::error('Erreur lors de la suppression du document du défunt: ' . $e->getMessage(), [ + 'exception' => $e, + 'trace' => $e->getTraceAsString(), + 'document_id' => $id, + ]); + + return response()->json([ + 'message' => 'Une erreur est survenue lors de la suppression du document du défunt.', + 'error' => config('app.debug') ? $e->getMessage() : null, + ], 500); + } + } +} diff --git a/thanasoft-back/app/Http/Controllers/Api/InterventionController.php b/thanasoft-back/app/Http/Controllers/Api/InterventionController.php index 26cfad8..273f785 100644 --- a/thanasoft-back/app/Http/Controllers/Api/InterventionController.php +++ b/thanasoft-back/app/Http/Controllers/Api/InterventionController.php @@ -173,4 +173,40 @@ class InterventionController extends Controller ], Response::HTTP_INTERNAL_SERVER_ERROR); } } + + /** + * Get interventions for a specific month. + */ + public function byMonth(Request $request): JsonResponse + { + try { + $validated = $request->validate([ + 'year' => 'required|integer|min:2000|max:2100', + 'month' => 'required|integer|min:1|max:12' + ]); + + $interventions = $this->interventionRepository->getByMonth( + $validated['year'], + $validated['month'] + ); + + return response()->json([ + 'data' => $interventions->map(function ($intervention) { + return new InterventionResource($intervention); + }), + 'meta' => [ + 'total' => $interventions->count(), + 'year' => $validated['year'], + 'month' => $validated['month'], + ] + ]); + } catch (\Exception $e) { + Log::error('Error fetching interventions by month: ' . $e->getMessage()); + + return response()->json([ + 'message' => 'Une erreur est survenue lors de la récupération des interventions du mois.', + 'error' => $e->getMessage() + ], Response::HTTP_INTERNAL_SERVER_ERROR); + } + } } diff --git a/thanasoft-back/app/Http/Requests/StoreDeceasedDocumentRequest.php b/thanasoft-back/app/Http/Requests/StoreDeceasedDocumentRequest.php new file mode 100644 index 0000000..9957c3b --- /dev/null +++ b/thanasoft-back/app/Http/Requests/StoreDeceasedDocumentRequest.php @@ -0,0 +1,49 @@ + + */ + public function rules(): array + { + return [ + 'deceased_id' => 'required|exists:deceased,id', + 'doc_type' => 'required|string|max:191', + 'file_id' => 'nullable|exists:files,id', + 'generated_at' => 'nullable|date', + ]; + } + + /** + * Get the error messages for the defined validation rules. + * + * @return array + */ + public function messages(): array + { + return [ + 'deceased_id.required' => 'Le défunt est obligatoire.', + 'deceased_id.exists' => 'Le défunt sélectionné n\'existe pas.', + 'doc_type.required' => 'Le type de document est obligatoire.', + 'doc_type.string' => 'Le type de document doit être une chaîne de caractères.', + 'doc_type.max' => 'Le type de document ne peut pas dépasser :max caractères.', + 'file_id.exists' => 'Le fichier sélectionné n\'existe pas.', + 'generated_at.date' => 'La date de génération doit être une date valide.', + ]; + } +} diff --git a/thanasoft-back/app/Http/Requests/UpdateDeceasedDocumentRequest.php b/thanasoft-back/app/Http/Requests/UpdateDeceasedDocumentRequest.php new file mode 100644 index 0000000..cae38d2 --- /dev/null +++ b/thanasoft-back/app/Http/Requests/UpdateDeceasedDocumentRequest.php @@ -0,0 +1,49 @@ + + */ + public function rules(): array + { + return [ + 'deceased_id' => 'sometimes|required|exists:deceased,id', + 'doc_type' => 'sometimes|required|string|max:191', + 'file_id' => 'nullable|exists:files,id', + 'generated_at' => 'nullable|date', + ]; + } + + /** + * Get the error messages for the defined validation rules. + * + * @return array + */ + public function messages(): array + { + return [ + 'deceased_id.required' => 'Le défunt est obligatoire.', + 'deceased_id.exists' => 'Le défunt sélectionné n\'existe pas.', + 'doc_type.required' => 'Le type de document est obligatoire.', + 'doc_type.string' => 'Le type de document doit être une chaîne de caractères.', + 'doc_type.max' => 'Le type de document ne peut pas dépasser :max caractères.', + 'file_id.exists' => 'Le fichier sélectionné n\'existe pas.', + 'generated_at.date' => 'La date de génération doit être une date valide.', + ]; + } +} diff --git a/thanasoft-back/app/Http/Resources/Deceased/DeceasedDocumentCollection.php b/thanasoft-back/app/Http/Resources/Deceased/DeceasedDocumentCollection.php new file mode 100644 index 0000000..c0b76a7 --- /dev/null +++ b/thanasoft-back/app/Http/Resources/Deceased/DeceasedDocumentCollection.php @@ -0,0 +1,48 @@ + + */ + public function toArray($request): array + { + return [ + 'data' => $this->collection->map(function ($document) { + return [ + 'id' => $document->id, + 'deceased_id' => $document->deceased_id, + 'doc_type' => $document->doc_type, + 'file_id' => $document->file_id, + 'generated_at' => $document->generated_at?->format('Y-m-d H:i:s'), + 'created_at' => $document->created_at?->format('Y-m-d H:i:s'), + 'updated_at' => $document->updated_at?->format('Y-m-d H:i:s'), + + // Relations + 'deceased' => $document->deceased ? [ + 'id' => $document->deceased->id, + 'first_name' => $document->deceased->first_name, + 'last_name' => $document->deceased->last_name, + 'full_name' => $document->deceased->first_name . ' ' . $document->deceased->last_name, + 'date_of_birth' => $document->deceased->date_of_birth?->format('Y-m-d'), + 'date_of_death' => $document->deceased->date_of_death?->format('Y-m-d'), + ] : null, + 'file' => $document->file ? [ + 'id' => $document->file->id, + 'filename' => $document->file->filename ?? null, + 'path' => $document->file->path ?? null, + 'mime_type' => $document->file->mime_type ?? null, + 'size' => $document->file->size ?? null, + ] : null, + ]; + }), + ]; + } +} diff --git a/thanasoft-back/app/Http/Resources/Deceased/DeceasedDocumentResource.php b/thanasoft-back/app/Http/Resources/Deceased/DeceasedDocumentResource.php new file mode 100644 index 0000000..633d636 --- /dev/null +++ b/thanasoft-back/app/Http/Resources/Deceased/DeceasedDocumentResource.php @@ -0,0 +1,54 @@ + + */ + public function toArray($request): array + { + return [ + 'id' => $this->id, + 'deceased_id' => $this->deceased_id, + 'doc_type' => $this->doc_type, + 'file_id' => $this->file_id, + 'generated_at' => $this->generated_at?->format('Y-m-d H:i:s'), + 'created_at' => $this->created_at?->format('Y-m-d H:i:s'), + 'updated_at' => $this->updated_at?->format('Y-m-d H:i:s'), + + // Relations + 'deceased' => $this->when( + $this->relationLoaded('deceased'), + function () { + return [ + 'id' => $this->deceased->id, + 'first_name' => $this->deceased->first_name, + 'last_name' => $this->deceased->last_name, + 'full_name' => $this->deceased->first_name . ' ' . $this->deceased->last_name, + 'date_of_birth' => $this->deceased->date_of_birth?->format('Y-m-d'), + 'date_of_death' => $this->deceased->date_of_death?->format('Y-m-d'), + ]; + } + ), + 'file' => $this->when( + $this->relationLoaded('file'), + function () { + return $this->file ? [ + 'id' => $this->file->id, + 'filename' => $this->file->filename ?? null, + 'path' => $this->file->path ?? null, + 'mime_type' => $this->file->mime_type ?? null, + 'size' => $this->file->size ?? null, + ] : null; + } + ), + ]; + } +} diff --git a/thanasoft-back/app/Providers/RepositoryServiceProvider.php b/thanasoft-back/app/Providers/RepositoryServiceProvider.php index 924eb69..81543e7 100644 --- a/thanasoft-back/app/Providers/RepositoryServiceProvider.php +++ b/thanasoft-back/app/Providers/RepositoryServiceProvider.php @@ -4,6 +4,8 @@ namespace App\Providers; use App\Repositories\DeceasedRepositoryInterface; use App\Repositories\DeceasedRepository; +use App\Repositories\DeceasedDocumentRepositoryInterface; +use App\Repositories\DeceasedDocumentRepository; use App\Repositories\InterventionRepositoryInterface; use App\Repositories\InterventionRepository; use Illuminate\Support\ServiceProvider; @@ -16,6 +18,7 @@ class RepositoryServiceProvider extends ServiceProvider public function register(): void { $this->app->bind(DeceasedRepositoryInterface::class, DeceasedRepository::class); + $this->app->bind(DeceasedDocumentRepositoryInterface::class, DeceasedDocumentRepository::class); $this->app->bind(InterventionRepositoryInterface::class, InterventionRepository::class); } diff --git a/thanasoft-back/app/Repositories/DeceasedDocumentRepository.php b/thanasoft-back/app/Repositories/DeceasedDocumentRepository.php new file mode 100644 index 0000000..6e2ea51 --- /dev/null +++ b/thanasoft-back/app/Repositories/DeceasedDocumentRepository.php @@ -0,0 +1,121 @@ +model->newQuery()->with(['deceased', 'file']); + + // Apply filters + if (!empty($filters['search'])) { + $query->where(function ($q) use ($filters) { + $q->where('doc_type', 'like', '%' . $filters['search'] . '%') + ->orWhereHas('deceased', function ($q) use ($filters) { + $q->where('first_name', 'like', '%' . $filters['search'] . '%') + ->orWhere('last_name', 'like', '%' . $filters['search'] . '%'); + }); + }); + } + + if (!empty($filters['deceased_id'])) { + $query->where('deceased_id', $filters['deceased_id']); + } + + if (!empty($filters['doc_type'])) { + $query->where('doc_type', $filters['doc_type']); + } + + if (!empty($filters['file_id'])) { + $query->where('file_id', $filters['file_id']); + } + + // Apply sorting + $sortField = $filters['sort_by'] ?? 'created_at'; + $sortDirection = $filters['sort_direction'] ?? 'desc'; + $query->orderBy($sortField, $sortDirection); + + return $query->paginate($perPage); + } + + /** + * Get documents by deceased ID + */ + public function getByDeceasedId(int $deceasedId): Collection + { + return $this->model->newQuery() + ->with(['deceased', 'file']) + ->where('deceased_id', $deceasedId) + ->orderBy('generated_at', 'desc') + ->get(); + } + + /** + * Get documents by document type + */ + public function getByDocType(string $docType): Collection + { + return $this->model->newQuery() + ->with(['deceased', 'file']) + ->where('doc_type', $docType) + ->orderBy('generated_at', 'desc') + ->get(); + } + + /** + * Get documents by file ID + */ + public function getByFileId(int $fileId): Collection + { + return $this->model->newQuery() + ->with(['deceased', 'file']) + ->where('file_id', $fileId) + ->orderBy('generated_at', 'desc') + ->get(); + } + + /** + * Search documents by various criteria + */ + public function search(array $criteria): Collection + { + $query = $this->model->newQuery()->with(['deceased', 'file']); + + if (!empty($criteria['deceased_id'])) { + $query->where('deceased_id', $criteria['deceased_id']); + } + + if (!empty($criteria['doc_type'])) { + $query->where('doc_type', $criteria['doc_type']); + } + + if (!empty($criteria['file_id'])) { + $query->where('file_id', $criteria['file_id']); + } + + if (!empty($criteria['generated_from'])) { + $query->where('generated_at', '>=', $criteria['generated_from']); + } + + if (!empty($criteria['generated_to'])) { + $query->where('generated_at', '<=', $criteria['generated_to']); + } + + return $query->orderBy('generated_at', 'desc')->get(); + } +} diff --git a/thanasoft-back/app/Repositories/DeceasedDocumentRepositoryInterface.php b/thanasoft-back/app/Repositories/DeceasedDocumentRepositoryInterface.php new file mode 100644 index 0000000..67ee56f --- /dev/null +++ b/thanasoft-back/app/Repositories/DeceasedDocumentRepositoryInterface.php @@ -0,0 +1,39 @@ +whereBetween('scheduled_at', [$startDate . ' 00:00:00', $endDate . ' 23:59:59']) + ->with(['client', 'deceased', 'location', 'assignedPractitioner']) + ->orderBy('scheduled_at', 'asc') + ->get(); + } } diff --git a/thanasoft-back/app/Repositories/InterventionRepositoryInterface.php b/thanasoft-back/app/Repositories/InterventionRepositoryInterface.php index a4df6df..7cf3185 100644 --- a/thanasoft-back/app/Repositories/InterventionRepositoryInterface.php +++ b/thanasoft-back/app/Repositories/InterventionRepositoryInterface.php @@ -57,4 +57,13 @@ interface InterventionRepositoryInterface * @return Intervention */ public function changeStatus(Intervention $intervention, string $status): Intervention; + + /** + * Get interventions for a specific month + * + * @param int $year + * @param int $month + * @return \Illuminate\Database\Eloquent\Collection + */ + public function getByMonth(int $year, int $month): \Illuminate\Database\Eloquent\Collection; } diff --git a/thanasoft-back/routes/api.php b/thanasoft-back/routes/api.php index 6b33347..0f65f9d 100644 --- a/thanasoft-back/routes/api.php +++ b/thanasoft-back/routes/api.php @@ -14,6 +14,7 @@ use App\Http\Controllers\Api\EmployeeController; use App\Http\Controllers\Api\ThanatopractitionerController; use App\Http\Controllers\Api\PractitionerDocumentController; use App\Http\Controllers\Api\DeceasedController; +use App\Http\Controllers\Api\DeceasedDocumentController; use App\Http\Controllers\Api\InterventionController; @@ -106,8 +107,22 @@ Route::middleware('auth:sanctum')->group(function () { Route::delete('/{deceased}', [DeceasedController::class, 'destroy']); }); + // Deceased Document Routes + Route::prefix('deceased-documents')->group(function () { + Route::get('/by-deceased/{deceasedId}', [DeceasedDocumentController::class, 'byDeceased']); + Route::get('/by-doc-type', [DeceasedDocumentController::class, 'byDocType']); + Route::get('/by-file/{fileId}', [DeceasedDocumentController::class, 'byFile']); + Route::get('/search', [DeceasedDocumentController::class, 'search']); + Route::get('/', [DeceasedDocumentController::class, 'index']); + Route::post('/', [DeceasedDocumentController::class, 'store']); + Route::get('/{id}', [DeceasedDocumentController::class, 'show']); + Route::put('/{id}', [DeceasedDocumentController::class, 'update']); + Route::delete('/{id}', [DeceasedDocumentController::class, 'destroy']); + }); + // Intervention Routes Route::prefix('interventions')->group(function () { + Route::get('/by-month', [InterventionController::class, 'byMonth']); Route::get('/', [InterventionController::class, 'index']); Route::post('/', [InterventionController::class, 'store']); Route::get('/{intervention}', [InterventionController::class, 'show']); diff --git a/thanasoft-front/src/components/Organism/Agenda/AgendaPresentation.vue b/thanasoft-front/src/components/Organism/Agenda/AgendaPresentation.vue new file mode 100644 index 0000000..f36b442 --- /dev/null +++ b/thanasoft-front/src/components/Organism/Agenda/AgendaPresentation.vue @@ -0,0 +1,130 @@ + + + + + diff --git a/thanasoft-front/src/components/atoms/Agenda/AddInterventionButton.vue b/thanasoft-front/src/components/atoms/Agenda/AddInterventionButton.vue new file mode 100644 index 0000000..f3caad2 --- /dev/null +++ b/thanasoft-front/src/components/atoms/Agenda/AddInterventionButton.vue @@ -0,0 +1,37 @@ + + + + + diff --git a/thanasoft-front/src/components/atoms/Agenda/InterventionBadge.vue b/thanasoft-front/src/components/atoms/Agenda/InterventionBadge.vue new file mode 100644 index 0000000..8cba9af --- /dev/null +++ b/thanasoft-front/src/components/atoms/Agenda/InterventionBadge.vue @@ -0,0 +1,50 @@ + + + + + diff --git a/thanasoft-front/src/components/molecules/Agenda/AgendaCalendar.vue b/thanasoft-front/src/components/molecules/Agenda/AgendaCalendar.vue new file mode 100644 index 0000000..f575af8 --- /dev/null +++ b/thanasoft-front/src/components/molecules/Agenda/AgendaCalendar.vue @@ -0,0 +1,148 @@ + + + + + diff --git a/thanasoft-front/src/components/molecules/Agenda/UpcomingInterventions.vue b/thanasoft-front/src/components/molecules/Agenda/UpcomingInterventions.vue new file mode 100644 index 0000000..f41af96 --- /dev/null +++ b/thanasoft-front/src/components/molecules/Agenda/UpcomingInterventions.vue @@ -0,0 +1,88 @@ + + + + + diff --git a/thanasoft-front/src/components/templates/Agenda/AgendaTemplate.vue b/thanasoft-front/src/components/templates/Agenda/AgendaTemplate.vue new file mode 100644 index 0000000..6cb46dd --- /dev/null +++ b/thanasoft-front/src/components/templates/Agenda/AgendaTemplate.vue @@ -0,0 +1,30 @@ + + + + + diff --git a/thanasoft-front/src/services/intervention.ts b/thanasoft-front/src/services/intervention.ts index b208b4e..29f03fb 100644 --- a/thanasoft-front/src/services/intervention.ts +++ b/thanasoft-front/src/services/intervention.ts @@ -232,6 +232,22 @@ export const InterventionService = { return response; }, + + /** + * Get interventions by month + */ + async getInterventionsByMonth( + year: number, + month: number + ): Promise { + const response = await request({ + url: "/api/interventions/by-month", + method: "get", + params: { year, month }, + }); + + return response; + }, }; export default InterventionService; diff --git a/thanasoft-front/src/stores/interventionStore.ts b/thanasoft-front/src/stores/interventionStore.ts index 190b4f2..dd03874 100644 --- a/thanasoft-front/src/stores/interventionStore.ts +++ b/thanasoft-front/src/stores/interventionStore.ts @@ -458,6 +458,36 @@ export const useInterventionStore = defineStore("intervention", () => { } }; + /** + * Get interventions by month + */ + const fetchInterventionsByMonth = async (year: number, month: number) => { + setLoading(true); + setError(null); + setSuccess(false); + + try { + const response = await InterventionService.getInterventionsByMonth( + year, + month + ); + setInterventions(response.data); + if (response.meta) { + setPagination(response.meta); + } + return response; + } catch (err: any) { + const errorMessage = + err.response?.data?.message || + err.message || + "Échec du chargement des interventions du mois"; + setError(errorMessage); + throw err; + } finally { + setLoading(false); + } + }; + /** * Reset the state */ @@ -517,6 +547,7 @@ export const useInterventionStore = defineStore("intervention", () => { searchInterventions, updateInterventionStatus, assignPractitioner, + fetchInterventionsByMonth, resetState, }; }); diff --git a/thanasoft-front/src/views/pages/Agenda.vue b/thanasoft-front/src/views/pages/Agenda.vue index aa24163..a16330c 100644 --- a/thanasoft-front/src/views/pages/Agenda.vue +++ b/thanasoft-front/src/views/pages/Agenda.vue @@ -1,11 +1,287 @@ - + + diff --git a/thanasoft-front/src/views/pages/Agenda/Agenda.vue b/thanasoft-front/src/views/pages/Agenda/Agenda.vue new file mode 100644 index 0000000..00baae5 --- /dev/null +++ b/thanasoft-front/src/views/pages/Agenda/Agenda.vue @@ -0,0 +1,446 @@ + + + + +