La nouvelle marque de cosmétique Tesnim avait un besoin vital de présence en ligne, notamment pour proposer ses produits et les vendre. Sa créatrice a fait appel à mes compétences, préférant partir sur une solution totalement personnalisée plutôt que d'utiliser un outil tel que Prestashop. J'ai naturellement saisi l'opportunité, y voyant un moyen de contribuer à un projet vraiment exigeant. En effet, ma cliente sait ce qu'elle veut: nous avons passé beaucoup de temps sur le maquettage de l'application afin de lui offrir un site qui reflète sa personnalité et l'esprit de sa marque - sobre, professionnel et simple d'utilisation.
Maquettage
J'ai réalisé les maquettes avec Figma, outil que je maîtrise désormais assez bien. J'ai tiré avantage des fonctions de générisation des objets, des couleurs et des designs pour refactorer rapidement lorsque ma cliente me faisait un retour, et j'ai designé toutes les différentes pages de l'application pour une vue desktop - je ne me suis pas occupé de la partie mobile, car premièrement je manquais de temps, et ensuite car nous en avions convenu avec ma cliente au préalable.
![Quelques écrans de mon fichier Figma (on voit les différents états du menu)](/_next/image?url=%2Fimg%2Fprojects%2Ftesnim%2Ffigma.png&w=3840&q=75)
Quelques écrans de mon fichier Figma (on voit les différents états du menu)
Une fois la palette de couleurs établie, je me suis inspiré de plusieurs identités existantes (par exemeple Sephora) afin que ma client puisse s'identifier rapidement à un monde qu'elle connaît déjà. Finalement, nous nous sommes arrêtés sur un nombre convenable de pages, et c'est à l'issue de ce processus que j'ai commencé le développement.
![Comment j'ai géré les tailles et couleurs du texte](/_next/image?url=%2Fimg%2Fprojects%2Ftesnim%2Ffigma2.png&w=3840&q=75)
Comment j'ai géré les tailles et couleurs du texte
Intégration frontend
En utilisant Next.js, j'ai développé l'ensemble des pages mockées afin de pouvoir me passer du backend pour cette première phase de réalisation. En effet, je n'avais pas envie de devoir gérer le front et le back en même temps, j'ai préféré dédier toutes mes capacités au pixel perfect et responsive, tâches qui se sont avérées assez ardues mais valorisantes une fois terminées. L'intégration d'une architecture hexagonale a largement facilité cette partie du travail !
![La page d'accueil du site marchand](/_next/image?url=%2Fimg%2Fprojects%2Ftesnim%2Fclient-home.png&w=3840&q=75)
La page d'accueil du site marchand
L'optimisation des rendus, le choix entre composant client/serveur et la mise en place de cette architecture hexagonale m'ont permis d'itérer rapidement et d'être serein quant à la TMA à venir de ce projet. Ma maîtrise de Next.js me permet d'envisager n'importe quel développement, et conjointement avec de simples fichiées SASS j'ai pu facilement tout intégrér. Hmm, facilement ? Non, une irréductible fonctionnalité persiste contre le développeur, et elle se nomme Menu...
![Le fameux petit menu](/_next/image?url=%2Fimg%2Fprojects%2Ftesnim%2Fclient-menu.png&w=3840&q=75)
Le fameux petit menu
En effet, j'ai éprouvé beaucoup de difficulté pour réaliser ce petit sous-menu et l'adapter à tous les cas d'utilisation (petit écran, smartphone...). Il fallait qu'il se comporte correctement jusqu'à trois niveaux de profondeur, et tout faire soi-même n'est évidemment pas chose aisée. J'ai perdu plusieurs jours là-dessus, néanmoins je n'appellerais pas ça perdre du temps car j'en ressors toujours plus expérimenté.
C'est ce que j'aime avec l'informatique: on nous dira toujours de ne pas réinventer la roue et je suis d'accord 90% du temps, mais parfois il est bon de se confronter à des défis et oser les surmonter. C'est ce qui forge une certaine excellence technique après tout !
![Liste des produits disponible dans l'application](/_next/image?url=%2Fimg%2Fprojects%2Ftesnim%2Fclient-products.png&w=3840&q=75)
Liste des produits disponible dans l'application
Next.js offre une technologie native pour gérer les images en les redimensionant dynamiquement, optimisant ainsi les chargements des pages. Or, cette technologie impose des contraintes difficilement conciliables avec une exigence pixel perfect / responsive; aussi, j'ai développé une surcouche permettant de profiter de cette optimisation tout en offrant un confort DX encore inégalé dans mon workflow. J'ai tellement apprécié que je l'ai reproduit sur certains de mes autres sites !
![Page dédiée à un produit en particulier](/_next/image?url=%2Fimg%2Fprojects%2Ftesnim%2Fclient-product.png&w=3840&q=75)
Page dédiée à un produit en particulier
![Formulaire de paiement, réalisé par moi-même et qui redirige vers une page Stripe](/_next/image?url=%2Fimg%2Fprojects%2Ftesnim%2Fclient-checkout.png&w=3840&q=75)
Formulaire de paiement, réalisé par moi-même et qui redirige vers une page Stripe
Finalement, pour tout ce qui est accessibilité et composants UX, j'ai opté pour Shadcn pour éviter de réinventer la roue et profiter d'une esthétique adaptable. Le seul défaut est la dépendance à TailwindCSS, qui je dois l'avouer ne me plaît plus (je l'ai longtemps utilisé, mais m'en suis détourné depuis un certain temps maintenant car j'abhore sa DX). Toutefois, j'ai réussi à lier les couleurs de ces composants à ma manière de gérer le thème de couleurs, centralisé dans un seul fichier SCSS et partagé à l'ensemble de l'application. Simple et intuitif, je ne regrette pas mon choix.
Place au backend
Je savais qu'une fois le front terminé, la quantité de travail restant serait considérablement réduite: en effet, connaissant par cœur Strapi, j'ai intégré en deux jours les fonctionnalités back puis connecté les deux parties du site pour obtenir une application fonctionnelle.
![Une des pages principales de l'application Strapi](/_next/image?url=%2Fimg%2Fprojects%2Ftesnim%2Fstrapi.png&w=3840&q=75)
Une des pages principales de l'application Strapi
Grâce à Strapi et sa nouvelle version 5, je gère la connexion utilisateur, le stockage des données, les processus automatisés (webhook Stripe, envoi de mails personnalisés...) et je peux offrir une interface digne de ce nom à ma cliente pour qu'elle puisse gérer le contenu de son site sans avoir à faire appel à moi.
À chaque fois que j'utilise Strapi, je surcharge son algorithme de connexion pour l'améliorer en termes de sécurité: en effet par défaut Strapi renvoie les access et refresh token en JSON et s'attend à ce que nous les stockions côté frontend, par exemple en local storage. Diantre, quelle immondice... Ce n'est pas du tout sécurisé ! Aussi, je l'ai amélioré pour qu'il renvoie ces données dans un cookie httpOnly, ce qui évite d'avoir à le stocker côté client et lisse les échanges pour une DX plus agréable (manipuler le local storage est simple mais couplé à du Typescript cela commence à complexifier les choses).
![Création d'un enregistrement dans Strapi](/_next/image?url=%2Fimg%2Fprojects%2Ftesnim%2Fstrapi-record.png&w=3840&q=75)
Création d'un enregistrement dans Strapi
Côté front, je valide toujours les données qui proviennent du back grâce à la petite librairie zod: cela me permet de détecter immédiatement un problème de données, et d'être certain que les données que je reçois sont celles auxquelles je m'attends. Plus de problème au runtime !
Finalement, j'ai offert à ma cliente un backoffice pour qu'elle gère elle-même ses données, mais je n'ai pas souhaité lui laisser un accès complet à toute l'application: j'ai mis en place des règles RBAC pour ne lui laisser accéder qu'aux rubriques utiles pour elles, afin qu'elle n'empiète pas sur tout le travail que j'ai accompli précédemment. Merci Strapi d'avoir passé ces règles dans le free tier !
![Gestion des règles RBAC dans Strapi](/_next/image?url=%2Fimg%2Fprojects%2Ftesnim%2Fstrapi-rbac.png&w=3840&q=75)
Gestion des règles RBAC dans Strapi
Pour ce projet, j'ai développé deux librairies publiée sur NPM:
- Une première offrant une surcouche pour les interactions avec l'API de Mondial Relay.
- Une seconde me permettant d'envoyer des mails avec Gmail de manière simplifiée.
Je suis fier de proposer mes première librairies 🎉
Déploiement
J'ai l'habitude de déployer des projets web, aussi j'ai opté pour Docker et son outil compose: en hostant sur un VPS, je peux monitorer et déployer très simplement grâce à ma CI/CD mise en place dans Gitlab. À un simple push sur la branche master, le site se redéploie automatiquement; quel plaisir à utiliser ✨
Durant la phase de déploiement de ce projet, je me suis décidé à migrer mes déploiements du cloud vers un serveur personnel que je monterai dans les prochains mois. Vous aurez certainement tendance à me dire que je me complique la vie pour rien (maintenance du hardware, mise en place des technologies, monitoring, scaling, résilience, sécurité etc...), et à ceci je vous répondrai: c'est bien le but ! Je suis un passionné qui cherche à maîtriser petit à petit toute la chaîne de développement, aussi aborder le domaine infrastructurel et le métier d'admin système me paraît tout à fait judicieux, après toutes ces années passées à maîtriser les technologies du web.
Aussi, attendez-vous à voir mentionnée l'évolution de ce projet, qui n'est autre que la mise en place d'un cluster Raspberry PI dans un DMZ hosté chez moi, protégé le plus efficacement possible grâce aux conseils de mon ami Nicolas expert en cybersécurité, pour faire tourner un cluster Kubernetes à même d'héberger toutes les applications web que je souhaite (personnelles comme professionnelles). Sécurité, déploiement et sauvegarde des données seront mes prochains chevaux de bataille, mais je suis très excité à l'idée de monter au créneau !
Conclusion
Développer une plateforme marchande de zéro est toujours un défi: technique, mais aussi fonctionnel puisque je dois entrer dans le monde de ma cliente et le traduire correctement pour concrétiser ses idées. J'aime toucher à tous ces aspects du web, et la satisfaction totale de ma cliente aura été ma plus grande récompense (mise à part ma rémunération lol). À bientôt pour de nouvelles aventures 🎉