{title}
+{description}
} +{definition.label}
+{definition.mode}
diff --git a/DESIGN_SYSTEM.md b/DESIGN_SYSTEM.md index cdcaf58..f8c3d66 100644 --- a/DESIGN_SYSTEM.md +++ b/DESIGN_SYSTEM.md @@ -267,7 +267,26 @@ Style courant : - pas de hover sur les panneaux de lecture ; - implementation via le mixin `gold-panel-frame` dans `website/src/styles/_mixins.scss`. -## 10. Boutons +## 10. Catalogue Documentation + +La page catalogue des outils utilise un layout de documentation. + +Regles : + +- hero court, puis contenu principal en deux colonnes sur desktop ; +- sommaire a gauche en panneau sticky, avec categories puis liens d'outils de la categorie active ; +- une seule categorie d'usage est affichee a droite a la fois ; +- la categorie active commence par un mini-hero descriptif, sans compteur decoratif ; +- chaque fiche commence par le titre, l'icone, le badge de categorie et une description directe de l'outil ; +- l'exemple interactif reste visible en permanence et centre horizontalement ; +- les reperes de boutons propres a l'outil sont places a gauche de l'exemple, puis empiles au-dessus sur mobile ; +- les reperes sont groupes par categorie de controles de l'outil, avec apercu visuel du bouton et label court ; +- les descriptions de reperes sont reservees aux comportements non evidents, par exemple un bouton qui agit sur toute la ligne ou une action de drag & drop ; +- les fonctionnalites detaillees et formats d'import texte sont presentes sous l'exemple dans un panneau repliable pour ne pas alourdir la lecture avant manipulation ; +- les controles propres au catalogue, comme la reinitialisation d'une demo, ne sont pas documentes comme fonctionnalites de l'outil ; +- sur mobile, le sommaire devient un bloc normal place avant les fiches, sans position sticky. + +## 11. Boutons ### Primary diff --git a/tests/helpers/data-validation.mjs b/tests/helpers/data-validation.mjs index a039c9b..ed24898 100644 --- a/tests/helpers/data-validation.mjs +++ b/tests/helpers/data-validation.mjs @@ -53,8 +53,22 @@ export function validateSiteContent(site) { "library.summaryLabel", "library.tocLabel", "library.tocTitle", + "library.docTocTitle", "library.tocDescription", "library.toolsLabel", + "library.categoryLabel", + "library.featureHeading", + "library.controlLegendHeading", + "library.categories.notesTracking", + "library.categories.references", + "library.categories.calculationData", + "library.categories.timeRoutines", + "library.categories.buildsCommands", + "library.categoryDescriptions.notesTracking", + "library.categoryDescriptions.references", + "library.categoryDescriptions.calculationData", + "library.categoryDescriptions.timeRoutines", + "library.categoryDescriptions.buildsCommands", "home.hero.eyebrow", "home.hero.title", "home.hero.description", @@ -442,6 +456,45 @@ export function validateSiteContent(site) { assert.equal(typeof item, "object", `library.summaryItems[${index}] must be an object`); }); + const libraryToolDocs = valueAt(site, "library.toolDocs"); + ["notepad", "checklist", "counters", "images", "imageAnnotation", "links", "calculator", "table", "timer", "taskPlanner", "combos", "equipmentPlanner"].forEach((toolType) => { + const docs = libraryToolDocs?.[toolType]; + assert.equal(typeof docs, "object", `library.toolDocs.${toolType} must be an object`); + assert.ok(Array.isArray(docs.controls), `library.toolDocs.${toolType}.controls must be an array`); + assert.ok(docs.controls.length >= 1, `library.toolDocs.${toolType}.controls must not be empty`); + docs.controls.forEach((control, index) => { + assert.equal(typeof control, "object", `library.toolDocs.${toolType}.controls[${index}] must be an object`); + assertNonEmptyString({ control }, "control.group"); + assertNonEmptyString({ control }, "control.icon"); + assertNonEmptyString({ control }, "control.title"); + if (control.text) assertNonEmptyString({ control }, "control.text"); + if (control.preview) { + assert.equal(typeof control.preview, "object", `library.toolDocs.${toolType}.controls[${index}].preview must be an object`); + assertNonEmptyString({ preview: control.preview }, "preview.kind"); + } + }); + assert.ok(Array.isArray(docs.features), `library.toolDocs.${toolType}.features must be an array`); + assert.ok(docs.features.length >= 1, `library.toolDocs.${toolType}.features must not be empty`); + docs.features.forEach((feature, index) => { + assertNonEmptyString({ feature }, "feature.title"); + assertNonEmptyString({ feature }, "feature.text"); + assert.equal(typeof feature, "object", `library.toolDocs.${toolType}.features[${index}] must be an object`); + if (feature.details) { + assert.ok(Array.isArray(feature.details), `library.toolDocs.${toolType}.features[${index}].details must be an array`); + assert.ok(feature.details.length >= 1, `library.toolDocs.${toolType}.features[${index}].details must not be empty`); + feature.details.forEach((detail, detailIndex) => { + assert.equal(typeof detail, "string", `library.toolDocs.${toolType}.features[${index}].details[${detailIndex}] must be a string`); + assert.ok(detail.trim(), `library.toolDocs.${toolType}.features[${index}].details[${detailIndex}] must not be empty`); + }); + } + }); + if (docs.importFormat) { + assertNonEmptyString({ importFormat: docs.importFormat }, "importFormat.title"); + assertNonEmptyString({ importFormat: docs.importFormat }, "importFormat.text"); + assertNonEmptyString({ importFormat: docs.importFormat }, "importFormat.example"); + } + }); + const aboutLimits = valueAt(site, "about.limits"); assert.ok(Array.isArray(aboutLimits), "about.limits must be an array"); assert.ok(aboutLimits.length >= 3, "about.limits must contain at least 3 items"); diff --git a/website/public/data/site.json b/website/public/data/site.json index 7c69651..a104738 100644 --- a/website/public/data/site.json +++ b/website/public/data/site.json @@ -36,8 +36,1079 @@ "summaryLabel": "Repères de la librairie", "tocLabel": "Sommaire des outils", "tocTitle": "Sommaire", + "docTocTitle": "Catalogue des outils", "tocDescription": "Accédez directement à un exemple d’outil dans la page.", "toolsLabel": "Exemples d'outils disponibles", + "categoryLabel": "Usage", + "featureHeading": "Fonctionnalités détaillées", + "controlLegendHeading": "Repères", + "categories": { + "notesTracking": "Notes & suivi", + "references": "Références", + "calculationData": "Calcul & données", + "timeRoutines": "Temps & routines", + "buildsCommands": "Builds & commandes" + }, + "categoryDescriptions": { + "notesTracking": "Les outils pour noter rapidement une information, suivre des objectifs et garder un état de session lisible.", + "references": "Les outils pour centraliser cartes, captures, images annotées et liens externes utiles pendant une partie.", + "calculationData": "Les outils pour manipuler des valeurs, comparer des données et structurer des informations en tableau.", + "timeRoutines": "Les outils pour gérer les temps de session, les resets, les tâches récurrentes et les routines quotidiennes ou hebdomadaires.", + "buildsCommands": "Les outils pour documenter des builds, organiser des équipements et conserver des séquences de commandes." + }, + "toolDocs": { + "notepad": { + "controls": [ + { + "group": "Édition de texte", + "icon": "edit", + "title": "Styles de texte", + "preview": { + "kind": "textFormats" + } + }, + { + "group": "Édition de texte", + "icon": "edit", + "title": "Titre", + "text": "S’applique a toute la ligne courante.", + "preview": { + "kind": "textButton", + "label": "T" + } + }, + { + "group": "Édition de texte", + "icon": "dropdown", + "title": "Liste à puces / Liste numérotée", + "preview": { + "kind": "listDropdown" + } + }, + { + "group": "Édition de texte", + "icon": "dropdown", + "title": "Couleur / surlignage", + "preview": { + "kind": "color" + } + }, + { + "group": "Dessin", + "icon": "edit", + "title": "Dessiner", + "preview": { + "kind": "iconButton", + "icon": "edit" + } + }, + { + "group": "Dessin", + "icon": "rubber", + "title": "Gommer", + "preview": { + "kind": "iconButton", + "icon": "rubber" + } + }, + { + "group": "Dessin", + "icon": "dropdown", + "title": "Couleur du trait", + "preview": { + "kind": "color" + } + }, + { + "group": "Dessin", + "icon": "dropdown", + "title": "Épaisseur du trait", + "preview": { + "kind": "drawingWidth", + "width": 4 + } + }, + { + "group": "Dessin", + "icon": "back", + "title": "Annuler le dernier trait", + "preview": { + "kind": "iconButton", + "icon": "back" + } + }, + { + "group": "Dessin", + "icon": "trash", + "title": "Effacer les dessins", + "preview": { + "kind": "iconButton", + "icon": "trash", + "danger": true + } + }, + { + "group": "Dessin", + "icon": "save", + "title": "Sauvegarde du dessin", + "preview": { + "kind": "switch", + "icon": "save", + "active": true + } + } + ], + "features": [ + { + "title": "Mise en page de texte", + "text": "Rédaction riche avec gras, italique, souligné, barré, titres, listes à puces, listes numérotées, couleurs de texte et surlignage.", + "details": [ + "Les boutons de mise en forme agissent sur le texte sélectionné ou sur le mot en cours de saisie.", + "Le menu listes regroupe les listes simples et numérotées pour éviter d'avoir deux boutons permanents.", + "Les couleurs de texte et de surlignage sont séparées pour distinguer une information importante d'un simple repère visuel." + ] + }, + { + "title": "Dessin manuel", + "text": "Ajout de traits au-dessus de la note, avec couleur, épaisseur, gomme, annulation et mode temporaire ou permanent.", + "details": [ + "Le mode dessin place un calque transparent au-dessus de la note sans remplacer le texte.", + "La gomme retire les traits dessinés, tandis que l'annulation retire le dernier tracé.", + "Le mode temporaire sert aux annotations de session; le mode permanent sauvegarde les traits avec la note." + ] + }, + { + "title": "Sauvegarde locale", + "text": "Le contenu est nettoyé puis gardé dans le navigateur, avec une date de modification visible dans l'outil.", + "details": [ + "La note conserve le texte riche autorisé, pas du HTML libre non contrôlé.", + "La date de dernière modification permet de vérifier si une note a bien été mise à jour.", + "Les données restent dans la toolbox locale et ne nécessitent pas de compte." + ] + } + ] + }, + "checklist": { + "controls": [ + { + "group": "Contrôles", + "icon": "settings", + "title": "Décrémenter / Incrémenter", + "preview": { + "kind": "buttonGroup", + "buttons": [ + { + "label": "-" + }, + { + "label": "+" + } + ] + } + }, + { + "group": "Contrôles", + "icon": "eye-open", + "title": "Visible quand terminée", + "preview": { + "kind": "iconButton", + "icon": "eye-open" + } + }, + { + "group": "Contrôles", + "icon": "hide", + "title": "Réduit quand terminée", + "preview": { + "kind": "iconButton", + "icon": "hide" + } + }, + { + "group": "Contrôles", + "icon": "eye-closed", + "title": "Masqué quand terminée", + "preview": { + "kind": "iconButton", + "icon": "eye-closed" + } + }, + { + "group": "Contrôles", + "icon": "drag", + "title": "Déplacer", + "preview": { + "kind": "iconButton", + "icon": "drag" + } + }, + { + "group": "Contrôles", + "icon": "edit", + "title": "Modifier", + "preview": { + "kind": "iconButton", + "icon": "edit" + } + }, + { + "group": "Contrôles", + "icon": "trash", + "title": "Supprimer", + "preview": { + "kind": "iconButton", + "icon": "trash", + "danger": true + } + } + ], + "features": [ + { + "title": "Objectifs et quantités", + "text": "Chaque item possède une quantité cible et une quantité actuelle. Les boutons + et - font progresser l'item jusqu'à validation complète.", + "details": [ + "Un item sans quantité spéciale utilise 1 comme objectif.", + "Un item de type Potion:10 demande dix validations avant d'être terminé.", + "La case reflète la progression réelle : cocher complète l'objectif, les boutons + et - ajustent le nombre atteint." + ] + }, + { + "title": "Catégories terminées", + "text": "Une catégorie est considérée comme terminée quand tous ses items atteignent leur quantité cible. Elle peut rester visible, passer en mode réduit ou être masquée.", + "details": [ + "Visible garde tous les items affichés, même terminés.", + "Réduit conserve le titre de catégorie pour garder un repère sans occuper toute la hauteur.", + "Caché retire les catégories terminées de la vue courante pour se concentrer sur ce qui reste à faire." + ] + }, + { + "title": "Réorganisation", + "text": "Déplacement des catégories et des items par drag & drop pour garder la liste dans l'ordre voulu.", + "details": [ + "Une catégorie peut être déplacée avant ou après une autre catégorie.", + "Un item peut être déplacé dans la même catégorie ou envoyé dans une autre catégorie.", + "Les zones de dépôt apparaissent pendant le déplacement pour montrer où l'item sera placé." + ] + } + ], + "importFormat": { + "title": "Import texte", + "text": "Une ligne commençant par # crée une catégorie. Une ligne item peut contenir une quantité avec le format Nom:quantité.", + "example": "# Potions\nPotion:10\nMéga potion:5\n\n# Armures\nCasque Rey Dau:1" + } + }, + "counters": { + "controls": [ + { + "group": "Contrôles", + "icon": "settings", + "title": "Décrémenter / Incrémenter", + "preview": { + "kind": "buttonGroup", + "buttons": [ + { + "label": "-" + }, + { + "label": "+" + } + ] + } + }, + { + "group": "Contrôles", + "icon": "rubber", + "title": "Remettre à zéro", + "preview": { + "kind": "iconButton", + "icon": "rubber" + } + }, + { + "group": "Contrôles", + "icon": "trash", + "title": "Supprimer", + "preview": { + "kind": "iconButton", + "icon": "trash", + "danger": true + } + } + ], + "features": [ + { + "title": "Compteurs rapides", + "text": "Ajout de compteurs nommés pour suivre essais, ressources, scores, victoires ou stocks.", + "details": [ + "Chaque compteur a son propre nom et sa propre valeur.", + "Les compteurs sont utiles pour suivre des essais de drop, des morts, des ressources ou des manches.", + "L'outil reste volontairement simple : pas de catégorie, pas de configuration obligatoire." + ] + }, + { + "title": "Actions immédiates", + "text": "Chaque compteur peut être incrémenté, décrémenté, réinitialisé ou supprimé sans configuration avancée.", + "details": [ + "Le bouton + ajoute une unité au compteur.", + "Le bouton - retire une unité si une valeur a été ajoutée par erreur.", + "Réinitialiser remet la valeur à zéro sans supprimer le compteur; supprimer retire le compteur entier." + ] + } + ] + }, + "images": { + "controls": [ + { + "group": "Contrôles", + "icon": "zoom", + "title": "Agrandir", + "preview": { + "kind": "iconButton", + "icon": "zoom" + } + }, + { + "group": "Contrôles", + "icon": "map", + "title": "Envoyer vers annotation d’image", + "preview": { + "kind": "iconButton", + "icon": "map" + } + }, + { + "group": "Contrôles", + "icon": "trash", + "title": "Supprimer", + "preview": { + "kind": "iconButton", + "icon": "trash", + "danger": true + } + } + ], + "features": [ + { + "title": "Galerie locale", + "text": "Ajout de captures, cartes ou références visuelles depuis un fichier ou par collage.", + "details": [ + "Le bouton d'ajout accepte des fichiers image depuis l'appareil.", + "La zone de collage permet d'ajouter rapidement une capture copiée depuis le presse-papiers.", + "Plusieurs images peuvent cohabiter dans la même galerie de toolbox." + ] + }, + { + "title": "Prévisualisation", + "text": "Chaque image peut être ouverte en grand et renommée pour retrouver rapidement la bonne référence.", + "details": [ + "Le bouton d'aperçu ouvre l'image sans sortir de l'application.", + "Le libellé peut être modifié pour remplacer un nom de fichier peu lisible.", + "La suppression retire seulement l'image concernée de l'outil courant." + ] + }, + { + "title": "Annotation rapide", + "text": "Une image peut être envoyée vers l'outil d'annotation pour ajouter marqueurs et dessins.", + "details": [ + "Annoter copie l'image vers l'outil Annotation d'images de la même toolbox.", + "L'image devient alors le support de marqueurs, libellés et dessins.", + "La galerie garde l'image originale pour conserver la référence source." + ] + } + ] + }, + "imageAnnotation": { + "controls": [ + { + "group": "Image et marqueurs", + "icon": "zoom", + "title": "Plein écran", + "preview": { + "kind": "iconButton", + "icon": "zoom" + } + }, + { + "group": "Image et marqueurs", + "icon": "trash", + "title": "Supprimer", + "preview": { + "kind": "iconButton", + "icon": "trash", + "danger": true + } + }, + { + "group": "Dessin", + "icon": "edit", + "title": "Dessiner", + "preview": { + "kind": "iconButton", + "icon": "edit" + } + }, + { + "group": "Dessin", + "icon": "rubber", + "title": "Gommer", + "preview": { + "kind": "iconButton", + "icon": "rubber" + } + }, + { + "group": "Dessin", + "icon": "dropdown", + "title": "Couleur du trait", + "preview": { + "kind": "color" + } + }, + { + "group": "Dessin", + "icon": "dropdown", + "title": "Épaisseur du trait", + "preview": { + "kind": "drawingWidth", + "width": 4 + } + }, + { + "group": "Dessin", + "icon": "back", + "title": "Annuler le dernier trait", + "preview": { + "kind": "iconButton", + "icon": "back" + } + }, + { + "group": "Dessin", + "icon": "trash", + "title": "Effacer les dessins", + "preview": { + "kind": "iconButton", + "icon": "trash", + "danger": true + } + }, + { + "group": "Dessin", + "icon": "save", + "title": "Sauvegarde du dessin", + "preview": { + "kind": "switch", + "icon": "save", + "active": true + } + } + ], + "features": [ + { + "title": "Image unique annotable", + "text": "Préparation d'une carte ou d'un plan avec une image principale, des marqueurs et des libellés.", + "details": [ + "Une seule image sert de plan de travail pour éviter de mélanger plusieurs cartes.", + "Les marqueurs sont placés relativement à l'image et suivent son redimensionnement.", + "Chaque marqueur peut porter un libellé court pour nommer une zone, un objectif ou un repère." + ] + }, + { + "title": "Dessin plein écran", + "text": "Les traits sont ajoutés en édition plein écran et restent alignés avec l'image redimensionnée.", + "details": [ + "Le plein écran donne plus de précision pour tracer sur une carte ou une capture.", + "Les traits utilisent des coordonnées proportionnelles pour rester au bon endroit après redimensionnement.", + "La couleur et l'épaisseur permettent de distinguer plusieurs types d'information." + ] + }, + { + "title": "Annotations temporaires ou permanentes", + "text": "Les dessins peuvent rester limités à la session ou être sauvegardés dans l'outil.", + "details": [ + "Le mode temporaire sert aux notes rapides qui ne doivent pas polluer l'image à long terme.", + "Le mode permanent sauvegarde les traits dans l'outil.", + "La gomme, l'annulation et l'effacement permettent de corriger la carte pendant l'édition." + ] + } + ] + }, + "links": { + "controls": [ + { + "group": "Contrôles", + "icon": "copy", + "title": "Copier", + "preview": { + "kind": "iconButton", + "icon": "copy" + } + }, + { + "group": "Contrôles", + "icon": "trash", + "title": "Supprimer", + "preview": { + "kind": "iconButton", + "icon": "trash", + "danger": true + } + } + ], + "features": [ + { + "title": "Raccourcis de session", + "text": "Regroupement de guides, builds, cartes interactives et ressources externes avec titres lisibles.", + "details": [ + "Chaque lien associe un titre lisible et une URL.", + "Le domaine est affiché pour identifier rapidement la source.", + "L'outil sert à garder les ressources externes accessibles depuis la toolbox sans rechercher à nouveau." + ] + }, + { + "title": "Copie rapide", + "text": "Chaque URL peut être copiée directement depuis la liste.", + "details": [ + "Copier envoie l'URL complète dans le presse-papiers.", + "Supprimer retire uniquement le lien concerné.", + "L'import texte permet de préparer plusieurs liens hors de l'application puis de les coller en une seule fois." + ] + } + ], + "importFormat": { + "title": "Import texte", + "text": "Un lien par ligne. Séparez le titre et l'URL avec deux-points.", + "example": "Build:https://example.com/build?class=rogue\nMap:https://example.com/map" + } + }, + "calculator": { + "controls": [ + { + "group": "Contrôles", + "icon": "rubber", + "title": "Tout effacer", + "preview": { + "kind": "iconButton", + "icon": "rubber", + "danger": true + } + }, + { + "group": "Contrôles", + "icon": "copy", + "title": "Copie pour créer une checklist", + "preview": { + "kind": "iconButton", + "icon": "copy" + } + }, + { + "group": "Contrôles", + "icon": "edit", + "title": "Renommer", + "preview": { + "kind": "iconButton", + "icon": "edit" + } + }, + { + "group": "Contrôles", + "icon": "trash", + "title": "Supprimer", + "preview": { + "kind": "iconButton", + "icon": "trash", + "danger": true + } + } + ], + "features": [ + { + "title": "Calculs enregistrés", + "text": "Saisie d'une expression, calcul du résultat et sauvegarde avec un libellé.", + "details": [ + "Le champ expression accepte les opérations de base et calcule le résultat avant sauvegarde.", + "Le libellé sert à nommer un coût, une ressource, un total ou une conversion.", + "Un résultat enregistré peut être renommé ou supprimé." + ] + }, + { + "title": "Arborescence", + "text": "Un résultat peut servir de base à des calculs enfants pour décomposer coûts, crafts ou conversions.", + "details": [ + "Utiliser comme base crée un lien parent/enfant entre le résultat choisi et les calculs suivants.", + "La racine revient au niveau principal pour recommencer une autre branche.", + "Ce fonctionnement aide à détailler un craft ou un total en plusieurs sous-calculs." + ] + }, + { + "title": "Copie checklist", + "text": "Les résultats peuvent être copiés dans un format exploitable par l'import texte de checklist.", + "details": [ + "La copie génère un texte de type Nom:quantité.", + "Ce texte peut être collé directement dans l'import de l'outil Checklist.", + "Le calculateur sert donc à préparer des objectifs chiffrés avant de les suivre comme tâches." + ] + } + ] + }, + "table": { + "controls": [ + { + "group": "Contrôles", + "icon": "add-row", + "title": "Ajouter / Supprimer ligne", + "preview": { + "kind": "buttonGroup", + "buttons": [ + { + "icon": "add-row" + }, + { + "icon": "remove-row", + "danger": true + } + ] + } + }, + { + "group": "Contrôles", + "icon": "add-column", + "title": "Ajouter / Supprimer colonne", + "preview": { + "kind": "buttonGroup", + "buttons": [ + { + "icon": "add-column" + }, + { + "icon": "remove-column", + "danger": true + } + ] + } + }, + { + "group": "Contrôles", + "icon": "copy", + "title": "Exporter au format TSV", + "preview": { + "kind": "iconButton", + "icon": "copy" + } + } + ], + "features": [ + { + "title": "Grille éditable", + "text": "Ajout et retrait de lignes ou colonnes, édition des en-têtes et sélection de cellules.", + "details": [ + "Les boutons ligne et colonne modifient la taille de la grille sans recréer le tableau.", + "Les en-têtes peuvent être renommés pour donner un sens aux données.", + "La cellule active sert de repère pour certaines actions, comme appliquer une formule." + ] + }, + { + "title": "Formules", + "text": "Les cellules peuvent contenir des formules avec références à d'autres cellules.", + "details": [ + "Une formule peut agréger ou transformer les valeurs d'une ligne, d'une colonne ou d'une cellule.", + "Les références de cellules permettent de construire des calculs liés à d'autres données du tableau.", + "Les erreurs de formule sont signalées dans la grille au lieu d'être ignorées silencieusement." + ] + }, + { + "title": "Export TSV", + "text": "Le tableau peut être copié en TSV pour être collé dans un tableur.", + "details": [ + "Le format TSV sépare les colonnes par tabulation et les lignes par retour à la ligne.", + "Il peut être collé dans un tableur externe en conservant la structure de grille.", + "Cette copie sert d'export rapide, sans modifier le stockage local de la toolbox." + ] + } + ] + }, + "timer": { + "controls": [ + { + "group": "Chronomètre", + "icon": "play-circle", + "title": "Démarrer / Pause / Stop", + "preview": { + "kind": "buttonGroup", + "buttons": [ + { + "icon": "play-circle" + }, + { + "icon": "pause-circle" + }, + { + "icon": "stop-circle" + } + ] + } + }, + { + "group": "Chronomètre", + "icon": "record-circle", + "title": "Étape", + "preview": { + "kind": "iconButton", + "icon": "record-circle" + } + }, + { + "group": "Chronomètre", + "icon": "rubber", + "title": "Tout effacer", + "preview": { + "kind": "iconButton", + "icon": "rubber", + "danger": true + } + }, + { + "group": "Compte à rebours", + "icon": "refresh", + "title": "Réinitialiser", + "preview": { + "kind": "iconButton", + "icon": "refresh" + } + }, + { + "group": "Compte à rebours", + "icon": "refresh", + "title": "Reset / relance automatique", + "preview": { + "kind": "switch", + "icon": "refresh", + "active": true + } + }, + { + "group": "Compte à rebours", + "icon": "sound-mute", + "title": "Alerte désactivée", + "preview": { + "kind": "iconButton", + "icon": "sound-mute" + } + }, + { + "group": "Compte à rebours", + "icon": "sound-min", + "title": "Alerte sur la page", + "preview": { + "kind": "iconButton", + "icon": "sound-min" + } + }, + { + "group": "Compte à rebours", + "icon": "sound-max", + "title": "Alerte sur le site", + "preview": { + "kind": "iconButton", + "icon": "sound-max" + } + }, + { + "group": "Compte à rebours", + "icon": "trash", + "title": "Supprimer", + "preview": { + "kind": "iconButton", + "icon": "trash", + "danger": true + } + } + ], + "features": [ + { + "title": "Chronomètre", + "text": "Suivi d'un temps avec pause, reset et étapes nommées.", + "details": [ + "Démarrer lance le chrono, pause suspend le temps, reset remet le chrono à zéro.", + "Le bouton étape enregistre un temps intermédiaire avec un libellé.", + "Les étapes permettent de comparer des runs, phases ou rotations dans une session." + ] + }, + { + "title": "Comptes à rebours", + "text": "Création de timers par durée, heure précise, pattern horaire ou intervalle.", + "details": [ + "Durée lance un timer simple, par exemple 00:30:00.", + "Heure précise cible une heure donnée de la journée.", + "Pattern horaire et Intervalle servent aux resets ou événements récurrents." + ] + }, + { + "title": "Alertes", + "text": "Les alertes peuvent rester liées à l'outil affiché ou être actives sur tout le site.", + "details": [ + "Aucune alerte garde le timer silencieux.", + "Alerte visible prévient seulement quand la toolbox concernée est ouverte.", + "Alerte globale site peut prévenir depuis une autre page de Sokko G, avec garde-fou sur les répétitions trop fréquentes." + ] + } + ] + }, + "taskPlanner": { + "controls": [ + { + "group": "Contrôles", + "icon": "eye-closed", + "title": "Masquer terminé", + "preview": { + "kind": "iconButton", + "icon": "eye-closed" + } + }, + { + "group": "Contrôles", + "icon": "settings", + "title": "Paramètres", + "preview": { + "kind": "iconButton", + "icon": "settings" + } + }, + { + "group": "Contrôles", + "icon": "drag", + "title": "Déplacer", + "preview": { + "kind": "iconButton", + "icon": "drag" + } + }, + { + "group": "Contrôles", + "icon": "edit", + "title": "Modifier", + "preview": { + "kind": "iconButton", + "icon": "edit" + } + }, + { + "group": "Contrôles", + "icon": "trash", + "title": "Supprimer", + "preview": { + "kind": "iconButton", + "icon": "trash", + "danger": true + } + } + ], + "features": [ + { + "title": "Tâches de routine", + "text": "Gestion de tâches ponctuelles, quotidiennes ou hebdomadaires avec resets configurables.", + "details": [ + "Une tâche unique se coche une fois et peut être nettoyée manuellement.", + "Une tâche quotidienne se réactive selon l'heure de reset configurée.", + "Une tâche hebdomadaire se réactive selon le jour et l'heure choisis." + ] + }, + { + "title": "Sous-tâches et prérequis", + "text": "Une tâche peut dépendre d'un parent et signaler les prérequis non effectués.", + "details": [ + "Le lien parent/enfant permet de regrouper une tâche sous une autre.", + "Les prérequis indiquent qu'une tâche ne devrait pas être faite avant une autre.", + "Les avertissements de prérequis restent visibles pour éviter de valider une routine dans le mauvais ordre." + ] + }, + { + "title": "Catégories", + "text": "Les tâches se regroupent par catégories réorganisables pour suivre une routine de session.", + "details": [ + "Les catégories peuvent être renommées et déplacées.", + "Une tâche peut changer de catégorie pendant la réorganisation.", + "Masquer les tâches terminées réduit la vue aux objectifs restants." + ] + } + ] + }, + "combos": { + "controls": [ + { + "group": "Contrôles", + "icon": "settings", + "title": "Successif / Simultané", + "preview": { + "kind": "buttonGroup", + "buttons": [ + { + "label": "A › B" + }, + { + "label": "A + B" + } + ] + } + }, + { + "group": "Contrôles", + "icon": "add", + "title": "Ajouter input", + "preview": { + "kind": "iconButton", + "icon": "add" + } + }, + { + "group": "Contrôles", + "icon": "clock", + "title": "Hold", + "preview": { + "kind": "iconButton", + "icon": "clock" + } + }, + { + "group": "Contrôles", + "icon": "back", + "title": "Retirer touche / étape", + "preview": { + "kind": "buttonGroup", + "buttons": [ + { + "icon": "back" + }, + { + "icon": "trash", + "danger": true + } + ] + } + }, + { + "group": "Contrôles", + "icon": "edit", + "title": "Modifier", + "text": "Ouvre la fiche d'une pièce pour ajuster stats, craft, source et sockets.", + "preview": { + "kind": "iconButton", + "icon": "edit" + } + }, + { + "group": "Contrôles", + "icon": "trash", + "title": "Supprimer", + "preview": { + "kind": "iconButton", + "icon": "trash", + "danger": true + } + } + ], + "features": [ + { + "title": "Séquences de touches", + "text": "Un combo est une suite d'étapes. Une étape peut contenir une seule touche ou plusieurs touches simultanées, affichées ensemble avec un +.", + "details": [ + "Cliquer sur une touche de la palette ajoute une nouvelle étape à la fin de la séquence.", + "En mode successif, A puis B crée deux étapes séparées : A, puis B.", + "En mode simultané, A puis B crée une seule étape groupée : A + B." + ] + }, + { + "title": "Création successive ou simultanée", + "text": "Le mode par défaut ajoute les inputs les uns après les autres. Le mode simultané ajoute les prochains inputs dans la même étape; le drag & drop permet aussi de fusionner deux étapes déjà créées.", + "details": [ + "Le switch A + B sert à décider si les prochaines touches doivent entrer dans l'étape active.", + "Déposer une touche sur une étape existante transforme cette étape en combinaison simultanée.", + "Ce geste permet de corriger une séquence après coup sans supprimer puis recréer tout le combo." + ] + }, + { + "title": "Catégories de combos", + "text": "Les combos peuvent être regroupés, édités, déplacés et supprimés par catégorie.", + "details": [ + "Le champ catégorie place automatiquement le combo dans le bon groupe.", + "Les catégories se replient pour masquer des groupes déjà connus.", + "Les poignées de déplacement servent à réordonner les catégories ou les combos dans une catégorie." + ] + }, + { + "title": "Périphériques et touches personnalisées", + "text": "La palette change selon la manette ou le clavier. Une touche personnalisée peut être ajoutée quand la commande du jeu n'existe pas dans la palette.", + "details": [ + "Les palettes PlayStation, Xbox, Switch et Nintendo 64 affichent les boutons propres à chaque manette.", + "Le mode clavier/souris propose les touches courantes, la souris et une bascule AZERTY/QWERTY.", + "Le champ touche personnalisée accepte une commande courte pour documenter une touche absente de la palette." + ] + } + ] + }, + "equipmentPlanner": { + "controls": [ + { + "group": "Contrôles", + "icon": "edit", + "title": "Modifier", + "preview": { + "kind": "iconButton", + "icon": "edit" + } + }, + { + "group": "Contrôles", + "icon": "drag", + "title": "Déplacer", + "preview": { + "kind": "iconButton", + "icon": "drag" + } + }, + { + "group": "Contrôles", + "icon": "trash", + "title": "Supprimer", + "preview": { + "kind": "iconButton", + "icon": "trash", + "danger": true + } + } + ], + "features": [ + { + "title": "Build d'équipement", + "text": "Organisation d'équipements par type avec icônes, état actif et détails d'obtention.", + "details": [ + "Chaque équipement appartient à un type, par exemple arme, casque ou anneau.", + "L'état actif décide si la pièce compte dans le résumé du build.", + "Les détails d'obtention servent à noter où récupérer ou fabriquer l'équipement." + ] + }, + { + "title": "Stats et matériaux", + "text": "Suivi des caractéristiques, bonus, matériaux de craft et totaux agrégés.", + "details": [ + "Les statistiques numériques sont additionnées dans le résumé.", + "Les bonus textuels restent listés à part pour ne pas perdre les effets non chiffrés.", + "Les matériaux de craft permettent de préparer une liste de ressources à récupérer." + ] + }, + { + "title": "Sertissages", + "text": "Ajout d'objets sertis, bonus associés et liens entre sockets.", + "details": [ + "Les sockets décrivent les emplacements disponibles sur une pièce.", + "Un objet serti peut ajouter des stats ou des bonus propres.", + "Les totaux de sockets aident à vérifier rapidement ce qui est déjà prévu dans le build." + ] + } + ] + } + }, "summaryItems": [ { "icon": "toolbox", @@ -201,6 +1272,11 @@ "icon": "tasklist", "name": "Planificateur de tâches", "description": "Organisez des tâches ponctuelles, quotidiennes ou hebdomadaires avec catégories, sous-tâches et dépendances parent/enfant." + }, + { + "icon": "chest-armor", + "name": "Planificateur d'équipements", + "description": "Planifiez un build par types d'équipement, avec pièces actives, statistiques, matériaux de craft, bonus et sertissages." } ], "limitsTitle": "À retenir", diff --git a/website/public/static/icons/book.svg b/website/public/static/icons/book.svg new file mode 100644 index 0000000..1140045 --- /dev/null +++ b/website/public/static/icons/book.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/website/src/components/Shell.jsx b/website/src/components/Shell.jsx index 1f557d6..dd80741 100644 --- a/website/src/components/Shell.jsx +++ b/website/src/components/Shell.jsx @@ -22,7 +22,10 @@ export function Shell({ route, content, games, toolboxes, links, actions, childr {content.navigation.games} {content.navigation.toolboxes} - {content.navigation.about} +
{content.sidebar.note}
diff --git a/website/src/features/toolboxes/ToolboxPages.jsx b/website/src/features/toolboxes/ToolboxPages.jsx index ec76aa0..406c619 100644 --- a/website/src/features/toolboxes/ToolboxPages.jsx +++ b/website/src/features/toolboxes/ToolboxPages.jsx @@ -72,7 +72,7 @@ export function ToolboxesPage({ siteContent, toolboxes, getToolboxGame, actions,{content.eyebrow}
{content.summary}
- {content.libraryLink} +Toolbox
Chargement des exemples...
{content.categoryLabel || "Catégorie"}
+{activeCategory.description}
} +{description}
} -{description}
} +{definition.mode}
{feature.text}
+ {Array.isArray(feature.details) && feature.details.length > 0 && ( +{docs.importFormat.text}
+{docs.importFormat.example}
+