Introduction
Dans ce tutoriel, nous allons créer une application de gestion des ressources humaines avec le Refine Framework et la déployer sur la DigitalOcean App Platform.
À la fin de ce tutoriel, nous aurons une application de gestion des ressources humaines qui comprend :
- Page de connexion : Permet aux utilisateurs de se connecter en tant que manager ou employé. Les managers ont accès aux pages
Congés
etDemandes
, tandis que les employés n’ont accès qu’à la pageCongés
. - Pages de congés : Permet aux employés de demander, de consulter et d’annuler leurs congés. Les managers peuvent également attribuer de nouveaux congés.
- Page des demandes : Accessible uniquement aux responsables RH pour approuver ou rejeter les demandes de congé.
Remarque : Vous pouvez obtenir le code source complet de l’application que nous allons créer dans ce tutoriel depuis ce dépôt GitHub
En procédant ainsi, nous utiliserons :
- API REST : Pour récupérer et mettre à jour les données. Refine dispose de packages de fournisseur de données intégrés et d’API REST, mais vous pouvez également créer les vôtres pour répondre à vos besoins spécifiques. Dans ce guide, nous allons utiliser NestJs CRUD comme notre service backend et le package @refinedev/nestjsx-crud comme notre fournisseur de données.
- Material UI : Nous l’utiliserons pour les composants UI et le personnaliserons entièrement selon notre propre design. Refine prend en charge Material UI par défaut, mais vous pouvez utiliser n’importe quelle bibliothèque UI que vous préférez.
Une fois que nous aurons construit l’application, nous la mettrons en ligne en utilisant la plateforme d’applications de DigitalOcean qui facilite la configuration, le lancement et la croissance des applications et des sites web statiques. Vous pouvez déployer du code en pointant simplement vers un dépôt GitHub et laisser la plateforme d’applications faire le gros du travail en gérant l’infrastructure, les environnements d’exécution des applications et les dépendances.
Prérequis
- Un environnement de développement local pour Node.js. Vous pouvez suivre le Guide d’installation de Node.js et création d’un environnement de développement local.
- Une connaissance préliminaire de React et TypeScript. Vous pouvez suivre la série Comment coder en React.js et Utiliser TypeScript avec React.
- Un compte GitHub
- Un compte DigitalOcean
Qu’est-ce que Refine ?
Refine est un méta-framework React open source pour construire des applications web B2B complexes, principalement axées sur la gestion des données, comme les outils internes, les panneaux d’administration et les tableaux de bord. Il est conçu en fournissant un ensemble de hooks et de composants pour améliorer le processus de développement avec un meilleur flux de travail pour le développeur.
Il offre des fonctionnalités complètes et prêtes pour la production pour des applications de niveau entreprise afin de simplifier les tâches rémunérées comme la gestion de l’état et des données, l’authentification et le contrôle d’accès. Cela permet aux développeurs de rester concentrés sur le cœur de leur application d’une manière qui est abstraite de nombreux détails d’implémentation écrasants.
Étape 1 — Configuration du projet
Nous utiliserons la commande npm create refine-app
pour initialiser le projet de manière interactive.
Sélectionnez les options suivantes lorsqu’elles vous sont demandées :
Une fois la configuration terminée, accédez au dossier du projet et lancez votre application avec :
Ouvrez http://localhost:5173
dans votre navigateur pour voir l’application.
Préparation du Projet
Maintenant que notre projet est configuré, apportons quelques modifications à la structure du projet et supprimons les fichiers inutiles.
Tout d’abord, installez les dépendances tierces :
@mui/x-date-pickers
,@mui/x-date-pickers-pro
: Ce sont des composants de sélection de date pour Material UI. Nous les utiliserons pour sélectionner la plage de dates des demandes de congé.react-hot-toast
: Une bibliothèque de toast minimaliste pour React. Nous l’utiliserons pour afficher des messages de succès et d’erreur.react-infinite-scroll-component
: Un composant React pour faciliter le défilement infini. Nous l’utiliserons pour charger plus de demandes de congé à mesure que l’utilisateur fait défiler la page pour voir plus de demandes.dayjs
: Une bibliothèque de date légère pour analyser, valider, manipuler et formater des dates.vite-tsconfig-paths
: Un plugin Vite qui vous permet d’utiliser des alias de chemin TypeScript dans votre projet Vite.
Après avoir installé les dépendances, mettez à jour vite.config.ts
et tsconfig.json
pour utiliser le plugin vite-tsconfig-paths
. Cela permet d’utiliser des alias de chemin TypeScript dans les projets Vite, permettant des importations avec l’alias @
.
Ensuite, supprimons les fichiers et dossiers inutiles :
src/contexts
: Ce dossier contient un seul fichier qui estColorModeContext
. Il gère le mode sombre/claire de l’application. Nous ne l’utiliserons pas dans ce tutoriel.src/components
: Ce dossier contient le composant<Header />
. Nous utiliserons un composant d’en-tête personnalisé dans ce tutoriel.
Après avoir supprimé les fichiers et dossiers, App.tsx
génère une erreur que nous corrigerons dans les étapes suivantes.
Tout au long du tutoriel, nous aborderons la programmation des pages et composants principaux. Alors, récupérez les fichiers et dossiers nécessaires depuis le répertoire GitHub. Avec ces fichiers, nous aurons une structure de base pour notre application de gestion des ressources humaines.
- icônes : Dossier des icônes contenant toutes les icônes de l’application.
- types :
index.ts
: Types de l’application.
- utilitaires:
constants.ts
: Constantes de l’application.axios.ts
: Instance Axios pour les requêtes API, gestion des jetons d’accès, des jetons de rafraîchissement et des erreurs.init-dayjs.ts
: Initialise Day.js avec les plugins requis.
- fournisseurs:
access-control
: Gère les autorisations utilisateur en utilisantaccessControlProvider
; contrôle la visibilité de la pageRequests
en fonction du rôle de l’utilisateur.auth-provider
: Gère l’authentification avecauthProvider
; assure que toutes les pages sont protégées et nécessitent une connexion.notification-provider
: Affiche les messages de succès et d’erreur viareact-hot-toast
.query-client
: Client de requête personnalisé pour un contrôle et une personnalisation complets.theme-provider
: Gère le thème Material UI.
- composants:
layout
: Composants de mise en page.loading-overlay
: Affiche un superposition de chargement pendant les récupérations de données.input
: Affiche les champs de saisie de formulaire.frame
: Composant personnalisé ajoutant des bordures, des titres et des icônes aux sections de la page.modal
: Composant de boîte de dialogue modale personnalisée.
Après avoir copié les fichiers et dossiers, la structure des fichiers devrait ressembler à ceci :
└── 📁src
└── 📁components
└── 📁frame
└── 📁input
└── 📁layout
└── 📁header
└── 📁page-header
└── 📁sider
└── 📁loading-overlay
└── 📁modal
└── 📁icons
└── 📁providers
└── 📁access-control
└── 📁auth-provider
└── 📁notification-provider
└── 📁query-client
└── 📁theme-provider
└── 📁types
└── 📁utilities
└── App.tsx
└── index.tsx
└── vite-env.d.ts
Ensuite, mettez à jour le fichier App.tsx
pour inclure les fournisseurs et composants nécessaires.
Décomposons les changements importants que nous avons apportés au fichier App.tsx
:
<Refine />
: Le composant principal de@refinedev/core
qui enveloppe l’ensemble de l’application pour fournir la récupération de données, la gestion d’état et d’autres fonctionnalités.<DevtoolsProvider />
et<DevtoolsPanel />
: Utilisés à des fins de débogage et de développement.<ThemeProvider />
: Applique un thème personnalisé à l’application.- Initialisation de Day.js: Pour la manipulation de la date et de l’heure.
- resources: Un tableau spécifiant les entités de données (
employee
etmanager
) que Refine va récupérer. Nous utilisons des ressources parent et enfant pour organiser les données et gérer les autorisations. Chaque ressource a unescope
définissant le rôle de l’utilisateur, qui contrôle l’accès à différentes parties de l’application. - queryClient: Un client de requête personnalisé pour un contrôle total et une personnalisation de la récupération des données.
- syncWithLocation: Permet de synchroniser l’état de l’application (filtres, trieurs, pagination, etc.) avec l’URL.
- warnWhenUnsavedChanges: Affiche un avertissement lorsque l’utilisateur essaie de naviguer loin d’une page avec des modifications non enregistrées.
<Layout />
: Un composant de mise en page personnalisé qui enveloppe le contenu de l’application. Il contient l’en-tête, la barre latérale et la zone de contenu principal. Nous expliquerons ce composant dans les étapes suivantes.
Maintenant, nous sommes prêts à commencer à construire l’application de gestion des ressources humaines.
Étape 2— Personnalisation et stylisation
Examinez de plus près le theme-provider
. Nous avons fortement personnalisé le thème Material UI pour correspondre au design de l’application de gestion des ressources humaines, en créant deux thèmes, un pour les gestionnaires et un pour les employés, afin de les différencier par des couleurs différentes.
De plus, nous avons ajouté Inter comme police personnalisée pour l’application. Pour l’installer, vous devez ajouter la ligne suivante au fichier index.html
:
Inspection du composant personnalisé <Layout />
Component
Dans l’étape précédente, nous avons ajouté un composant de mise en page personnalisé à l’application. Normalement, nous pourrions utiliser la mise en page par défaut du framework UI, mais nous voulons montrer comment vous pouvez personnaliser.
Le composant de mise en page contient l’en-tête, la barre latérale et la zone de contenu principal. Il utilise <ThemedLayoutV2 />
comme base et l’a personnalisé pour correspondre à la conception de l’application de gestion des ressources humaines.
<Sider />
La barre latérale contient le logo de l’application et les liens de navigation. Sur les appareils mobiles, c’est une barre latérale collapsible qui s’ouvre lorsque l’utilisateur clique sur l’icône du menu. Les liens de navigation sont préparés avec le hook useMenu
de Refine et rendus en fonction du rôle de l’utilisateur à l’aide du composant <CanAccess />
.
<UserSelect />
Monté sur la barre latérale, il affiche l’avatar et le nom de l’utilisateur connecté. Lorsqu’on clique dessus, il ouvre une popover avec les détails de l’utilisateur et un bouton de déconnexion. Les utilisateurs peuvent basculer entre différents rôles en sélectionnant dans la liste déroulante. Ce composant permet de tester en passant entre les utilisateurs avec différents rôles.
<Header />
Il ne rend rien sur les appareils de bureau. Sur les appareils mobiles, il affiche le logo de l’application et une icône de menu pour ouvrir la barre latérale. L’en-tête est collant et toujours visible en haut de la page.
<PageHeader />
Cela affiche le titre de la page et les boutons de navigation. Le titre de la page est généré automatiquement avec le useResource
hook, qui récupère le nom de la ressource depuis le contexte Refine. Cela nous permet de partager le même style et la même mise en page à travers l’application.
Étape 3 — Mise en œuvre de l’authentification et de l’autorisation
Dans cette étape, nous allons mettre en œuvre la logique d’authentification et d’autorisation pour notre application de gestion des ressources humaines. Cela servira d’excellent exemple de contrôle d’accès dans les applications d’entreprise.
Lorsque les utilisateurs se connectent en tant que gestionnaires, ils pourront voir les pages Temps de congé
et Demandes
. S’ils se connectent en tant qu’employés, ils ne verront que la page Temps de congé
. Les gestionnaires peuvent approuver ou refuser les demandes de congé sur la page Demandes
.
Les employés peuvent demander un congé et consulter leur historique sur la page Time Off
. Pour mettre en œuvre cela, nous utiliserons les fonctionnalités authProvider
et accessControlProvider
de Refine.
Authentication
Dans Refine, l’authentification est gérée par le authProvider
. Cela vous permet de définir la logique d’authentification pour votre application. À l’étape précédente, nous avons déjà copié le authProvider
du dépôt GitHub et l’avons donné au composant <Refine />
en tant que prop. Nous utiliserons les hooks et composants suivants pour contrôler le comportement de notre application en fonction de la connexion de l’utilisateur ou non.
useLogin
: Un hook qui fournit une fonctionmutate
pour connecter l’utilisateur.useLogout
: Un hook qui fournit une fonctionmutate
pour déconnecter l’utilisateur.useIsAuthenticated
: Un hook qui renvoie un booléen indiquant si l’utilisateur est authentifié.<Authenticated />
: Un composant qui affiche ses enfants uniquement si l’utilisateur est authentifié.
Autorisation
Dans Refine, l’autorisation est gérée par le accessControlProvider
. Il vous permet de définir les rôles et les permissions des utilisateurs, et de contrôler l’accès à différentes parties de l’application en fonction du rôle de l’utilisateur. À l’étape précédente, nous avons déjà copié le accessControlProvider
depuis le dépôt GitHub et l’avons donné au composant <Refine />
en tant que prop. Prenons un peu plus de temps pour examiner le accessControlProvider
et voir comment il fonctionne.
Dans notre application, nous avons deux rôles : MANAGER
et EMPLOYEE
.
Les gestionnaires ont accès à la page Demandes
, tandis que les employés n’ont accès qu’à la page Temps libre
. Le accessControlProvider
vérifie le rôle de l’utilisateur et l’étendue de la ressource pour déterminer si l’utilisateur peut y accéder. Si le rôle de l’utilisateur correspond à l’étendue de la ressource, il peut y accéder. Sinon, l’accès lui est refusé. Nous utiliserons le hook useCan
et le composant <CanAccess />
pour contrôler le comportement de notre application en fonction du rôle de l’utilisateur.
Configuration de la page de connexion
Lors de l’étape précédente, nous avons ajouté le authProvider
au composant <Refine />
. Le authProvider
est responsable de la gestion de l’authentification.
Tout d’abord, nous devons obtenir des images. Nous utiliserons ces images comme images de fond pour la page de connexion. Créez un nouveau dossier appelé images
dans le dossier public
et obtenez les images à partir du dépôt GitHub.
Après avoir obtenu les images, créons un nouveau fichier appelé index.tsx
dans le dossier src/pages/login
et ajoutons le code suivant :
Pour simplifier le processus d’authentification, nous avons créé un objet mockUsers
avec deux tableaux : managers
et employees
. Chaque tableau contient des objets utilisateurs prédéfinis. Lorsqu’un utilisateur sélectionne un email dans le menu déroulant et clique sur le bouton Sign in
, la fonction login
est appelée avec l’email sélectionné. La fonction login
est une fonction de mutation fournie par le hook useLogin
de Refine. Elle appelle authProvider.login
avec l’email sélectionné.
Ensuite, importons le composant <PageLogin />
et mettons à jour le fichier App.tsx
avec les changements mis en évidence.
Dans le fichier App.tsx
mis à jour, nous avons ajouté le composant <Authenticated />
de Refine. Ce composant est utilisé pour protéger les routes nécessitant une authentification. Il prend une prop key
pour identifier de manière unique le composant, une prop fallback
à rendre lorsque l’utilisateur n’est pas authentifié, et une prop redirectOnFail
pour rediriger l’utilisateur vers la route spécifiée lorsque l’authentification échoue. En interne, il appelle la méthode authProvider.check
pour vérifier si l’utilisateur est authentifié.
Regardons de plus près ce que nous avons sur key="auth-pages"
<Authenticated />
le composant s’enveloppe dans la route “/login” pour vérifier l’état d’authentification de l’utilisateur.
fallback={<Outlet />}
: Si l’utilisateur n’est pas authentifié, rendre la route imbriquée (c’est-à-dire afficher le composant<PageLogin />
).- Enfants (
<Navigate to="/" />
) : Si l’utilisateur est authentifié, le rediriger vers la page d’accueil (/
).
Examinons de plus près ce que nous avons sur key="catch-all"
<Authenticated />
le composant s’enveloppe dans la route path="*"
pour vérifier l’état d’authentification de l’utilisateur. Cette route est une route de capture qui rend le <ErrorComponent />
lorsque l’utilisateur est authentifié. Elle nous permet d’afficher une page 404 lorsque l’utilisateur essaie d’accéder à une route inexistante.
Maintenant, lorsque vous exécutez l’application et naviguez vers http://localhost:5173/login
, vous devriez voir la page de connexion avec le menu déroulant pour sélectionner l’utilisateur.
Pour l’instant, la page “/” ne fait rien. Dans les étapes suivantes, nous allons implémenter les pages Time Off
et Requests
.
Étape 4 — Création d’une page Time Off
Création de la page de liste des congés
Dans cette étape, nous allons construire la page Congés
. Les employés peuvent demander des congés et voir leur historique de congés. Les managers peuvent également consulter leur historique, mais au lieu de demander des congés, ils peuvent les attribuer directement à eux-mêmes. Nous allons faire fonctionner cela en utilisant le accessControlProvider
de Refine, le composant <CanAccess />
et le hook useCan
.

