feat: add user guide page with print/PDF support
Some checks failed
Release / build (windows-latest) (push) Has been cancelled
Some checks failed
Release / build (windows-latest) (push) Has been cancelled
Add DocsPage with full user guide content, TOC sidebar with scroll spy, and a print button that opens the OS print dialog for PDF export. Print styles hide sidebars and remove layout constraints for clean output. Link to user guide added on Settings page. Bump version to 0.2.12. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
9914737f26
commit
0831663bbd
9 changed files with 718 additions and 3 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "simpl_result_scaffold",
|
"name": "simpl_result_scaffold",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.2.11",
|
"version": "0.2.12",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "simpl-result"
|
name = "simpl-result"
|
||||||
version = "0.2.11"
|
version = "0.2.12"
|
||||||
description = "Personal finance management app"
|
description = "Personal finance management app"
|
||||||
authors = ["you"]
|
authors = ["you"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"$schema": "https://schema.tauri.app/config/2",
|
"$schema": "https://schema.tauri.app/config/2",
|
||||||
"productName": "Simpl Résultat",
|
"productName": "Simpl Résultat",
|
||||||
"version": "0.2.11",
|
"version": "0.2.12",
|
||||||
"identifier": "com.simpl.resultat",
|
"identifier": "com.simpl.resultat",
|
||||||
"build": {
|
"build": {
|
||||||
"beforeDevCommand": "npm run dev",
|
"beforeDevCommand": "npm run dev",
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import AdjustmentsPage from "./pages/AdjustmentsPage";
|
||||||
import BudgetPage from "./pages/BudgetPage";
|
import BudgetPage from "./pages/BudgetPage";
|
||||||
import ReportsPage from "./pages/ReportsPage";
|
import ReportsPage from "./pages/ReportsPage";
|
||||||
import SettingsPage from "./pages/SettingsPage";
|
import SettingsPage from "./pages/SettingsPage";
|
||||||
|
import DocsPage from "./pages/DocsPage";
|
||||||
|
|
||||||
export default function App() {
|
export default function App() {
|
||||||
return (
|
return (
|
||||||
|
|
@ -22,6 +23,7 @@ export default function App() {
|
||||||
<Route path="/budget" element={<BudgetPage />} />
|
<Route path="/budget" element={<BudgetPage />} />
|
||||||
<Route path="/reports" element={<ReportsPage />} />
|
<Route path="/reports" element={<ReportsPage />} />
|
||||||
<Route path="/settings" element={<SettingsPage />} />
|
<Route path="/settings" element={<SettingsPage />} />
|
||||||
|
<Route path="/docs" element={<DocsPage />} />
|
||||||
</Route>
|
</Route>
|
||||||
</Routes>
|
</Routes>
|
||||||
</BrowserRouter>
|
</BrowserRouter>
|
||||||
|
|
|
||||||
|
|
@ -410,6 +410,10 @@
|
||||||
"tryAgain": "Try again"
|
"tryAgain": "Try again"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"userGuide": {
|
||||||
|
"title": "User Guide",
|
||||||
|
"description": "Learn how to use all features of the app"
|
||||||
|
},
|
||||||
"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": {
|
"help": {
|
||||||
"title": "About Settings",
|
"title": "About Settings",
|
||||||
|
|
@ -443,6 +447,215 @@
|
||||||
"nov": "Nov",
|
"nov": "Nov",
|
||||||
"dec": "Dec"
|
"dec": "Dec"
|
||||||
},
|
},
|
||||||
|
"docs": {
|
||||||
|
"title": "User Guide",
|
||||||
|
"backToSettings": "Back to Settings",
|
||||||
|
"print": "Print",
|
||||||
|
"features": "Features",
|
||||||
|
"howTo": "How To",
|
||||||
|
"quickStart": "Quick Start",
|
||||||
|
"tipsHeader": "Tips",
|
||||||
|
"gettingStarted": {
|
||||||
|
"title": "Getting Started",
|
||||||
|
"overview": "Simpl'Result helps you track your personal finances by importing bank statements, categorizing transactions, setting budgets, and generating reports.",
|
||||||
|
"features": [
|
||||||
|
"Import CSV bank statements from multiple sources",
|
||||||
|
"Automatic and manual transaction categorization",
|
||||||
|
"Budget planning with monthly and annual views",
|
||||||
|
"Visual reports and trend analysis"
|
||||||
|
],
|
||||||
|
"steps": [
|
||||||
|
"Go to Settings and set your import folder — create one subfolder per bank account",
|
||||||
|
"Place your CSV bank statements in the corresponding subfolder",
|
||||||
|
"Open the Import page and configure your source (column mapping, delimiter, date format)",
|
||||||
|
"Import your transactions, then head to Categories to set up keyword rules",
|
||||||
|
"Use Auto-categorize on the Transactions page to apply your rules in bulk",
|
||||||
|
"Set up your Budget and track progress via Reports"
|
||||||
|
],
|
||||||
|
"tips": [
|
||||||
|
"You can switch between English and French using the language selector in the sidebar",
|
||||||
|
"Each page has a help icon (?) in the header with quick tips",
|
||||||
|
"Your data is stored locally on your computer — nothing is sent to the cloud"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"dashboard": {
|
||||||
|
"title": "Dashboard",
|
||||||
|
"overview": "The Dashboard gives you an at-a-glance summary of your financial situation for a selected time period.",
|
||||||
|
"features": [
|
||||||
|
"Balance, income, and expense summary cards",
|
||||||
|
"Expense breakdown by category (pie chart)",
|
||||||
|
"Recent transactions list",
|
||||||
|
"Adjustable time period selector"
|
||||||
|
],
|
||||||
|
"steps": [
|
||||||
|
"Use the period selector in the top-right to choose a time range (month, 3 months, year, etc.)",
|
||||||
|
"Review the summary cards for your balance, total income, and total expenses",
|
||||||
|
"Check the pie chart to see how your spending is distributed across categories",
|
||||||
|
"Scroll down to see your most recent transactions"
|
||||||
|
],
|
||||||
|
"tips": [
|
||||||
|
"The balance is calculated as income minus expenses for the selected period",
|
||||||
|
"Click on a category in the pie chart to view its transactions"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"import": {
|
||||||
|
"title": "Import",
|
||||||
|
"overview": "Import bank statements from CSV files using a step-by-step wizard. Each bank account is represented as a source folder.",
|
||||||
|
"features": [
|
||||||
|
"Multi-step import wizard with data preview",
|
||||||
|
"Configurable column mapping, delimiter, and date format",
|
||||||
|
"Automatic duplicate detection (within batch and against existing data)",
|
||||||
|
"Import templates to save and reuse source configurations",
|
||||||
|
"Import history with the ability to delete past imports"
|
||||||
|
],
|
||||||
|
"steps": [
|
||||||
|
"Set your import folder via the folder picker at the top of the page",
|
||||||
|
"Create a subfolder for each bank/source and place CSV files inside",
|
||||||
|
"Click on a source to open the import wizard",
|
||||||
|
"Configure the delimiter, encoding, date format, and column mapping",
|
||||||
|
"Select which files to import and preview the parsed data",
|
||||||
|
"Check for duplicates, review the summary, then confirm the import"
|
||||||
|
],
|
||||||
|
"tips": [
|
||||||
|
"Save your configuration as a template so you don't have to reconfigure each time",
|
||||||
|
"Files already imported are marked with a badge — re-importing them will trigger duplicate detection",
|
||||||
|
"You can delete an import from the history to remove all its transactions"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"transactions": {
|
||||||
|
"title": "Transactions",
|
||||||
|
"overview": "Browse, filter, sort, and categorize all your imported transactions. This is where you organize your financial data.",
|
||||||
|
"features": [
|
||||||
|
"Search and filter by description, category, source, or date range",
|
||||||
|
"Quick period selectors (this month, last month, this year, etc.)",
|
||||||
|
"Sortable columns (date, description, amount, category)",
|
||||||
|
"Inline category assignment via dropdown",
|
||||||
|
"Auto-categorize based on keyword rules",
|
||||||
|
"Add keywords directly from a transaction",
|
||||||
|
"Transaction notes"
|
||||||
|
],
|
||||||
|
"steps": [
|
||||||
|
"Use the filter bar to narrow down transactions by text, category, source, or date",
|
||||||
|
"Click a column header to sort ascending or descending",
|
||||||
|
"To categorize a transaction, click its category dropdown and select a category",
|
||||||
|
"To auto-categorize all uncategorized transactions, click the Auto-categorize button",
|
||||||
|
"To add a keyword rule from a transaction, click the + icon and enter the keyword"
|
||||||
|
],
|
||||||
|
"tips": [
|
||||||
|
"Use the quick period buttons (This month, Last month, etc.) for fast date filtering",
|
||||||
|
"Auto-categorize only affects uncategorized transactions — it won't overwrite manual assignments",
|
||||||
|
"Adding a keyword from a transaction pre-fills the category so you can quickly build rules"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"categories": {
|
||||||
|
"title": "Categories",
|
||||||
|
"overview": "Manage your category tree with subcategories, keyword rules for auto-categorization, and custom colors.",
|
||||||
|
"features": [
|
||||||
|
"Hierarchical categories with parent/child relationships",
|
||||||
|
"Three category types: Expense, Income, Transfer",
|
||||||
|
"Keyword rules with priority levels for auto-categorization",
|
||||||
|
"Custom colors for chart display",
|
||||||
|
"Toggle categories as inputable or non-inputable",
|
||||||
|
"Re-initialize categories to defaults"
|
||||||
|
],
|
||||||
|
"steps": [
|
||||||
|
"Click Add Category to create a new category — choose a name, type, and optional parent",
|
||||||
|
"Select a category in the tree to view its details and keyword list",
|
||||||
|
"Add keywords that match transaction descriptions for auto-categorization",
|
||||||
|
"Set keyword priority to resolve conflicts when multiple categories match",
|
||||||
|
"Use the color picker to assign a custom color for charts"
|
||||||
|
],
|
||||||
|
"tips": [
|
||||||
|
"Non-inputable categories are hidden from budget and transaction dropdowns but still visible in reports",
|
||||||
|
"Higher priority keywords win when multiple categories match the same transaction",
|
||||||
|
"Use Re-initialize to reset categories to defaults — this will unlink all transaction categories"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"adjustments": {
|
||||||
|
"title": "Adjustments",
|
||||||
|
"overview": "Add manual entries that don't come from bank imports — useful for expected expenses, income, or corrections not yet in your statements.",
|
||||||
|
"features": [
|
||||||
|
"Create named adjustment groups with multiple entries",
|
||||||
|
"Assign a category to each entry",
|
||||||
|
"Mark adjustments as recurring"
|
||||||
|
],
|
||||||
|
"steps": [
|
||||||
|
"Click New Adjustment to create an adjustment group",
|
||||||
|
"Add entries with a description, amount, date, and category",
|
||||||
|
"Toggle the recurring flag if the adjustment should repeat each period"
|
||||||
|
],
|
||||||
|
"tips": [
|
||||||
|
"Adjustments appear in your budget actuals alongside imported transactions",
|
||||||
|
"Use adjustments for planned expenses that haven't hit your bank account yet"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"budget": {
|
||||||
|
"title": "Budget",
|
||||||
|
"overview": "Plan your monthly budget for each category and track planned vs. actual spending throughout the year.",
|
||||||
|
"features": [
|
||||||
|
"Monthly budget grid for all categories",
|
||||||
|
"Annual column with automatic totals",
|
||||||
|
"Split annual amount evenly across 12 months",
|
||||||
|
"Budget templates to save and apply configurations",
|
||||||
|
"Parent category subtotals"
|
||||||
|
],
|
||||||
|
"steps": [
|
||||||
|
"Use the year navigator to select the budget year",
|
||||||
|
"Click on any month cell to enter a planned amount",
|
||||||
|
"Press Enter to save, Escape to cancel, or Tab to move to the next month",
|
||||||
|
"Use the split button (on the Annual column) to distribute evenly across all months",
|
||||||
|
"Save your budget as a template to reuse it in future years"
|
||||||
|
],
|
||||||
|
"tips": [
|
||||||
|
"The Annual column auto-sums all 12 months — a warning appears if monthly totals don't match",
|
||||||
|
"Templates can be applied to specific months or all 12 at once",
|
||||||
|
"Parent categories show subtotals aggregated from their children"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"reports": {
|
||||||
|
"title": "Reports",
|
||||||
|
"overview": "Visualize your financial data with interactive charts and compare your budget plan against actual spending.",
|
||||||
|
"features": [
|
||||||
|
"Monthly Trends: income vs. expenses over time (bar chart)",
|
||||||
|
"Expenses by Category: spending breakdown (pie chart)",
|
||||||
|
"Category Over Time: track how each category evolves (line chart)",
|
||||||
|
"Budget vs Actual: monthly and year-to-date comparison table"
|
||||||
|
],
|
||||||
|
"steps": [
|
||||||
|
"Use the tabs to switch between Trends, By Category, Over Time, and Budget vs Actual views",
|
||||||
|
"Adjust the time period using the period selector",
|
||||||
|
"In the pie chart, click a category to hide/show it",
|
||||||
|
"In Budget vs Actual, toggle between Monthly and Year-to-Date views"
|
||||||
|
],
|
||||||
|
"tips": [
|
||||||
|
"Hidden categories are remembered while you stay on the page — click Show All to reset",
|
||||||
|
"The period selector applies to all chart tabs simultaneously",
|
||||||
|
"Budget vs Actual shows dollar and percentage variance for each category"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"settings": {
|
||||||
|
"title": "Settings",
|
||||||
|
"overview": "Configure app preferences, check for updates, and manage your data with export/import tools.",
|
||||||
|
"features": [
|
||||||
|
"App version display",
|
||||||
|
"Automatic update checker with one-click install",
|
||||||
|
"Data export (transactions, categories, or both) in JSON or CSV format",
|
||||||
|
"Data import from a previously exported file",
|
||||||
|
"Optional encryption for exported files"
|
||||||
|
],
|
||||||
|
"steps": [
|
||||||
|
"Click Check for Updates to see if a new version is available",
|
||||||
|
"Use the Data Management section to export or import your data",
|
||||||
|
"When exporting, choose what to include and optionally set a password for encryption",
|
||||||
|
"When importing, select a previously exported file — encrypted files will prompt for the password"
|
||||||
|
],
|
||||||
|
"tips": [
|
||||||
|
"Updates only replace the app binary — your database is never modified",
|
||||||
|
"Change the app language using the language selector in the sidebar",
|
||||||
|
"Export regularly to keep a backup of your data"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
"common": {
|
"common": {
|
||||||
"save": "Save",
|
"save": "Save",
|
||||||
"cancel": "Cancel",
|
"cancel": "Cancel",
|
||||||
|
|
|
||||||
|
|
@ -410,6 +410,10 @@
|
||||||
"tryAgain": "Réessayer"
|
"tryAgain": "Réessayer"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"userGuide": {
|
||||||
|
"title": "Guide d'utilisation",
|
||||||
|
"description": "Apprenez à utiliser toutes les fonctionnalités de l'application"
|
||||||
|
},
|
||||||
"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": {
|
"help": {
|
||||||
"title": "À propos des Paramètres",
|
"title": "À propos des Paramètres",
|
||||||
|
|
@ -443,6 +447,215 @@
|
||||||
"nov": "Nov",
|
"nov": "Nov",
|
||||||
"dec": "Déc"
|
"dec": "Déc"
|
||||||
},
|
},
|
||||||
|
"docs": {
|
||||||
|
"title": "Guide d'utilisation",
|
||||||
|
"backToSettings": "Retour aux paramètres",
|
||||||
|
"print": "Imprimer",
|
||||||
|
"features": "Fonctionnalités",
|
||||||
|
"howTo": "Comment faire",
|
||||||
|
"quickStart": "Démarrage rapide",
|
||||||
|
"tipsHeader": "Astuces",
|
||||||
|
"gettingStarted": {
|
||||||
|
"title": "Premiers pas",
|
||||||
|
"overview": "Simpl'Résultat vous aide à suivre vos finances personnelles en important des relevés bancaires, en catégorisant les transactions, en planifiant des budgets et en générant des rapports.",
|
||||||
|
"features": [
|
||||||
|
"Importation de relevés bancaires CSV depuis plusieurs sources",
|
||||||
|
"Catégorisation automatique et manuelle des transactions",
|
||||||
|
"Planification budgétaire avec vues mensuelles et annuelles",
|
||||||
|
"Rapports visuels et analyse des tendances"
|
||||||
|
],
|
||||||
|
"steps": [
|
||||||
|
"Allez dans Paramètres et définissez votre dossier d'import — créez un sous-dossier par compte bancaire",
|
||||||
|
"Placez vos relevés bancaires CSV dans le sous-dossier correspondant",
|
||||||
|
"Ouvrez la page Import et configurez votre source (mapping des colonnes, délimiteur, format de date)",
|
||||||
|
"Importez vos transactions, puis allez dans Catégories pour configurer les règles de mots-clés",
|
||||||
|
"Utilisez l'auto-catégorisation sur la page Transactions pour appliquer vos règles en masse",
|
||||||
|
"Configurez votre Budget et suivez votre progression via les Rapports"
|
||||||
|
],
|
||||||
|
"tips": [
|
||||||
|
"Vous pouvez basculer entre le français et l'anglais via le sélecteur de langue dans la barre latérale",
|
||||||
|
"Chaque page a une icône d'aide (?) dans l'en-tête avec des astuces rapides",
|
||||||
|
"Vos données sont stockées localement sur votre ordinateur — rien n'est envoyé vers le cloud"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"dashboard": {
|
||||||
|
"title": "Tableau de bord",
|
||||||
|
"overview": "Le tableau de bord vous donne un aperçu rapide de votre situation financière pour une période sélectionnée.",
|
||||||
|
"features": [
|
||||||
|
"Cartes résumées du solde, des revenus et des dépenses",
|
||||||
|
"Répartition des dépenses par catégorie (graphique circulaire)",
|
||||||
|
"Liste des transactions récentes",
|
||||||
|
"Sélecteur de période ajustable"
|
||||||
|
],
|
||||||
|
"steps": [
|
||||||
|
"Utilisez le sélecteur de période en haut à droite pour choisir une plage de temps (mois, 3 mois, année, etc.)",
|
||||||
|
"Consultez les cartes résumées pour votre solde, revenus totaux et dépenses totales",
|
||||||
|
"Vérifiez le graphique circulaire pour voir comment vos dépenses sont réparties par catégorie",
|
||||||
|
"Faites défiler vers le bas pour voir vos transactions les plus récentes"
|
||||||
|
],
|
||||||
|
"tips": [
|
||||||
|
"Le solde est calculé comme les revenus moins les dépenses pour la période sélectionnée",
|
||||||
|
"Cliquez sur une catégorie dans le graphique circulaire pour voir ses transactions"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"import": {
|
||||||
|
"title": "Import",
|
||||||
|
"overview": "Importez des relevés bancaires à partir de fichiers CSV à l'aide d'un assistant étape par étape. Chaque compte bancaire est représenté par un dossier source.",
|
||||||
|
"features": [
|
||||||
|
"Assistant d'import multi-étapes avec aperçu des données",
|
||||||
|
"Mapping de colonnes configurable, délimiteur et format de date",
|
||||||
|
"Détection automatique des doublons (dans le lot et contre les données existantes)",
|
||||||
|
"Modèles d'import pour sauvegarder et réutiliser les configurations",
|
||||||
|
"Historique des imports avec possibilité de supprimer les imports précédents"
|
||||||
|
],
|
||||||
|
"steps": [
|
||||||
|
"Définissez votre dossier d'import via le sélecteur de dossier en haut de la page",
|
||||||
|
"Créez un sous-dossier pour chaque banque/source et placez-y les fichiers CSV",
|
||||||
|
"Cliquez sur une source pour ouvrir l'assistant d'import",
|
||||||
|
"Configurez le délimiteur, l'encodage, le format de date et le mapping des colonnes",
|
||||||
|
"Sélectionnez les fichiers à importer et prévisualisez les données analysées",
|
||||||
|
"Vérifiez les doublons, examinez le résumé, puis confirmez l'import"
|
||||||
|
],
|
||||||
|
"tips": [
|
||||||
|
"Sauvegardez votre configuration comme modèle pour ne pas avoir à reconfigurer à chaque fois",
|
||||||
|
"Les fichiers déjà importés sont marqués d'un badge — les ré-importer déclenchera la détection de doublons",
|
||||||
|
"Vous pouvez supprimer un import de l'historique pour retirer toutes ses transactions"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"transactions": {
|
||||||
|
"title": "Transactions",
|
||||||
|
"overview": "Parcourez, filtrez, triez et catégorisez toutes vos transactions importées. C'est ici que vous organisez vos données financières.",
|
||||||
|
"features": [
|
||||||
|
"Recherche et filtre par description, catégorie, source ou plage de dates",
|
||||||
|
"Sélecteurs de période rapides (ce mois, mois dernier, cette année, etc.)",
|
||||||
|
"Colonnes triables (date, description, montant, catégorie)",
|
||||||
|
"Assignation de catégorie en ligne via menu déroulant",
|
||||||
|
"Auto-catégorisation basée sur les règles de mots-clés",
|
||||||
|
"Ajout de mots-clés directement depuis une transaction",
|
||||||
|
"Notes sur les transactions"
|
||||||
|
],
|
||||||
|
"steps": [
|
||||||
|
"Utilisez la barre de filtres pour affiner les transactions par texte, catégorie, source ou date",
|
||||||
|
"Cliquez sur un en-tête de colonne pour trier par ordre croissant ou décroissant",
|
||||||
|
"Pour catégoriser une transaction, cliquez sur son menu déroulant de catégorie et sélectionnez une catégorie",
|
||||||
|
"Pour auto-catégoriser toutes les transactions non catégorisées, cliquez sur le bouton Auto-catégoriser",
|
||||||
|
"Pour ajouter une règle de mot-clé depuis une transaction, cliquez sur l'icône + et entrez le mot-clé"
|
||||||
|
],
|
||||||
|
"tips": [
|
||||||
|
"Utilisez les boutons de période rapide (Ce mois, Mois dernier, etc.) pour filtrer rapidement par date",
|
||||||
|
"L'auto-catégorisation n'affecte que les transactions non catégorisées — elle n'écrase pas les assignations manuelles",
|
||||||
|
"Ajouter un mot-clé depuis une transaction pré-remplit la catégorie pour construire rapidement vos règles"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"categories": {
|
||||||
|
"title": "Catégories",
|
||||||
|
"overview": "Gérez votre arbre de catégories avec des sous-catégories, des règles de mots-clés pour l'auto-catégorisation et des couleurs personnalisées.",
|
||||||
|
"features": [
|
||||||
|
"Catégories hiérarchiques avec relations parent/enfant",
|
||||||
|
"Trois types de catégories : Dépense, Revenu, Transfert",
|
||||||
|
"Règles de mots-clés avec niveaux de priorité pour l'auto-catégorisation",
|
||||||
|
"Couleurs personnalisées pour l'affichage des graphiques",
|
||||||
|
"Basculer les catégories en saisissable ou non-saisissable",
|
||||||
|
"Réinitialiser les catégories aux valeurs par défaut"
|
||||||
|
],
|
||||||
|
"steps": [
|
||||||
|
"Cliquez sur Ajouter une catégorie pour créer une nouvelle catégorie — choisissez un nom, un type et un parent optionnel",
|
||||||
|
"Sélectionnez une catégorie dans l'arbre pour voir ses détails et sa liste de mots-clés",
|
||||||
|
"Ajoutez des mots-clés correspondant aux descriptions des transactions pour l'auto-catégorisation",
|
||||||
|
"Définissez la priorité des mots-clés pour résoudre les conflits quand plusieurs catégories correspondent",
|
||||||
|
"Utilisez le sélecteur de couleur pour assigner une couleur personnalisée pour les graphiques"
|
||||||
|
],
|
||||||
|
"tips": [
|
||||||
|
"Les catégories non-saisissables sont masquées du budget et des menus déroulants mais restent visibles dans les rapports",
|
||||||
|
"Les mots-clés de priorité supérieure l'emportent quand plusieurs catégories correspondent à la même transaction",
|
||||||
|
"Utilisez Réinitialiser pour revenir aux catégories par défaut — cela dissociera toutes les catégories des transactions"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"adjustments": {
|
||||||
|
"title": "Ajustements",
|
||||||
|
"overview": "Ajoutez des entrées manuelles non issues de vos relevés bancaires — utile pour les dépenses prévues, revenus ou corrections pas encore dans vos relevés.",
|
||||||
|
"features": [
|
||||||
|
"Créer des groupes d'ajustement nommés avec plusieurs entrées",
|
||||||
|
"Assigner une catégorie à chaque entrée",
|
||||||
|
"Marquer des ajustements comme récurrents"
|
||||||
|
],
|
||||||
|
"steps": [
|
||||||
|
"Cliquez sur Nouvel ajustement pour créer un groupe d'ajustement",
|
||||||
|
"Ajoutez des entrées avec une description, un montant, une date et une catégorie",
|
||||||
|
"Activez le drapeau récurrent si l'ajustement doit se répéter à chaque période"
|
||||||
|
],
|
||||||
|
"tips": [
|
||||||
|
"Les ajustements apparaissent dans vos réels de budget aux côtés des transactions importées",
|
||||||
|
"Utilisez les ajustements pour les dépenses prévues qui n'ont pas encore été débitées de votre compte"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"budget": {
|
||||||
|
"title": "Budget",
|
||||||
|
"overview": "Planifiez votre budget mensuel pour chaque catégorie et suivez le prévu par rapport au réel tout au long de l'année.",
|
||||||
|
"features": [
|
||||||
|
"Grille budgétaire mensuelle pour toutes les catégories",
|
||||||
|
"Colonne annuelle avec totaux automatiques",
|
||||||
|
"Répartition égale du montant annuel sur 12 mois",
|
||||||
|
"Modèles de budget pour sauvegarder et appliquer des configurations",
|
||||||
|
"Sous-totaux par catégorie parente"
|
||||||
|
],
|
||||||
|
"steps": [
|
||||||
|
"Utilisez le navigateur d'année pour sélectionner l'année du budget",
|
||||||
|
"Cliquez sur une cellule de mois pour entrer un montant prévu",
|
||||||
|
"Appuyez sur Entrée pour sauvegarder, Échap pour annuler, ou Tab pour passer au mois suivant",
|
||||||
|
"Utilisez le bouton de répartition (sur la colonne Annuel) pour distribuer également sur tous les mois",
|
||||||
|
"Sauvegardez votre budget comme modèle pour le réutiliser les années suivantes"
|
||||||
|
],
|
||||||
|
"tips": [
|
||||||
|
"La colonne Annuel additionne automatiquement les 12 mois — un avertissement apparaît si les totaux mensuels ne correspondent pas",
|
||||||
|
"Les modèles peuvent être appliqués à des mois spécifiques ou aux 12 mois d'un coup",
|
||||||
|
"Les catégories parentes affichent les sous-totaux agrégés de leurs enfants"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"reports": {
|
||||||
|
"title": "Rapports",
|
||||||
|
"overview": "Visualisez vos données financières avec des graphiques interactifs et comparez votre plan budgétaire au réel.",
|
||||||
|
"features": [
|
||||||
|
"Tendances mensuelles : revenus vs dépenses dans le temps (graphique en barres)",
|
||||||
|
"Dépenses par catégorie : répartition des dépenses (graphique circulaire)",
|
||||||
|
"Catégories dans le temps : suivez l'évolution de chaque catégorie (graphique en ligne)",
|
||||||
|
"Budget vs Réel : tableau comparatif mensuel et cumul annuel"
|
||||||
|
],
|
||||||
|
"steps": [
|
||||||
|
"Utilisez les onglets pour basculer entre Tendances, Par catégorie, Dans le temps et Budget vs Réel",
|
||||||
|
"Ajustez la période avec le sélecteur de période",
|
||||||
|
"Dans le graphique circulaire, cliquez sur une catégorie pour la masquer/afficher",
|
||||||
|
"Dans Budget vs Réel, basculez entre les vues Mensuel et Cumul annuel"
|
||||||
|
],
|
||||||
|
"tips": [
|
||||||
|
"Les catégories masquées sont mémorisées tant que vous restez sur la page — cliquez sur Tout afficher pour réinitialiser",
|
||||||
|
"Le sélecteur de période s'applique à tous les onglets de graphiques simultanément",
|
||||||
|
"Budget vs Réel affiche l'écart en dollars et en pourcentage pour chaque catégorie"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"settings": {
|
||||||
|
"title": "Paramètres",
|
||||||
|
"overview": "Configurez les préférences de l'application, vérifiez les mises à jour et gérez vos données avec les outils d'export/import.",
|
||||||
|
"features": [
|
||||||
|
"Affichage de la version de l'application",
|
||||||
|
"Vérification automatique des mises à jour avec installation en un clic",
|
||||||
|
"Export des données (transactions, catégories, ou les deux) en format JSON ou CSV",
|
||||||
|
"Import des données depuis un fichier exporté précédemment",
|
||||||
|
"Chiffrement optionnel pour les fichiers exportés"
|
||||||
|
],
|
||||||
|
"steps": [
|
||||||
|
"Cliquez sur Vérifier les mises à jour pour voir si une nouvelle version est disponible",
|
||||||
|
"Utilisez la section Gestion des données pour exporter ou importer vos données",
|
||||||
|
"Lors de l'export, choisissez ce qu'il faut inclure et définissez optionnellement un mot de passe pour le chiffrement",
|
||||||
|
"Lors de l'import, sélectionnez un fichier exporté précédemment — les fichiers chiffrés demanderont le mot de passe"
|
||||||
|
],
|
||||||
|
"tips": [
|
||||||
|
"Les mises à jour ne remplacent que le programme — votre base de données n'est jamais modifiée",
|
||||||
|
"Changez la langue de l'application via le sélecteur de langue dans la barre latérale",
|
||||||
|
"Exportez régulièrement pour garder une sauvegarde de vos données"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
"common": {
|
"common": {
|
||||||
"save": "Enregistrer",
|
"save": "Enregistrer",
|
||||||
"cancel": "Annuler",
|
"cancel": "Annuler",
|
||||||
|
|
|
||||||
228
src/pages/DocsPage.tsx
Normal file
228
src/pages/DocsPage.tsx
Normal file
|
|
@ -0,0 +1,228 @@
|
||||||
|
import { useEffect, useRef, useState } from "react";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { Link, useLocation } from "react-router-dom";
|
||||||
|
import {
|
||||||
|
Rocket,
|
||||||
|
LayoutDashboard,
|
||||||
|
Upload,
|
||||||
|
ArrowLeftRight,
|
||||||
|
Tags,
|
||||||
|
SlidersHorizontal,
|
||||||
|
PiggyBank,
|
||||||
|
BarChart3,
|
||||||
|
Settings,
|
||||||
|
ArrowLeft,
|
||||||
|
Lightbulb,
|
||||||
|
ListChecks,
|
||||||
|
Footprints,
|
||||||
|
Printer,
|
||||||
|
} from "lucide-react";
|
||||||
|
|
||||||
|
const SECTIONS = [
|
||||||
|
{ key: "gettingStarted", icon: Rocket },
|
||||||
|
{ key: "dashboard", icon: LayoutDashboard },
|
||||||
|
{ key: "import", icon: Upload },
|
||||||
|
{ key: "transactions", icon: ArrowLeftRight },
|
||||||
|
{ key: "categories", icon: Tags },
|
||||||
|
{ key: "adjustments", icon: SlidersHorizontal },
|
||||||
|
{ key: "budget", icon: PiggyBank },
|
||||||
|
{ key: "reports", icon: BarChart3 },
|
||||||
|
{ key: "settings", icon: Settings },
|
||||||
|
] as const;
|
||||||
|
|
||||||
|
export default function DocsPage() {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const location = useLocation();
|
||||||
|
const [activeSection, setActiveSection] = useState<string>(SECTIONS[0].key);
|
||||||
|
const sectionRefs = useRef<Record<string, HTMLElement | null>>({});
|
||||||
|
const contentRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
|
// Scroll spy via IntersectionObserver
|
||||||
|
useEffect(() => {
|
||||||
|
const container = contentRef.current;
|
||||||
|
if (!container) return;
|
||||||
|
|
||||||
|
const observer = new IntersectionObserver(
|
||||||
|
(entries) => {
|
||||||
|
for (const entry of entries) {
|
||||||
|
if (entry.isIntersecting) {
|
||||||
|
setActiveSection(entry.target.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
root: container,
|
||||||
|
rootMargin: "-10% 0px -80% 0px",
|
||||||
|
threshold: 0,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
for (const { key } of SECTIONS) {
|
||||||
|
const el = sectionRefs.current[key];
|
||||||
|
if (el) observer.observe(el);
|
||||||
|
}
|
||||||
|
|
||||||
|
return () => observer.disconnect();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// Handle initial anchor from URL
|
||||||
|
useEffect(() => {
|
||||||
|
const hash = location.hash.replace("#", "");
|
||||||
|
if (hash && sectionRefs.current[hash]) {
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
sectionRefs.current[hash]?.scrollIntoView({ behavior: "smooth" });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [location.hash]);
|
||||||
|
|
||||||
|
const scrollToSection = (key: string) => {
|
||||||
|
sectionRefs.current[key]?.scrollIntoView({ behavior: "smooth" });
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex h-full overflow-hidden">
|
||||||
|
{/* Sidebar TOC */}
|
||||||
|
<nav className="w-56 shrink-0 border-r border-[var(--border)] p-4 overflow-y-auto">
|
||||||
|
<Link
|
||||||
|
to="/settings"
|
||||||
|
className="flex items-center gap-2 text-sm text-[var(--muted-foreground)] hover:text-[var(--foreground)] transition-colors mb-4"
|
||||||
|
>
|
||||||
|
<ArrowLeft size={14} />
|
||||||
|
{t("docs.backToSettings")}
|
||||||
|
</Link>
|
||||||
|
|
||||||
|
<h2 className="text-sm font-semibold text-[var(--muted-foreground)] uppercase tracking-wider mb-3">
|
||||||
|
{t("docs.title")}
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
<ul className="space-y-1">
|
||||||
|
{SECTIONS.map(({ key, icon: Icon }) => (
|
||||||
|
<li key={key}>
|
||||||
|
<button
|
||||||
|
onClick={() => scrollToSection(key)}
|
||||||
|
className={`flex items-center gap-2 w-full text-left px-3 py-2 rounded-lg text-sm transition-colors ${
|
||||||
|
activeSection === key
|
||||||
|
? "bg-[var(--primary)] text-white font-medium"
|
||||||
|
: "text-[var(--muted-foreground)] hover:bg-[var(--border)] hover:text-[var(--foreground)]"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<Icon size={15} />
|
||||||
|
{t(`docs.${key}.title`)}
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
{/* Scrollable content */}
|
||||||
|
<div ref={contentRef} className="flex-1 overflow-y-auto p-6">
|
||||||
|
<div className="max-w-3xl mx-auto space-y-6">
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<h1 className="text-2xl font-bold">{t("docs.title")}</h1>
|
||||||
|
<button
|
||||||
|
onClick={() => window.print()}
|
||||||
|
className="print:hidden flex items-center gap-2 px-3 py-2 text-sm rounded-lg bg-[var(--card)] border border-[var(--border)] text-[var(--muted-foreground)] hover:text-[var(--foreground)] hover:bg-[var(--muted)] transition-colors"
|
||||||
|
title={t("docs.print")}
|
||||||
|
>
|
||||||
|
<Printer size={16} />
|
||||||
|
{t("docs.print")}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{SECTIONS.map(({ key, icon: Icon }) => (
|
||||||
|
<section
|
||||||
|
key={key}
|
||||||
|
id={key}
|
||||||
|
ref={(el) => {
|
||||||
|
sectionRefs.current[key] = el;
|
||||||
|
}}
|
||||||
|
className="bg-[var(--card)] border border-[var(--border)] rounded-xl p-6 space-y-4"
|
||||||
|
>
|
||||||
|
{/* Section header */}
|
||||||
|
<div className="flex items-center gap-3">
|
||||||
|
<div className="w-9 h-9 rounded-lg bg-[var(--primary)]/10 flex items-center justify-center text-[var(--primary)]">
|
||||||
|
<Icon size={20} />
|
||||||
|
</div>
|
||||||
|
<h2 className="text-lg font-semibold">
|
||||||
|
{t(`docs.${key}.title`)}
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Overview */}
|
||||||
|
<p className="text-[var(--muted-foreground)]">
|
||||||
|
{t(`docs.${key}.overview`)}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
{/* Features */}
|
||||||
|
<div>
|
||||||
|
<h3 className="flex items-center gap-2 text-sm font-semibold uppercase tracking-wider text-[var(--muted-foreground)] mb-2">
|
||||||
|
<ListChecks size={14} />
|
||||||
|
{t("docs.features")}
|
||||||
|
</h3>
|
||||||
|
<ul className="space-y-1">
|
||||||
|
{(
|
||||||
|
t(`docs.${key}.features`, {
|
||||||
|
returnObjects: true,
|
||||||
|
}) as string[]
|
||||||
|
).map((item, i) => (
|
||||||
|
<li
|
||||||
|
key={i}
|
||||||
|
className="flex items-start gap-2 text-sm"
|
||||||
|
>
|
||||||
|
<span className="text-[var(--primary)] mt-0.5 shrink-0">•</span>
|
||||||
|
{item}
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Steps */}
|
||||||
|
<div>
|
||||||
|
<h3 className="flex items-center gap-2 text-sm font-semibold uppercase tracking-wider text-[var(--muted-foreground)] mb-2">
|
||||||
|
<Footprints size={14} />
|
||||||
|
{key === "gettingStarted"
|
||||||
|
? t("docs.quickStart")
|
||||||
|
: t("docs.howTo")}
|
||||||
|
</h3>
|
||||||
|
<ol className="space-y-1 list-decimal list-inside">
|
||||||
|
{(
|
||||||
|
t(`docs.${key}.steps`, {
|
||||||
|
returnObjects: true,
|
||||||
|
}) as string[]
|
||||||
|
).map((item, i) => (
|
||||||
|
<li key={i} className="text-sm">
|
||||||
|
{item}
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Tips */}
|
||||||
|
<div className="bg-[var(--background)] rounded-lg p-4">
|
||||||
|
<h3 className="flex items-center gap-2 text-sm font-semibold uppercase tracking-wider text-[var(--muted-foreground)] mb-2">
|
||||||
|
<Lightbulb size={14} />
|
||||||
|
{t("docs.tipsHeader")}
|
||||||
|
</h3>
|
||||||
|
<ul className="space-y-1">
|
||||||
|
{(
|
||||||
|
t(`docs.${key}.tips`, {
|
||||||
|
returnObjects: true,
|
||||||
|
}) as string[]
|
||||||
|
).map((item, i) => (
|
||||||
|
<li
|
||||||
|
key={i}
|
||||||
|
className="flex items-start gap-2 text-sm text-[var(--muted-foreground)]"
|
||||||
|
>
|
||||||
|
<Lightbulb size={13} className="text-[var(--primary)] mt-0.5 shrink-0" />
|
||||||
|
{item}
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -9,9 +9,12 @@ import {
|
||||||
RotateCcw,
|
RotateCcw,
|
||||||
Loader2,
|
Loader2,
|
||||||
ShieldCheck,
|
ShieldCheck,
|
||||||
|
BookOpen,
|
||||||
|
ChevronRight,
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
import { getVersion } from "@tauri-apps/api/app";
|
import { getVersion } from "@tauri-apps/api/app";
|
||||||
import { useUpdater } from "../hooks/useUpdater";
|
import { useUpdater } from "../hooks/useUpdater";
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
import { APP_NAME } from "../shared/constants";
|
import { APP_NAME } from "../shared/constants";
|
||||||
import { PageHelp } from "../components/shared/PageHelp";
|
import { PageHelp } from "../components/shared/PageHelp";
|
||||||
import DataManagementCard from "../components/settings/DataManagementCard";
|
import DataManagementCard from "../components/settings/DataManagementCard";
|
||||||
|
|
@ -53,6 +56,27 @@ export default function SettingsPage() {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* User guide card */}
|
||||||
|
<Link
|
||||||
|
to="/docs"
|
||||||
|
className="block bg-[var(--card)] border border-[var(--border)] rounded-xl p-6 hover:border-[var(--primary)] transition-colors group"
|
||||||
|
>
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<div className="flex items-center gap-4">
|
||||||
|
<div className="w-12 h-12 rounded-xl bg-[var(--primary)]/10 flex items-center justify-center text-[var(--primary)]">
|
||||||
|
<BookOpen size={22} />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h2 className="text-lg font-semibold">{t("settings.userGuide.title")}</h2>
|
||||||
|
<p className="text-sm text-[var(--muted-foreground)]">
|
||||||
|
{t("settings.userGuide.description")}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<ChevronRight size={18} className="text-[var(--muted-foreground)] group-hover:text-[var(--primary)] transition-colors" />
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
|
||||||
{/* Update card */}
|
{/* Update card */}
|
||||||
<div className="bg-[var(--card)] border border-[var(--border)] rounded-xl p-6 space-y-4">
|
<div className="bg-[var(--card)] border border-[var(--border)] rounded-xl p-6 space-y-4">
|
||||||
<h2 className="text-lg font-semibold flex items-center gap-2">
|
<h2 className="text-lg font-semibold flex items-center gap-2">
|
||||||
|
|
|
||||||
|
|
@ -100,6 +100,41 @@ body {
|
||||||
transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
|
transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Print styles */
|
||||||
|
@media print {
|
||||||
|
/* Hide app sidebar and docs TOC */
|
||||||
|
aside,
|
||||||
|
nav.w-56 {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove screen layout constraints */
|
||||||
|
.h-screen,
|
||||||
|
.overflow-hidden,
|
||||||
|
.overflow-y-auto {
|
||||||
|
height: auto !important;
|
||||||
|
overflow: visible !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* White background for print */
|
||||||
|
body,
|
||||||
|
:root {
|
||||||
|
background: white !important;
|
||||||
|
color: black !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clean section breaks */
|
||||||
|
section {
|
||||||
|
break-inside: avoid;
|
||||||
|
border-color: #e5e7eb !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Disable transitions for print */
|
||||||
|
*, *::before, *::after {
|
||||||
|
transition: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Scrollbar styling */
|
/* Scrollbar styling */
|
||||||
::-webkit-scrollbar {
|
::-webkit-scrollbar {
|
||||||
width: 6px;
|
width: 6px;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue