diff --git a/src/components/shared/PageHelp.tsx b/src/components/shared/PageHelp.tsx new file mode 100644 index 0000000..8301983 --- /dev/null +++ b/src/components/shared/PageHelp.tsx @@ -0,0 +1,59 @@ +import { useState, useRef, useEffect } from "react"; +import { useTranslation } from "react-i18next"; +import { CircleHelp, X } from "lucide-react"; + +export function PageHelp({ helpKey }: { helpKey: string }) { + const { t } = useTranslation(); + const [isOpen, setIsOpen] = useState(false); + const ref = useRef(null); + + // Close on outside click (same pattern as CategoryCombobox) + useEffect(() => { + if (!isOpen) return; + const handler = (e: MouseEvent) => { + if (ref.current && !ref.current.contains(e.target as Node)) { + setIsOpen(false); + } + }; + document.addEventListener("mousedown", handler); + return () => document.removeEventListener("mousedown", handler); + }, [isOpen]); + + const tips = t(`${helpKey}.help.tips`, { returnObjects: true }) as string[]; + + return ( +
+ + {isOpen && ( +
+
+

+ {t(`${helpKey}.help.title`)} +

+ +
+
    + {Array.isArray(tips) && + tips.map((tip, i) => ( +
  • + + {tip} +
  • + ))} +
+
+ )} +
+ ); +} diff --git a/src/i18n/locales/en.json b/src/i18n/locales/en.json index 1460372..172163b 100644 --- a/src/i18n/locales/en.json +++ b/src/i18n/locales/en.json @@ -26,6 +26,15 @@ "6months": "6 months", "12months": "12 months", "all": "All" + }, + "help": { + "title": "How to use the Dashboard", + "tips": [ + "Use the period selector (top right) to view different time ranges", + "Summary cards show your balance, income, and expenses for the selected period", + "The pie chart breaks down your expenses by category", + "Recent transactions are listed at the bottom" + ] } }, "import": { @@ -145,6 +154,15 @@ "checkDuplicates": "Check duplicates", "confirm": "Confirm", "import": "Import" + }, + "help": { + "title": "How to import bank statements", + "tips": [ + "Set your import folder, then create one subfolder per bank/source with CSV files inside", + "Click a source to configure column mapping, delimiter, and date format", + "Preview your data before importing to catch formatting issues", + "Duplicate detection prevents the same transactions from being imported twice" + ] } }, "transactions": { @@ -184,7 +202,16 @@ }, "autoCategorize": "Auto-categorize", "autoCategorizeResult": "{{count}} transaction(s) categorized", - "autoCategorizeNone": "No new matches found" + "autoCategorizeNone": "No new matches found", + "help": { + "title": "How to use Transactions", + "tips": [ + "Use the filters to search by description, category, source, or date range", + "Click a column header to sort transactions", + "Assign categories by clicking the category dropdown on each row", + "Auto-categorize uses your keyword rules to categorize transactions in bulk" + ] + } }, "categories": { "title": "Categories", @@ -207,7 +234,16 @@ "keywordCount": "Keywords", "keywordText": "Keyword...", "priority": "Priority", - "customColor": "Custom color" + "customColor": "Custom color", + "help": { + "title": "How to manage Categories", + "tips": [ + "Create top-level categories and subcategories to organize your expenses and income", + "Add keywords to a category so transactions matching those words are auto-categorized", + "Set a priority on keywords to resolve conflicts when multiple categories match", + "Click a category in the tree to view its details, edit it, or manage keywords" + ] + } }, "adjustments": { "title": "Adjustments", @@ -215,7 +251,15 @@ "date": "Date", "description": "Description", "amount": "Amount", - "recurring": "Recurring" + "recurring": "Recurring", + "help": { + "title": "How to use Adjustments", + "tips": [ + "Adjustments let you add manual entries that don't come from bank imports", + "Use them for expected expenses or income not yet reflected in your statements", + "Recurring adjustments repeat automatically each period" + ] + } }, "budget": { "title": "Budget", @@ -224,7 +268,15 @@ "planned": "Planned", "actual": "Actual", "difference": "Difference", - "template": "Template" + "template": "Template", + "help": { + "title": "How to use Budget", + "tips": [ + "Set planned amounts for each category to track your spending goals", + "Compare planned vs. actual spending to see where you're over or under budget", + "Use templates to quickly apply the same budget across multiple months" + ] + } }, "reports": { "title": "Reports", @@ -232,7 +284,16 @@ "byCategory": "Expenses by Category", "overTime": "Category Over Time", "trends": "Monthly Trends", - "export": "Export" + "export": "Export", + "help": { + "title": "How to use Reports", + "tips": [ + "Switch between Trends, By Category, and Over Time views using the tabs", + "Use the period selector to adjust the time range for all charts", + "Monthly Trends shows your income and expenses over time", + "Category Over Time tracks how spending in each category evolves" + ] + } }, "settings": { "title": "Settings", @@ -251,7 +312,15 @@ "error": "Update failed", "retryButton": "Retry" }, - "dataSafeNotice": "Your data is safe — only the app binary is replaced, your database is not modified." + "dataSafeNotice": "Your data is safe — only the app binary is replaced, your database is not modified.", + "help": { + "title": "About Settings", + "tips": [ + "Check for app updates and install them directly from this page", + "Your data is stored locally and is never affected by updates", + "Change the app language using the language selector in the sidebar" + ] + } }, "common": { "save": "Save", diff --git a/src/i18n/locales/fr.json b/src/i18n/locales/fr.json index 7c9f3b1..69481be 100644 --- a/src/i18n/locales/fr.json +++ b/src/i18n/locales/fr.json @@ -26,6 +26,15 @@ "6months": "6 mois", "12months": "12 mois", "all": "Tout" + }, + "help": { + "title": "Comment utiliser le tableau de bord", + "tips": [ + "Utilisez le sélecteur de période (en haut à droite) pour changer la plage de dates", + "Les cartes résumées affichent votre solde, revenus et dépenses pour la période sélectionnée", + "Le graphique circulaire détaille vos dépenses par catégorie", + "Les transactions récentes sont listées en bas de page" + ] } }, "import": { @@ -145,6 +154,15 @@ "checkDuplicates": "Vérifier les doublons", "confirm": "Confirmer", "import": "Importer" + }, + "help": { + "title": "Comment importer des relevés bancaires", + "tips": [ + "Configurez votre dossier d'import, puis créez un sous-dossier par banque/source avec des fichiers CSV", + "Cliquez sur une source pour configurer le mapping des colonnes, le délimiteur et le format de date", + "Prévisualisez vos données avant l'import pour détecter les problèmes de formatage", + "La détection des doublons empêche d'importer les mêmes transactions deux fois" + ] } }, "transactions": { @@ -184,7 +202,16 @@ }, "autoCategorize": "Auto-catégoriser", "autoCategorizeResult": "{{count}} transaction(s) catégorisée(s)", - "autoCategorizeNone": "Aucune correspondance trouvée" + "autoCategorizeNone": "Aucune correspondance trouvée", + "help": { + "title": "Comment utiliser les Transactions", + "tips": [ + "Utilisez les filtres pour rechercher par description, catégorie, source ou plage de dates", + "Cliquez sur un en-tête de colonne pour trier les transactions", + "Assignez une catégorie via le menu déroulant sur chaque ligne", + "L'auto-catégorisation utilise vos règles de mots-clés pour catégoriser en masse" + ] + } }, "categories": { "title": "Catégories", @@ -207,7 +234,16 @@ "keywordCount": "Mots-clés", "keywordText": "Mot-clé...", "priority": "Priorité", - "customColor": "Couleur personnalisée" + "customColor": "Couleur personnalisée", + "help": { + "title": "Comment gérer les Catégories", + "tips": [ + "Créez des catégories et sous-catégories pour organiser vos dépenses et revenus", + "Ajoutez des mots-clés à une catégorie pour que les transactions correspondantes soient auto-catégorisées", + "Définissez une priorité sur les mots-clés pour résoudre les conflits entre catégories", + "Cliquez sur une catégorie dans l'arbre pour voir ses détails, la modifier ou gérer ses mots-clés" + ] + } }, "adjustments": { "title": "Ajustements", @@ -215,7 +251,15 @@ "date": "Date", "description": "Description", "amount": "Montant", - "recurring": "Récurrent" + "recurring": "Récurrent", + "help": { + "title": "Comment utiliser les Ajustements", + "tips": [ + "Les ajustements permettent d'ajouter des entrées manuelles non issues de vos relevés bancaires", + "Utilisez-les pour des dépenses ou revenus prévus non encore reflétés dans vos relevés", + "Les ajustements récurrents se répètent automatiquement à chaque période" + ] + } }, "budget": { "title": "Budget", @@ -224,7 +268,15 @@ "planned": "Prévu", "actual": "Réel", "difference": "Écart", - "template": "Modèle" + "template": "Modèle", + "help": { + "title": "Comment utiliser le Budget", + "tips": [ + "Définissez des montants prévus par catégorie pour suivre vos objectifs de dépenses", + "Comparez le prévu et le réel pour voir où vous dépassez ou êtes en dessous du budget", + "Utilisez les modèles pour appliquer rapidement le même budget sur plusieurs mois" + ] + } }, "reports": { "title": "Rapports", @@ -232,7 +284,16 @@ "byCategory": "Dépenses par catégorie", "overTime": "Catégories dans le temps", "trends": "Tendances mensuelles", - "export": "Exporter" + "export": "Exporter", + "help": { + "title": "Comment utiliser les Rapports", + "tips": [ + "Basculez entre les vues Tendances, Par catégorie et Dans le temps via les onglets", + "Utilisez le sélecteur de période pour ajuster la plage de dates de tous les graphiques", + "Les tendances mensuelles montrent vos revenus et dépenses au fil du temps", + "Catégories dans le temps suit l'évolution des dépenses par catégorie" + ] + } }, "settings": { "title": "Paramètres", @@ -251,7 +312,15 @@ "error": "Erreur lors de la mise à jour", "retryButton": "Réessayer" }, - "dataSafeNotice": "Vos données sont en sécurité — seul le programme est remplacé, votre base de données n'est pas modifiée." + "dataSafeNotice": "Vos données sont en sécurité — seul le programme est remplacé, votre base de données n'est pas modifiée.", + "help": { + "title": "À propos des Paramètres", + "tips": [ + "Vérifiez les mises à jour de l'application et installez-les directement depuis cette page", + "Vos données sont stockées localement et ne sont jamais affectées par les mises à jour", + "Changez la langue de l'application via le sélecteur de langue dans la barre latérale" + ] + } }, "common": { "save": "Enregistrer", diff --git a/src/pages/AdjustmentsPage.tsx b/src/pages/AdjustmentsPage.tsx index fd90c2a..1366e9a 100644 --- a/src/pages/AdjustmentsPage.tsx +++ b/src/pages/AdjustmentsPage.tsx @@ -1,11 +1,15 @@ import { useTranslation } from "react-i18next"; +import { PageHelp } from "../components/shared/PageHelp"; export default function AdjustmentsPage() { const { t } = useTranslation(); return (
-

{t("adjustments.title")}

+
+

{t("adjustments.title")}

+ +

{t("common.noResults")}

diff --git a/src/pages/BudgetPage.tsx b/src/pages/BudgetPage.tsx index fd61651..8f0c4c5 100644 --- a/src/pages/BudgetPage.tsx +++ b/src/pages/BudgetPage.tsx @@ -1,11 +1,15 @@ import { useTranslation } from "react-i18next"; +import { PageHelp } from "../components/shared/PageHelp"; export default function BudgetPage() { const { t } = useTranslation(); return (
-

{t("budget.title")}

+
+

{t("budget.title")}

+ +

{t("common.noResults")}

diff --git a/src/pages/CategoriesPage.tsx b/src/pages/CategoriesPage.tsx index 7394a44..fcf85ee 100644 --- a/src/pages/CategoriesPage.tsx +++ b/src/pages/CategoriesPage.tsx @@ -1,5 +1,6 @@ import { useTranslation } from "react-i18next"; import { Plus } from "lucide-react"; +import { PageHelp } from "../components/shared/PageHelp"; import { useCategories } from "../hooks/useCategories"; import CategoryTree from "../components/categories/CategoryTree"; import CategoryDetailPanel from "../components/categories/CategoryDetailPanel"; @@ -26,8 +27,11 @@ export default function CategoriesPage() { return (
-
-

{t("categories.title")}

+
+
+

{t("categories.title")}

+ +