Avant de commencer à construire la page de congés, nous devons créer quelques composants pour afficher l’historique des congés, les demandes de congés à venir et les statistiques des congés utilisés. À la fin de cette étape, nous utiliserons ces composants pour construire la page de congés.
Création du composant <TimeOffList />
pour afficher l’historique des congés
Créez un nouveau dossier appelé time-offs
dans le dossier src/components
. À l’intérieur du dossier time-offs
, créez un nouveau fichier appelé list.tsx
et ajoutez le code suivant :
Le fichier list.tsx
est long, mais la plupart de son contenu concerne le style et la présentation de l’interface utilisateur.

Nous utiliserons ce composant <TimeOffList />
dans trois contextes différents :
La prop type
détermine quel type de liste de congés afficher :
inReview
: Affiche les demandes de congé en attente d’approbation.upcoming
: Affiche les congés à venir qui ont été approuvés mais qui ne se sont pas encore produits.history
: Liste les congés qui ont été approuvés et qui ont déjà eu lieu.
À l’intérieur du composant, nous créerons des filtres et des trieurs basés sur la prop type
. Nous utiliserons ces filtres et trieurs pour récupérer les données de congé depuis l’API.
Décomposons les parties clés du composant :
1. Obtenir l’utilisateur actuel
useGetIdentity<Employee>()
: Récupère les informations de l’utilisateur actuel.- Nous utilisons l’ID de l’employé pour filtrer les congés afin que chaque utilisateur ne voie que ses demandes.
2. Récupération des données de congé avec défilement infini
-
useInfiniteList<TimeOff>()
: Récupère les données de congés avec défilement infini.resource
: Spécifie le point de terminaison de l’API.sorters
etfilters
: Ajustés en fonction detype
pour récupérer les bonnes données.- Filtre
employeeId
: Assure que seuls les congés de l’utilisateur actuel sont récupérés. queryOptions.enabled
: Exécute la requête uniquement lorsque les données de l’employé sont disponibles.
-
<InfiniteScroll />
: Permet de charger plus de données au fur et à mesure que l’utilisateur fait défiler vers le bas.next
: Fonction pour récupérer la page suivante de données.hasMore
: Indique si d’autres données sont disponibles.
3. Annuler une demande de congé
useDelete
: Fournit la fonctiontimeOffCancel
pour supprimer une demande de congé.- Utilisé lorsqu’un utilisateur annule son congé.
- Affiche un message de succès une fois l’opération terminée.
4. Affichage des dates avec <DateField />
<DateField />
: Formate et affiche les dates de manière conviviale.valeur
: La date à afficher.format
: Spécifie le format de la date (par exemple, “5 janvier”).
5. Création de filtres et trieurs basés sur le type
Filtres:
- Définit les critères pour récupérer les congés en fonction du statut et des dates.
historique
: Récupère les congés approuvés qui sont déjà terminés.à_venir
: Récupère les congés approuvés qui sont à venir.
Trieurs:
- Détermine l’ordre des données récupérées.
historique
: Trie par date de début par ordre décroissant.
Construction du composant <TimeOffLeaveCards />
pour afficher les statistiques des congés utilisés.
Créez un nouveau fichier appelé leave-cards.tsx
dans le dossier src/components/time-offs
et ajoutez le code suivant :

