From a597d2dae8664dce03f3e0280c20c73bbcfbf2be Mon Sep 17 00:00:00 2001 From: Hugues <hugues@lydra.fr> Date: Thu, 29 Jul 2021 13:26:54 +0000 Subject: [PATCH] feat: add features componet and documentation --- README.md | 35 ++++ doc/sections.md | 181 +++++++++++++++++++++ docusaurus.config.js | 2 +- src/components/HomepageFeatures.js | 55 ++++--- src/components/HomepageFeatures.module.css | 27 ++- src/components/HomepagePromises.js | 62 +++++++ src/components/HomepagePromises.module.css | 6 + src/css/custom.css | 7 + src/pages/index.js | 4 +- 9 files changed, 348 insertions(+), 31 deletions(-) create mode 100644 doc/sections.md create mode 100644 src/components/HomepagePromises.js create mode 100644 src/components/HomepagePromises.module.css diff --git a/README.md b/README.md index 4abc191..c295f12 100644 --- a/README.md +++ b/README.md @@ -35,3 +35,38 @@ If you are using GitHub pages for hosting, this command is a convenient way to b ## Create a new page [Follow this doc](doc/pages.md). + +## Create a new section + +[Follow this doc](doc/sections.md). + +## Three structure + +``` +├── babel.config.js // contains configurations to Babel, a JavaScript compiler +├── blog // contains the blog Markdown files. +├── doc // contains the Markdown files for the Froggit docs. +├── docs // contains the Markdown files for the docs. +├── docusaurus.config.js // a config file containing the site configuration. +├── package.json // a Docusaurus website is a React app. You can install and use any npm packages +├── README.md +├── sidebars.js // used to specify the order of documentations in the sidebar +├── src // non-documentation files like pages or custom React components +│  ├── components // contains React reusable Components and it's CSS modules +│  ├── css // global CSS +│  └── pages // pages Components +├── static // static directory +│  └── img // images folder +│ +``` + +More details on Project structure: + +* `/blog/` - You can delete the directory if you do not want/need a blog. More details can be found in the [blog guide](https://docusaurus.io/docs/blog) +* `/docs/` - Customize the order in sidebars.js. More details can be found in the [docs guide](https://docusaurus.io/docs/docs-markdown-features) +* `/src/` - You don't have to strictly put your non-documentation files in here but putting them under a centralized directory makes it easier to specify in case you need to do some sort of linting/processing + * `/src/pages` - More details can be found in the [pages guide](https://docusaurus.io/docs/creating-pages) +* `/static/` - Any contents inside here will be copied into the root of the final `build` directory +* `/docusaurus.config.js` - This is the equivalent of `siteConfig.js` in Docusaurus v1 + + diff --git a/doc/sections.md b/doc/sections.md new file mode 100644 index 0000000..dbc4318 --- /dev/null +++ b/doc/sections.md @@ -0,0 +1,181 @@ +# Créer des sections + +Docusaurus étant un Framework de la librairie React, on y retrouve la même logique. + +L'affichage d'une page web est un ensemble de composants réutilisables, que l'on peux assembler. + +Nous allons nous appuyer sur l'utilisation de ces Composants pour créer nos différentes sections d'affichage, notamment pour gérer le rendu visuel de la page d'accueil du site `index.js`. + +Chaque section de pages va être définie dans un Composant enfant dans le dossier `./src/components/`, puis importée dans un Composant parent dans le dossier `./src/pages/`. + +Un composant (_Componant_) contient: des données qui constituent un état (_state_), des comportements et un rendu (l'affichage), ces trois notions vont interagir entre elles. + +## Création du composant + +Pour l'exemple, nous allons expliquer comment nous avons créer la section chargée d'afficher les fonctionnalités (_Features_) de Froggit. + +Dans le dossier `src/components/`, nous avons créé un fichier React `HomepageFeatures.js`. + + +Nous avons choisi de nommer notre fichier `HomepageFeatures`, en [PascalCase](https://techlib.fr/definition/pascalcase.html), car ce composent est destiné à être affiché, dans la `Homepage` (page d'Accueil) et doit afficher les `Features` (fonctionnalités) de Froggit. + +Ce fichier est composé de 3 parties: + + +- une pour gérer les données de notre section ; +- une pour définir les comportements que nous attendons en utilisant différentes fonctions ; +- une pour définir l'affichage. Nous utilisons le JSX pour cette partie, voir l' [introduction au JSX](https://fr.reactjs.org/docs/introducing-jsx.html) sur la doc de React pour des explications sur cette extension syntaxique du JavaScript. + +### Les données de notre section + +Nous allons créer un tableau d'objets JavaScript pour définir les données à afficher dans notre section. Il y a 3 objets pour chaque élément du tableau : +1. Un titre, de type `chaîne de charactère` (_String_), donc entouré de guillements simples `'` ou doubles `"`). +2. Une description, que nous définissons en tant qu' `Element JSX`. Nous pouvons ainsi lui donner un _template_ de rendu comme valeur, avec les balises HTML de notre choix, juste un paragraphe dans notre cas. Pour cela, nous devons définir sa valeur entre des parenthèses et à l'intérieur d' une balise parent, pouvant être une `div`, ou comme nous utilisons ci-dessous, avec une simple balise vide. +3. Une image, que nous définissons en tant que `Composant React`, afin de simplifier la syntaxe de notre code dans les prochaines étapes notemment pour définir notre affichage. Comme cette image est un composant, nous la nommons `Svg` en PascalCase. +Enfin, nous utilisons ici le format `SVG`, mais nous pouvons utiliser d'autres formats tels que le `PNG`, `GIF` et `JPG`. Mais dans ce cas il faudra installer le plugin officiel de gestion d' [images](https://docusaurus.io/fr/docs/api/plugins/@docusaurus/plugin-ideal-image) pour les formats `PNG` ou `JPG`. + +Nous appelons notre tableau `featuresList` car c'est la liste des fonctionnalités. + +```jsx +const FeatureList = [ + { + title: "1. Le Lab 🧪", + Svg: require("../../static/img/logo_froggit.svg").default, + description: ( + <> + <p>Le laboratoire vous permet d’héberger votre code et de collaborer dessus avec Git. C'est plus qu'un serveur Git puisque vous pouvez gérer un projet complet dessus. Le Lab est le cÅ“ur de Froggit et il sert aussi de base centrale pour l’authentification unique (SSO) des autres services.</p> + </> + ), + }, + { + title: "2. La CI ðŸ”", + Svg: require("../../static/img/logo_froggit.svg").default, + description: ( + <> + <p>Fournir un outil de collaboration de code sans Intégration Continue n'était pas pensable pour nous. C'est pour cela que nous avons mis en place une CI avec un serveur et un débordement élastique dans Kubernetes.</p> + </> + ), + }, + { + title: "3. Le Chat 💬", + Svg: require("../../static/img/logo_froggit.svg").default, + description: ( + <> + <p>Pour collaborer les équipes ont besoin de communiquer. Qu'elles soient physiquement au même endroit ou non une communication asynchrone est importante. C'est pour cela que Froggit inclut un chat avec le service. Vous pourrez même faire remonter vos alertes et messages venant du Lab. L'authentification se fera grâce au Lab, vous n'aurez qu'un seul compte pour tous les services de Froggit. Vous pourrez abandonner Slack sans crainte !</p> + </> + ), + }, + { + title: "4. Les Pages 🔖", + Svg: require("../../static/img/logo_froggit.svg").default, + description: ( + <> + <p>Vous avez besoin de créer des sites statiques pour vos documentations. C'est pour cela que nous mettons en place les GitLab pages qui vous permettent d'héberger des sites statiques.</p> + </> + ), + }, +]; +``` +Notre section affichera les 4 éléments, chacune avec un titre, une description et une image en Svg. + + +### Affichage + +Il faut maintenant définir l'affichage que nous souhaitons que ce composant renvoie. + +Nous avons créé une fonction qui renvoie le rendu, grâce à un _template_. + +L'utilisation du JSX simplifie cette tâche, nous avons trois parties qui sont les clés issues de notre tableau à afficher. + +Tous élément JavaScript doit alors être affiché entre accolade: `{---}` afin d'être correctement interprété. + +Notre affichage doit impérativement être entouré de balises parents, telle une `div`. + +Nous passons comme argument les clés de notre tableau (Svg, title, description) à notre fonction + +```jsx +function Features({Svg, title, description}) { + return ( + <div className={"container"}> + <Svg alt={title} /> + </div> + <div> + <h3>{title}</h3> + <p>{description}</p> + </div> + </div> + ); +} +``` + +Ainsi, notre composant va renvoyer notre Svg en image, le titre en `h3` et la description en paragraphe. + +### Réutilisation du composant + +Nous devons également importer certains utilitaires, selon nos besoins (la librairie React, les modules CSS), puis exporter notre composant, pour qu'il puisse être réutilisé. +Il est nécessaire d'utiliser le système d'import/export de [modules JavaScript](https://javascript.info/import-export). + + +### Définition des Comportements + +Nous itérons sur chaque élément de notre tableau, en utilisant la méthode JavaScript `.map`, qui est très souvent utilisé dans les Composants React. + +La méthode map() crée un nouveau tableau avec les résultats de chaque élément du tableau. [Voici un tutoriel expliquant cette méthode](https://www.freecodecamp.org/news/javascript-map-how-to-use-the-js-map-function-array-method/). + +``` +export default function HomepageFeatures() { + return ( + <div> + {FeaturesList.map((props, idx) => ( + <Features key={idx} {...props} /> + ))} + </div> + ); +} +``` + +Nous utilisons grâce à une `fonction fléchée`, une fonction de _Callback_ pour boucler sur notre tableau, qui prend 2 paramètres, les `props` qui représentent les valeurs du tableau, et `idx`, les clés. les `...` est un [Spread Operator](https://www.techiediaries.com/react-spread-operator-props-setstate/). + +Notre Composant `HomepageFeatures` est également exporté au début de la déclaration de la fonction avec `export default`. + +## Utilisation du composant + +Nous pouvons désormais utiliser notre composant dans un composant parent. + +Dans notre cas, ce composant parent est la page d'accueil du site `src/pages/index.js`. + +Il suffit d'importer notre composant enfant, que nous venons de créer, et de le mettre, comme une balise, dans la partie `return` de la fonction `Home`. La fonction `Home` retourne la vue de notre page : + +```jsx +import React from "react"; +import HomepagePromises from "../components/HomepagePromises"; +import HomepageFeatures from "../components/HomepageFeatures"; + +// (...) + +export default function Home() { + return ( + <Layout> + <HomepageHeader /> + <main> + <HomepagePromises /> + <HomepageFeatures /> + </main> + </Layout> + ); +} +``` + +Entre nos balises `Layout`, nous retrouvons 3 composants enfants, d'abord l'entête (_header_) nommé <HomepageHeader /> qui a été créé à l'intérieur même de ce composant. + +Puis nous retrouvons 2 Composants, qui ont été importé depuis le dossier `src/components/`: +1. <HomepagePromises />, pour la section des promesses +2. <HomepageFeatures />, pour la section des fonctionnalités + +## Feuille de style CSS + +Un Composant peut avoir sa propre feuille de style CSS. Nous donnons le même nom que le fichier de composant au fichier CSS suivi du suffixe `.module.css`. + +Un composant peut également utiliser la feuille de style générale `custom.css`. Ce fichier regroupe les attributs de styles standard commun à tous le site. + +Chaque feuille de style que l'on souhaite utiliser doit être importé dans le Composant. diff --git a/docusaurus.config.js b/docusaurus.config.js index a28a6b4..06723cc 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -20,7 +20,7 @@ module.exports = { src: "img/logo_froggit.svg", }, items: [ - {to: "/dummy_page", label: "Fonctionnalités", position: "left"}, + {to: "/#features", label: "Fonctionnalités", position: "left"}, {to: "/faq", label: "FAQ", position: "left"}, {to: "/dummy_page", label: "Tarifs", position: "left"}, {to: "/blog", label: "Blog", position: "left"}, diff --git a/src/components/HomepageFeatures.js b/src/components/HomepageFeatures.js index bb82efc..5f45f28 100644 --- a/src/components/HomepageFeatures.js +++ b/src/components/HomepageFeatures.js @@ -4,46 +4,51 @@ import styles from "./HomepageFeatures.module.css"; const FeatureList = [ { - title: "Sûr", - // eslint-disable-next-line - Svg: require("../../static/img/bouclier.svg").default, + title: "1. Le Lab 🧪", + Svg: require("../../static/img/logo_froggit.svg").default, description: ( <> - <p>Vos données sont en lieu sûr et sauvegardées toutes les nuits.</p> + <p>Le laboratoire vous permet d’héberger votre code et de collaborer dessus avec Git. C'est plus qu'un serveur Git puisque vous pouvez gérer un projet complet dessus. Le Lab est le cÅ“ur de Froggit et il sert aussi de base centrale pour l’authentification unique (SSO) des autres services.</p> </> - ), + ), + }, + { + title: "2. La CI ðŸ”", + Svg: require("../../static/img/logo_froggit.svg").default, + description: ( + <> + <p>Fournir un outil de collaboration de code sans Intégration Continue n'était pas pensable pour nous. C'est pour cela que nous avons mis en place une CI avec un serveur et un débordement élastique dans Kubernetes.</p> + </> + ), }, { - title: "Souverain", - // eslint-disable-next-line - Svg: require("../../static/img/rgpd.svg").default, + title: "3. Le Chat 💬", + Svg: require("../../static/img/logo_froggit.svg").default, description: ( <> - <p>Nous sommes hébergés en France et conformes au RGPD.</p> + <p>Pour collaborer les équipes ont besoin de communiquer. Qu'elles soient physiquement au même endroit ou non une communication asynchrone est importante. C'est pour cela que Froggit inclut un chat avec le service. Vous pourrez même faire remonter vos alertes et messages venant du Lab. L'authentification se fera grâce au Lab, vous n'aurez qu'un seul compte pour tous les services de Froggit. Vous pourrez abandonner Slack sans crainte !</p> </> ), }, { - // eslint-disable-next-line - title: "Libre", - // eslint-disable-next-line - Svg: require("../../static/img/liberte.svg").default, + title: "4. Les Pages 🔖", + Svg: require("../../static/img/logo_froggit.svg").default, description: ( <> - <p>Notre solution s'appuie sur des logiciels libres et nos conditions générales sont éthiques.</p> + <p>Vous avez besoin de créer des sites statiques pour vos documentations. C'est pour cela que nous mettons en place les GitLab pages qui vous permettent d'héberger des sites statiques.</p> </> ), }, -]; +]; // eslint-disable-next-line function Feature({Svg, title, description}) { return ( - <div className={clsx("col col--4")}> - <div className="text--center"> - <Svg className={styles.featureSvg} alt={title} /> + <div className={clsx("hero hero--primary text--center padding-horiz--md", styles.featureContainer)}> + <div className={styles.featureSvg}> + <Svg className={styles.svg} alt={title} /> </div> - <div className="text--center padding-horiz--md"> + <div className={styles.featureText}> <h3>{title}</h3> <p>{description}</p> </div> @@ -53,13 +58,11 @@ function Feature({Svg, title, description}) { export default function HomepageFeatures() { return ( - <section className={styles.features}> - <div className="container"> - <div className="row"> - {FeatureList.map((props, idx) => ( - <Feature key={idx} {...props} /> - ))} - </div> + <section className="sections"> + <div id="features"> + {FeatureList.map((props, idx) => ( + <Feature key={idx} {...props} /> + ))} </div> </section> ); diff --git a/src/components/HomepageFeatures.module.css b/src/components/HomepageFeatures.module.css index 611856a..0042bd4 100644 --- a/src/components/HomepageFeatures.module.css +++ b/src/components/HomepageFeatures.module.css @@ -7,7 +7,28 @@ width: 100%; } -.featureSvg { - height: 150px; - width: 150px; +.svg { + height: 175px; + width: 175px; +} + +.featureContainer { + min-height: 200px; + padding: 2.5rem 0; + margin-bottom: -1px; + border-top: 1px solid rgb(238, 238, 238); + border-bottom: 1px solid rgb(238, 238, 238); + flex-direction: row; +} + +.featureContainer > .featureSvg { + width: 50%; + flex-shrink: 1; + text-align: center; +} + +.featureText { + padding-right: 20px; + width: 60%; + flex-shrink: 0; } diff --git a/src/components/HomepagePromises.js b/src/components/HomepagePromises.js new file mode 100644 index 0000000..c63bc29 --- /dev/null +++ b/src/components/HomepagePromises.js @@ -0,0 +1,62 @@ +import React from "react"; +import clsx from "clsx"; +import styles from "./HomepagePromises.module.css"; + +const PromiseList = [ + { + title: "Sûr", + Svg: require("../../static/img/bouclier.svg").default, + description: ( + <> + <p>Vos données sont en lieu sûr et sauvegardées toutes les nuits.</p> + </> + ), + }, + { + title: "Souverain", + Svg: require("../../static/img/rgpd.svg").default, + description: ( + <> + <p>Nous sommes hébergés en France et conformes au RGPD.</p> + </> + ), + }, + { + title: "Libre", + Svg: require("../../static/img/liberte.svg").default, + description: ( + <> + <p>Notre solution s'appuie sur des logiciels libres et nos conditions générales sont éthiques.</p> + </> + ), + }, +]; + +// eslint-disable-next-line +function Promise({Svg, title, description}) { + return ( + <div className={clsx("col col--4")}> + <div className="text--center"> + <Svg className={styles.promiseSvg} alt={title} /> + </div> + <div className="text--center padding-horiz--md"> + <h3>{title}</h3> + <p>{description}</p> + </div> + </div> + ); +} + +export default function HomepagePromises() { + return ( + <section className="sections"> + <div className="container"> + <div className="row"> + {PromiseList.map((props, idx) => ( + <Promise key={idx} {...props} /> + ))} + </div> + </div> + </section> + ); +} diff --git a/src/components/HomepagePromises.module.css b/src/components/HomepagePromises.module.css new file mode 100644 index 0000000..cc8102f --- /dev/null +++ b/src/components/HomepagePromises.module.css @@ -0,0 +1,6 @@ +/* stylelint-disable docusaurus/copyright-header */ + +.promiseSvg { + height: 150px; + width: 150px; +} diff --git a/src/css/custom.css b/src/css/custom.css index b3d3c3c..0c565c3 100644 --- a/src/css/custom.css +++ b/src/css/custom.css @@ -27,3 +27,10 @@ html[data-theme='dark'] .docusaurus-highlight-code-line { background-color: rgba(0, 0, 0, 0.3); } + +.sections { + display: flex; + align-items: center; + padding: 2rem 0; + width: 100%; +} diff --git a/src/pages/index.js b/src/pages/index.js index 3be0f9c..aa1da7c 100644 --- a/src/pages/index.js +++ b/src/pages/index.js @@ -3,6 +3,7 @@ import clsx from "clsx"; import Layout from "@theme/Layout"; import useDocusaurusContext from "@docusaurus/useDocusaurusContext"; import styles from "./index.module.css"; +import HomepagePromises from "../components/HomepagePromises"; import HomepageFeatures from "../components/HomepageFeatures"; function HomepageHeader() { @@ -10,7 +11,7 @@ function HomepageHeader() { return ( <header className={clsx("hero hero--primary", styles.heroBanner)}> <div className="container"> - <h1 className="hero__subtitle">{siteConfig.tagline}</h1> + <h1 className="hero__subtitle">{siteConfig.tagline}</h1> </div> </header> ); @@ -25,6 +26,7 @@ export default function Home() { > <HomepageHeader /> <main> + <HomepagePromises /> <HomepageFeatures /> </main> </Layout> -- GitLab