Le composant <TimeOffLeaveCards />
affiche des statistiques sur les congés d’un employé. Il montre trois cartes pour le congé annuel, le congé maladie et le congé occasionnel, indiquant combien de jours sont disponibles ou utilisés.
Décomposons les parties clés du composant :
1. Récupération des données
- Données de l’employé : Utilise
useGetIdentity
pour obtenir les informations de l’employé actuel, comme le nombre de jours de congé annuel disponibles. - Comptes de congés : Utilise
useList
pour récupérer le nombre total de jours de congé maladie et de congé occasionnel utilisés par l’employé. Il définitpageSize
sur 1 car nous avons seulement besoin du compte total, pas de tous les détails.
2. Affichage des cartes
- Le composant rend trois composants de carte, un pour chaque type de congé.
- Chaque carte montre :
- Le type de congé (par exemple, Congé Annuel).
- Le nombre de jours disponibles ou utilisés.
- Une icône représentant le type de congé.
3. Gestion des états de chargement
- Si les données sont encore en cours de chargement, un espace réservé squelette s’affiche à la place des chiffres réels.
- La prop
loading
est passée aux cartes pour gérer cet état.
4. Le composant de carte
- Reçoit les props
type
,valeur
etloading
. - Utilise un
variantMap
pour obtenir les libellés, couleurs et icônes corrects en fonction du type de congé. - Affiche les informations de congé avec le style approprié.
Construction de <PageEmployeeTimeOffsList />
Maintenant que nous avons les composants pour la liste des congés et l’affichage des cartes de congé, créons le nouveau fichier dans le dossier src/pages/employee/time-offs/
appelé list.tsx
et ajoutons le code suivant :
<PageEmployeeTimeOffsList />
est le composant principal de la page des congés, nous utiliserons ce composant pour afficher les listes de congés et les cartes de congé lorsque les utilisateurs naviguent vers l’itinéraire /employee/time-offs
.

Décomposons les parties clés du composant :
1. Vérification des rôles de l’utilisateur
- Utilise le crochet
useCan
pour déterminer si l’utilisateur actuel est un gestionnaire. - Définit
isManager
surtrue
si l’utilisateur a les autorisations de gestionnaire.
2. Application du thème en fonction du rôle
- Enveloppe le contenu à l’intérieur d’un
<ThemeProvider />
. - Le thème change en fonction que l’utilisateur soit un gestionnaire ou un employé.
3. En-tête de page avec bouton conditionnel
- Rend un
<PageHeader />
avec le titre « Congés ». - Inclut un
<CreateButton />
qui change en fonction du rôle de l’utilisateur :- Si l’utilisateur est un gestionnaire, le bouton affiche « Assigner des congés ».
- Si l’utilisateur n’est pas un gestionnaire, il affiche « Demander des congés ».
- Cela est géré à l’aide du composant
<CanAccess />
, qui vérifie les permissions.
4. Affichage des statistiques de congés
- Inclut le composant
<TimeOffLeaveCards />
pour afficher les soldes et l’utilisation des congés. - Cela fournit un résumé des congés annuels, maladie et occasionnels.
5. Liste des demandes de congés
- Utilise une mise en page
<Grid />
pour organiser le contenu. - Sur le côté gauche (
md={6}
), il affiche :TimeOffList
avectype="inReview"
: Affiche les demandes de congés en attente.TimeOffList
avectype="upcoming"
: Affiche les congés approuvés à venir.
- Sur le côté droit (
md={6}
), il affiche:TimeOffList
avectype="historique"
: Affiche les congés passés qui ont déjà eu lieu.
Ajout de la route « /employee/time-offs »
Nous sommes prêts à rendre le composant <PageEmployeeTimeOffsList />
sur la route /employee/time-offs
. Mettons à jour le fichier App.tsx
pour inclure cette route:
Démontons les éléments clés du fichier App.tsx
mis à jour:
1. Définition de la ressource Congés
Nous avons ajouté une nouvelle ressource pour les congés en tant qu’enfant de la ressource
employé. Cela indique que les congés sont liés aux employés et sont accessibles par les employés.
name: 'congés'
: C’est l’identifiant de la ressource, utilisé en interne par Refine.list: '/employee/time-offs'
: Spécifie la route qui affiche la vue liste de la ressource.meta
: Un objet contenant des métadonnées supplémentaires sur la ressource.parent: 'employee'
: Regroupe cette ressource sous le champemployee
, qui peut être utilisé pour organiser les ressources dans l’interface utilisateur (comme dans un menu latéral) ou pour le contrôle d’accès.scope: Role.EMPLOYEE
: Indique que cette ressource est accessible aux utilisateurs ayant le rôleEMPLOYEE
. Nous l’utilisons dans leaccessControlProvider
pour gérer les autorisations.label: 'Time Off'
: Le nom d’affichage de la ressource dans l’interface utilisateur.icon: <TimeOffIcon />
: Associe leTimeOffIcon
à cette ressource pour une identification visuelle.
2. Redirection vers la ressource “time-offs” lorsque les utilisateurs naviguent vers la route /
Nous utilisons le <NavigateToResource />
composant pour rediriger les utilisateurs vers la ressource time-offs
lorsqu’ils naviguent vers la route /
. Cela garantit que les utilisateurs voient la liste des congés par défaut.
3. Redirection vers la ressource « time-offs » lorsque les utilisateurs sont authentifiés
Lorsque les utilisateurs sont authentifiés, nous les redirigeons vers la ressource time-offs
. S’ils ne sont pas authentifiés, ils voient la page de connexion.
4. Ajout de la Route /employee/time-offs
Nous organisons les pages des employés en utilisant des routes imbriquées. Tout d’abord, nous créons une route principale avec path='employee'
qui enveloppe le contenu dans un thème et une mise en page spécifiques aux employés. À l’intérieur de cette route, nous ajoutons path='time-offs'
, qui affiche le composant PageEmployeeTimeOffsList
. Cette structure regroupe toutes les fonctionnalités des employés sous un seul chemin et maintient le style cohérent.
Après avoir ajouté ces modifications, vous pouvez naviguer vers la route /employee/time-offs
pour voir la page de la liste des congés en action.

En ce moment, la page de la liste des congés est fonctionnelle, mais elle manque de la capacité de créer de nouvelles demandes de congé. Ajoutons la capacité de créer de nouvelles demandes de congé.
Construction de la page de création de congés
Nous allons créer une nouvelle page pour demander ou attribuer des congés. Cette page comportera un formulaire où les utilisateurs pourront spécifier le type de congé, les dates de début et de fin, ainsi que des notes supplémentaires.
Avant de commencer, nous devons créer de nouveaux composants à utiliser dans le formulaire :
Création du composant <TimeOffFormSummary />
Créez un nouveau fichier appelé form-summary.tsx
dans le dossier src/components/time-offs/
et ajoutez le code suivant :

Le composant <TimeOffFormSummary />
affiche un résumé de la demande de congé. Il montre le nombre de jours de congé annuel disponibles, le nombre de jours demandés et les jours restants. Nous utiliserons ce composant dans le formulaire de congé pour fournir aux utilisateurs un aperçu clair de leur demande.
Création du composant <PageEmployeeTimeOffsCreate />
Créez un nouveau fichier appelé create.tsx
dans le dossier src/pages/employee/time-offs/
et ajoutez le code suivant :

Le composant <PageEmployeeTimeOffsCreate />
affiche un formulaire pour créer de nouvelles demandes de congé dans une application de gestion des ressources humaines. Les employés et les managers peuvent l’utiliser pour demander ou attribuer des congés. Le formulaire comprend des options pour sélectionner le type de congé, choisir les dates de début et de fin, ajouter des notes et il montre un résumé du congé demandé.
Décomposons les principales parties du composant :
1. Vérification du rôle de l’utilisateur
Avec le useCan
hook, nous vérifions si l’utilisateur actuel a des permissions de manager. Cela détermine si l’utilisateur peut attribuer des congés ou seulement les demander. Nous traiterons la soumission du formulaire différemment dans onFinishHandler
en fonction du rôle de l’utilisateur.
2. État du formulaire et soumission
useForm
initialise le formulaire avec des valeurs par défaut et définit les notifications de succès en fonction du rôle de l’utilisateur. La fonction onFinishHandler
traite les données du formulaire avant de les soumettre. Pour les managers, le statut est immédiatement défini sur APPROVED
, tandis que les demandes des employés sont soumises pour examen.
3. Styles
Dans notre design, la couleur principale change en fonction du rôle de l’utilisateur. Nous utilisons le <ThemeProvider />
pour appliquer le bon thème en conséquence. Le texte et l’icône du bouton de soumission changent également selon que l’utilisateur est un manager ou un employé.
4. Ajout de la route “/employee/time-offs/create”
Nous devons ajouter la nouvelle route pour la page de création de congés. Mettons à jour le fichier App.tsx
pour inclure cette route :
Après avoir ajouté ces changements, vous pouvez naviguer vers la route /employee/time-offs/create
ou cliquer sur le bouton “Attribuer des congés” sur la page de la liste des congés pour accéder au formulaire de création de congés.

Étape 5 — Construction de la page de gestion des demandes de congé
Dans cette étape, nous allons créer une nouvelle page pour gérer les demandes de congé. Cette page permettra aux gestionnaires de consulter et d’approuver ou de rejeter les demandes de congé soumises par les employés.

Construction de la page de liste des demandes de congé
Nous allons créer une nouvelle page pour gérer les demandes de congé. Cette page inclura une liste des demandes de congé, affichant des détails tels que le nom de l’employé, le type de congé, les dates demandées et le statut actuel.
Avant de commencer, nous devons créer de nouveaux composants à utiliser dans la liste :
Construction du composant <RequestsList />
Créez un nouveau fichier appelé list.tsx
dans le dossier src/components/requests/
et ajoutez le code suivant :
Le composant <RequestsList />
affiche une liste de demandes de congé avec un défilement infini. Il inclut un indicateur de chargement, des espaces réservés squelette et un message en l’absence de données. Ce composant est conçu pour gérer efficacement de grands ensembles de données et offrir une expérience utilisateur fluide.
Création du composant <RequestsListItem />
Créez un nouveau fichier appelé list-item.tsx
dans le dossier src/components/requests/
et ajoutez le code suivant :
Le composant <RequestsListItem />
affiche une seule demande de congé dans la liste. Il inclut l’avatar de l’employé, son nom, une description, et un bouton pour voir les détails de la demande. Ce composant est réutilisable et peut être utilisé pour rendre chaque élément de la liste des demandes de congé.
Création du composant <PageManagerRequestsList />
Créez un nouveau fichier appelé list.tsx
dans le dossier src/pages/manager/requests/
et ajoutez le code suivant :
Le composant <PageManagerRequestsList />
affiche les demandes de congé en attente que les managers doivent approuver. Il montre des détails comme le nom de l’employé, le type de congé, les dates demandées et combien de temps s’est écoulé depuis la demande. Les managers peuvent cliquer sur une demande pour voir plus de détails. Il utilise <RequestsList />
et <RequestsListItem />
pour rendre la liste.
Ce composant accepte également children
comme prop. Ensuite, nous allons implémenter une route modale utilisant <Outlet />
pour afficher les détails de la demande, rendant la route /manager/requests/:id
à l’intérieur du composant.
Ajout de la route “/manager/requests”
Nous devons ajouter le nouveau chemin pour la page de gestion des demandes de congé. Mettons à jour le fichier App.tsx
pour inclure ce chemin :
Après avoir apporté ces modifications, vous pouvez naviguer vers le chemin /manager/requests
pour voir la page de gestion des demandes de congé en action

Création de la page des détails de la demande de congé
Dans cette étape, nous allons créer une nouvelle page pour afficher les détails d’une demande de congé. Cette page affichera le nom de l’employé, le type de congé, les dates demandées et l’état actuel. Les responsables peuvent approuver ou rejeter la demande depuis cette page.
Création du composant <TimeOffRequestModal />
Tout d’abord, créez un fichier appelé use-get-employee-time-off-usage
dans le dossier src/hooks/
et ajoutez le code suivant :
Nous utiliserons le hook useGetEmployeeTimeOffUsage
pour calculer le nombre total de jours qu’un employé a pris pour chaque type de congé. Cette information sera affichée dans la page des détails de la demande de congé.
Après cela, créez un nouveau fichier appelé time-off-request-modal.tsx
dans le dossier src/components/requests/
et ajoutez le code suivant :
Décomposons le composant <TimeOffRequestModal />
:
1. Récupération de l’utilisation des congés de l’employé
Le crochet useGetEmployeeTimeOffUsage
est utilisé pour récupérer l’utilisation des congés de l’employé. Ce crochet calcule les jours de congé annuel restants et les jours de congé maladie et décontracté précédemment utilisés en fonction de l’historique des congés de l’employé.
2. Récupération des congés approuvés qui se chevauchent
Le crochet useList
avec les filtres ci-dessus récupère tous les congés approuvés qui se chevauchent avec la demande de congé actuelle. Cette liste est utilisée pour afficher les employés absents entre les dates demandées.
3. Gestion de l’approbation/du rejet de la demande de congé
La fonction handleSubmit
est appelée lorsque le responsable approuve ou rejette la demande de congé.
Refine invalide automatiquement le cache des ressources après la mutation de la ressource (les congés
dans ce cas).
Étant donné que l’utilisation des congés de l’employé est calculée en fonction de l’historique des congés, nous invalidons également le cache de ressources des employés
pour mettre à jour l’utilisation des congés de l’employé.
Ajout de la route « /manager/requests/:id »
Dans cette étape, nous allons créer une nouvelle route pour afficher la page de détails de la demande de congé, où les responsables peuvent approuver ou rejeter les demandes.
Créons un nouveau fichier appelé edit.tsx
dans le dossier src/pages/manager/requests/time-offs/
et ajoutons le code suivant:
Maintenant, nous devons ajouter la nouvelle route pour afficher la page de détails de la demande de congé. Mettons à jour le fichier App.tsx
pour inclure cette route:
Jetons un coup d’œil de plus près aux changements:
Le code ci-dessus met en place une structure de routes imbriquées où un modal est affiché lors de la navigation vers une route enfant spécifique. Le composant <PageManagerRequestsTimeOffsEdit />
est un modal et est rendu en tant qu’enfant du composant <PageManagerRequestsList />
. Cette structure nous permet d’afficher le modal au-dessus de la page de liste tout en gardant la page de liste visible en arrière-plan.
Lorsque vous naviguez vers la route /manager/requests/:id/edit
ou cliquez sur une demande de congé dans la liste, la page de détails de la demande de congé sera affichée comme un modal au-dessus de la page de liste.

Étape 6 — Mise en œuvre de l’autorisation et du contrôle d’accès
L’autorisation est un élément critique dans les applications de niveau entreprise, jouant un rôle clé à la fois en matière de sécurité et d’efficacité opérationnelle. Elle garantit que seuls les utilisateurs autorisés peuvent accéder à des ressources spécifiques, protégeant ainsi les données sensibles et les fonctionnalités. Le système d’autorisation de Refine fournit l’infrastructure nécessaire pour protéger vos ressources et garantir que les utilisateurs interagissent avec votre application de manière sécurisée et contrôlée. Dans cette étape, nous mettrons en place l’autorisation et le contrôle d’accès pour la fonction de gestion des demandes d’absence. Nous restreindrons l’accès aux routes /manager/requests
et /manager/requests/:id/edit
aux seuls managers à l’aide du composant <CanAccess />
.
Actuellement, lorsque vous vous connectez en tant qu’employé, vous ne pouvez pas voir le lien de la page Demandes
dans la barre latérale, mais vous pouvez toujours accéder à la route /manager/requests
en tapant l’URL dans le navigateur. Nous ajouterons une protection pour empêcher l’accès non autorisé à ces routes.
Mettons à jour le fichier App.tsx
pour inclure les vérifications d’autorisation:
Dans le code ci-dessus, nous avons ajouté le composant <CanAccess />
à la route « /manager ». Ce composant vérifie si l’utilisateur a le rôle de « manager » avant de rendre les routes enfants. Si l’utilisateur n’a pas le rôle de « manager », il sera redirigé vers la page de liste des congés pour les employés.
Maintenant, lorsque vous vous connectez en tant qu’employé et que vous essayez d’accéder à la route /manager/requests
, vous serez redirigé vers la page de liste des congés pour les employés.
Étape 7 — Déploiement sur la plateforme d’application DigitalOcean
Dans cette étape, nous allons déployer l’application sur la plateforme d’application DigitalOcean. Pour ce faire, nous hébergerons le code source sur GitHub et connecterons le dépôt GitHub à la plateforme d’application.
Pousser le code sur GitHub
Connectez-vous à votre compte GitHub et créez un nouveau dépôt nommé refine-hr
. Vous pouvez rendre le dépôt public ou privé :
Après avoir créé le dépôt, naviguez dans le répertoire du projet et exécutez la commande suivante pour initialiser un nouveau dépôt Git :
Ensuite, ajoutez tous les fichiers au dépôt Git avec cette commande :
Puis, validez les fichiers avec cette commande :
Ensuite, ajoutez le dépôt GitHub comme dépôt distant avec cette commande :
Ensuite, spécifiez que vous souhaitez pousser votre code vers la branche main
avec cette commande :
Enfin, poussez le code vers le dépôt GitHub avec cette commande :
Lorsque vous y êtes invité, entrez vos identifiants GitHub pour pousser votre code.
Vous recevrez un message de succès après que le code a été poussé vers le dépôt GitHub.
Dans cette section, vous avez poussé votre projet sur GitHub afin de pouvoir y accéder en utilisant les Applications DigitalOcean. L’étape suivante consiste à créer une nouvelle Application DigitalOcean en utilisant votre projet et à configurer le déploiement automatique.
Déploiement sur la plateforme d’applications DigitalOcean
Dans ce processus, vous prendriez une application React et la prépareriez pour le déploiement via la plateforme d’applications de DigitalOcean. Vous lieriez votre dépôt GitHub à DigitalOcean, configureriez comment l’application sera construite, puis créeriez un déploiement initial d’un projet. Après le déploiement du projet, les modifications supplémentaires que vous apportez seront automatiquement reconstruites et mises à jour.
À la fin de cette étape, vous aurez votre application déployée sur DigitalOcean avec une livraison continue prévue.
Connectez-vous à votre compte DigitalOcean et accédez à la page Applications. Cliquez sur le bouton Créer une application :
Si vous n’avez pas connecté votre compte GitHub à DigitalOcean, vous serez invité à le faire. Cliquez sur le bouton Connecter à GitHub. Une nouvelle fenêtre s’ouvrira, vous demandant d’autoriser DigitalOcean à accéder à votre compte GitHub.
Après avoir autorisé DigitalOcean, vous serez redirigé vers la page des applications DigitalOcean. La prochaine étape consiste à sélectionner votre dépôt GitHub. Après avoir sélectionné votre dépôt, vous serez invité à choisir une branche à déployer. Sélectionnez la branche main
et cliquez sur le bouton Suivant.
Ensuite, vous verrez les étapes de configuration de votre application. Dans ce tutoriel, vous pouvez cliquer sur le bouton Suivant pour passer les étapes de configuration. Cependant, vous pouvez également configurer votre application comme vous le souhaitez.
Attendez que la construction soit terminée. Après la fin de la construction, appuyez sur Application en direct pour accéder à votre projet dans le navigateur. Il sera identique au projet testé localement, mais il sera accessible sur le web avec une URL sécurisée. De plus, vous pouvez suivre ce tutoriel disponible sur le site de la communauté DigitalOcean pour apprendre comment déployer des applications basées sur React sur la plateforme d’application.
Remarque : En cas d’échec du déploiement de la construction, vous pouvez configurer votre commande de construction sur DigitalOcean pour utiliser npm install --production=false && npm run build && npm prune --production
au lieu de npm run build
Conclusion
Dans ce tutoriel, nous avons construit une application de gestion des ressources humaines en utilisant Refine depuis le début et nous nous sommes familiarisés avec la façon de créer une application CRUD entièrement fonctionnelle.
De plus, nous allons démontrer comment déployer votre application sur la DigitalOcean App Platform.
Si vous souhaitez en savoir plus sur Refine, vous pouvez consulter la documentation et si vous avez des questions ou des retours, vous pouvez rejoindre le serveur Discord de Refine.