Merge pull request 'feat: Add online user guide with screenshots (#203)' (#204) from issue-203-add-online-user-guide into main
All checks were successful
Deploy to Staging / Build Images (push) Successful in 37s
Deploy to Staging / Deploy to Staging (push) Successful in 52s
Deploy to Staging / Verify Staging (push) Successful in 9s
Deploy to Staging / Notify Staging Ready (push) Successful in 9s
Deploy to Staging / Notify Staging Failure (push) Has been skipped
Reviewed-on: #204
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"testModules": [
|
||||
{
|
||||
"moduleId": "/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/src/features/dashboard/hooks/__tests__/useDashboardData.test.ts",
|
||||
"moduleId": "/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/src/pages/__tests__/GuidePage.test.tsx",
|
||||
"tests": [
|
||||
{
|
||||
"name": "Module failed to load (Error)",
|
||||
@@ -11,58 +11,7 @@
|
||||
{
|
||||
"message": "File not found: tsconfig.json (resolved as: /Users/egullickson/Documents/Technology/coding/motovaultpro/tsconfig.json)",
|
||||
"name": "Error",
|
||||
"stack": "Error: File not found: tsconfig.json (resolved as: /Users/egullickson/Documents/Technology/coding/motovaultpro/tsconfig.json)\n at ConfigSet.resolvePath (/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/node_modules/ts-jest/dist/legacy/config/config-set.js:616:19)\n at ConfigSet._setupConfigSet (/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/node_modules/ts-jest/dist/legacy/config/config-set.js:322:71)\n at new ConfigSet (/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/node_modules/ts-jest/dist/legacy/config/config-set.js:206:14)\n at TsJestTransformer._createConfigSet (/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/node_modules/ts-jest/dist/legacy/ts-jest-transformer.js:119:16)\n at TsJestTransformer._configsFor (/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/node_modules/ts-jest/dist/legacy/ts-jest-transformer.js:98:34)\n at TsJestTransformer.getCacheKey (/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/node_modules/ts-jest/dist/legacy/ts-jest-transformer.js:249:30)\n at ScriptTransformer._getCacheKey (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/@jest/transform/build/index.js:195:41)\n at ScriptTransformer._getFileCachePath (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/@jest/transform/build/index.js:231:27)\n at ScriptTransformer.transformSource (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/@jest/transform/build/index.js:402:32)\n at ScriptTransformer._transformAndBuildScript (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/@jest/transform/build/index.js:519:40)\n at ScriptTransformer.transform (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/@jest/transform/build/index.js:558:19)\n at Runtime.transformFile (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/jest-runtime/build/index.js:1290:53)\n at Runtime._execModule (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/jest-runtime/build/index.js:1243:34)\n at Runtime._loadModule (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/jest-runtime/build/index.js:944:12)\n at Runtime.requireModule (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/jest-runtime/build/index.js:832:12)\n at jestAdapter (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/jest-circus/build/runner.js:84:33)\n at processTicksAndRejections (node:internal/process/task_queues:104:5)\n at runTestInternal (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/jest-runner/build/testWorker.js:275:16)\n at runTest (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/jest-runner/build/testWorker.js:343:7)\n at Object.worker (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/jest-runner/build/testWorker.js:497:12)"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"moduleId": "/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/src/features/dashboard/components/__tests__/DashboardScreen.test.tsx",
|
||||
"tests": [
|
||||
{
|
||||
"name": "Module failed to load (Error)",
|
||||
"fullName": "Module failed to load (Error)",
|
||||
"state": "failed",
|
||||
"errors": [
|
||||
{
|
||||
"message": "File not found: tsconfig.json (resolved as: /Users/egullickson/Documents/Technology/coding/motovaultpro/tsconfig.json)",
|
||||
"name": "Error",
|
||||
"stack": "Error: File not found: tsconfig.json (resolved as: /Users/egullickson/Documents/Technology/coding/motovaultpro/tsconfig.json)\n at ConfigSet.resolvePath (/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/node_modules/ts-jest/dist/legacy/config/config-set.js:616:19)\n at ConfigSet._setupConfigSet (/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/node_modules/ts-jest/dist/legacy/config/config-set.js:322:71)\n at new ConfigSet (/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/node_modules/ts-jest/dist/legacy/config/config-set.js:206:14)\n at TsJestTransformer._createConfigSet (/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/node_modules/ts-jest/dist/legacy/ts-jest-transformer.js:119:16)\n at TsJestTransformer._configsFor (/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/node_modules/ts-jest/dist/legacy/ts-jest-transformer.js:98:34)\n at TsJestTransformer.getCacheKey (/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/node_modules/ts-jest/dist/legacy/ts-jest-transformer.js:249:30)\n at ScriptTransformer._getCacheKey (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/@jest/transform/build/index.js:195:41)\n at ScriptTransformer._getFileCachePath (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/@jest/transform/build/index.js:231:27)\n at ScriptTransformer.transformSource (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/@jest/transform/build/index.js:402:32)\n at ScriptTransformer._transformAndBuildScript (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/@jest/transform/build/index.js:519:40)\n at ScriptTransformer.transform (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/@jest/transform/build/index.js:558:19)\n at Runtime.transformFile (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/jest-runtime/build/index.js:1290:53)\n at Runtime._execModule (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/jest-runtime/build/index.js:1243:34)\n at Runtime._loadModule (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/jest-runtime/build/index.js:944:12)\n at Runtime.requireModule (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/jest-runtime/build/index.js:832:12)\n at jestAdapter (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/jest-circus/build/runner.js:84:33)\n at processTicksAndRejections (node:internal/process/task_queues:104:5)\n at runTestInternal (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/jest-runner/build/testWorker.js:275:16)\n at runTest (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/jest-runner/build/testWorker.js:343:7)\n at Object.worker (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/jest-runner/build/testWorker.js:497:12)"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"moduleId": "/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/src/features/dashboard/components/__tests__/ActionBar.test.tsx",
|
||||
"tests": [
|
||||
{
|
||||
"name": "Module failed to load (Error)",
|
||||
"fullName": "Module failed to load (Error)",
|
||||
"state": "failed",
|
||||
"errors": [
|
||||
{
|
||||
"message": "File not found: tsconfig.json (resolved as: /Users/egullickson/Documents/Technology/coding/motovaultpro/tsconfig.json)",
|
||||
"name": "Error",
|
||||
"stack": "Error: File not found: tsconfig.json (resolved as: /Users/egullickson/Documents/Technology/coding/motovaultpro/tsconfig.json)\n at ConfigSet.resolvePath (/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/node_modules/ts-jest/dist/legacy/config/config-set.js:616:19)\n at ConfigSet._setupConfigSet (/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/node_modules/ts-jest/dist/legacy/config/config-set.js:322:71)\n at new ConfigSet (/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/node_modules/ts-jest/dist/legacy/config/config-set.js:206:14)\n at TsJestTransformer._createConfigSet (/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/node_modules/ts-jest/dist/legacy/ts-jest-transformer.js:119:16)\n at TsJestTransformer._configsFor (/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/node_modules/ts-jest/dist/legacy/ts-jest-transformer.js:98:34)\n at TsJestTransformer.getCacheKey (/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/node_modules/ts-jest/dist/legacy/ts-jest-transformer.js:249:30)\n at ScriptTransformer._getCacheKey (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/@jest/transform/build/index.js:195:41)\n at ScriptTransformer._getFileCachePath (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/@jest/transform/build/index.js:231:27)\n at ScriptTransformer.transformSource (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/@jest/transform/build/index.js:402:32)\n at ScriptTransformer._transformAndBuildScript (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/@jest/transform/build/index.js:519:40)\n at ScriptTransformer.transform (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/@jest/transform/build/index.js:558:19)\n at Runtime.transformFile (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/jest-runtime/build/index.js:1290:53)\n at Runtime._execModule (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/jest-runtime/build/index.js:1243:34)\n at Runtime._loadModule (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/jest-runtime/build/index.js:944:12)\n at Runtime.requireModule (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/jest-runtime/build/index.js:832:12)\n at jestAdapter (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/jest-circus/build/runner.js:84:33)\n at processTicksAndRejections (node:internal/process/task_queues:104:5)\n at runTestInternal (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/jest-runner/build/testWorker.js:275:16)\n at runTest (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/jest-runner/build/testWorker.js:343:7)\n at Object.worker (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/jest-runner/build/testWorker.js:497:12)"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"moduleId": "/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/src/features/dashboard/components/__tests__/VehicleRosterCard.test.tsx",
|
||||
"tests": [
|
||||
{
|
||||
"name": "Module failed to load (Error)",
|
||||
"fullName": "Module failed to load (Error)",
|
||||
"state": "failed",
|
||||
"errors": [
|
||||
{
|
||||
"message": "File not found: tsconfig.json (resolved as: /Users/egullickson/Documents/Technology/coding/motovaultpro/tsconfig.json)",
|
||||
"name": "Error",
|
||||
"stack": "Error: File not found: tsconfig.json (resolved as: /Users/egullickson/Documents/Technology/coding/motovaultpro/tsconfig.json)\n at ConfigSet.resolvePath (/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/node_modules/ts-jest/dist/legacy/config/config-set.js:616:19)\n at ConfigSet._setupConfigSet (/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/node_modules/ts-jest/dist/legacy/config/config-set.js:322:71)\n at new ConfigSet (/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/node_modules/ts-jest/dist/legacy/config/config-set.js:206:14)\n at TsJestTransformer._createConfigSet (/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/node_modules/ts-jest/dist/legacy/ts-jest-transformer.js:119:16)\n at TsJestTransformer._configsFor (/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/node_modules/ts-jest/dist/legacy/ts-jest-transformer.js:98:34)\n at TsJestTransformer.getCacheKey (/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/node_modules/ts-jest/dist/legacy/ts-jest-transformer.js:249:30)\n at ScriptTransformer._getCacheKey (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/@jest/transform/build/index.js:195:41)\n at ScriptTransformer._getFileCachePath (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/@jest/transform/build/index.js:231:27)\n at ScriptTransformer.transformSource (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/@jest/transform/build/index.js:402:32)\n at ScriptTransformer._transformAndBuildScript (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/@jest/transform/build/index.js:519:40)\n at ScriptTransformer.transform (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/@jest/transform/build/index.js:558:19)\n at Runtime.transformFile (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/jest-runtime/build/index.js:1290:53)\n at Runtime._execModule (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/jest-runtime/build/index.js:1243:34)\n at Runtime._loadModule (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/jest-runtime/build/index.js:944:12)\n at Runtime.requireModule (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/jest-runtime/build/index.js:832:12)\n at jestAdapter (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/jest-circus/build/runner.js:84:33)\n at processTicksAndRejections (node:internal/process/task_queues:104:5)\n at runTestInternal (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/jest-runner/build/testWorker.js:275:16)\n at runTest (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/jest-runner/build/testWorker.js:343:7)\n at Object.worker (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/jest-runner/build/testWorker.js:497:12)"
|
||||
"stack": "Error: File not found: tsconfig.json (resolved as: /Users/egullickson/Documents/Technology/coding/motovaultpro/tsconfig.json)\n at ConfigSet.resolvePath (/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/node_modules/ts-jest/dist/legacy/config/config-set.js:616:19)\n at ConfigSet._setupConfigSet (/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/node_modules/ts-jest/dist/legacy/config/config-set.js:322:71)\n at new ConfigSet (/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/node_modules/ts-jest/dist/legacy/config/config-set.js:206:14)\n at TsJestTransformer._createConfigSet (/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/node_modules/ts-jest/dist/legacy/ts-jest-transformer.js:119:16)\n at TsJestTransformer._configsFor (/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/node_modules/ts-jest/dist/legacy/ts-jest-transformer.js:98:34)\n at TsJestTransformer.getCacheKey (/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/node_modules/ts-jest/dist/legacy/ts-jest-transformer.js:249:30)\n at ScriptTransformer._getCacheKey (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/@jest/transform/build/index.js:195:41)\n at ScriptTransformer._getFileCachePath (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/@jest/transform/build/index.js:231:27)\n at ScriptTransformer.transformSource (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/@jest/transform/build/index.js:402:32)\n at ScriptTransformer._transformAndBuildScript (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/@jest/transform/build/index.js:519:40)\n at ScriptTransformer.transform (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/@jest/transform/build/index.js:558:19)\n at Runtime.transformFile (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/jest-runtime/build/index.js:1290:53)\n at Runtime._execModule (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/jest-runtime/build/index.js:1243:34)\n at Runtime._loadModule (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/jest-runtime/build/index.js:944:12)\n at Runtime.requireModule (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/jest-runtime/build/index.js:832:12)\n at jestAdapter (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/jest-circus/build/runner.js:84:33)\n at processTicksAndRejections (node:internal/process/task_queues:104:5)\n at runTestInternal (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/jest-runner/build/index.js:275:16)\n at runTest (/Users/egullickson/Documents/Technology/coding/motovaultpro/node_modules/jest-runner/build/index.js:343:7)"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
955
docs/USER-GUIDE.md
Normal file
@@ -0,0 +1,955 @@
|
||||
# MotoVaultPro User Guide
|
||||
|
||||
Precision Vehicle Management -- Track every mile. Own every detail.
|
||||
|
||||
MotoVaultPro is a cloud-based vehicle management platform for car enthusiasts and collectors. It tracks your entire fleet in one place: maintenance histories, fuel logs, documents, gas stations, and performance analytics.
|
||||
|
||||
This guide walks through every feature of the application.
|
||||
|
||||
---
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [Getting Started](#1-getting-started)
|
||||
- [Creating an Account](#creating-an-account)
|
||||
- [Logging In](#logging-in)
|
||||
- [Onboarding](#onboarding)
|
||||
- [Trouble Logging In](#trouble-logging-in)
|
||||
2. [Dashboard](#2-dashboard)
|
||||
- [Your Fleet Overview](#your-fleet-overview)
|
||||
- [Quick Actions](#quick-actions)
|
||||
3. [Vehicles](#3-vehicles)
|
||||
- [Viewing Your Vehicles](#viewing-your-vehicles)
|
||||
- [Adding a Vehicle](#adding-a-vehicle)
|
||||
- [VIN Decode](#vin-decode)
|
||||
- [Vehicle Detail Page](#vehicle-detail-page)
|
||||
- [Editing a Vehicle](#editing-a-vehicle)
|
||||
- [Deleting a Vehicle](#deleting-a-vehicle)
|
||||
4. [Fuel Logs](#4-fuel-logs)
|
||||
- [Fuel Logs Overview](#fuel-logs-overview)
|
||||
- [Logging Fuel](#logging-fuel)
|
||||
- [Receipt Scanning](#receipt-scanning)
|
||||
- [Editing and Deleting Fuel Logs](#editing-and-deleting-fuel-logs)
|
||||
5. [Maintenance](#5-maintenance)
|
||||
- [Maintenance Records](#maintenance-records)
|
||||
- [Adding a Maintenance Record](#adding-a-maintenance-record)
|
||||
- [Maintenance Schedules](#maintenance-schedules)
|
||||
- [Creating a Schedule](#creating-a-schedule)
|
||||
6. [Gas Stations](#6-gas-stations)
|
||||
- [Finding Stations](#finding-stations)
|
||||
- [Saved Stations](#saved-stations)
|
||||
- [Premium 93 Stations](#premium-93-stations)
|
||||
7. [Documents](#7-documents)
|
||||
- [Documents Overview](#documents-overview)
|
||||
- [Adding a Document](#adding-a-document)
|
||||
- [Document Types](#document-types)
|
||||
8. [Settings](#8-settings)
|
||||
- [Profile](#profile)
|
||||
- [Security and Privacy](#security-and-privacy)
|
||||
- [Subscription](#subscription)
|
||||
- [Notifications](#notifications)
|
||||
- [Appearance and Units](#appearance-and-units)
|
||||
- [Data Import and Export](#data-import-and-export)
|
||||
- [Account Actions](#account-actions)
|
||||
9. [Subscription Tiers and Pro Features](#9-subscription-tiers-and-pro-features)
|
||||
- [Tier Comparison](#tier-comparison)
|
||||
- [VIN Camera Scanning and Decode (Pro)](#vin-camera-scanning-and-decode-pro)
|
||||
- [Fuel Receipt Scanning (Pro)](#fuel-receipt-scanning-pro)
|
||||
- [Maintenance Receipt Scanning (Pro)](#maintenance-receipt-scanning-pro)
|
||||
- [Maintenance Manual PDF Extraction (Pro)](#maintenance-manual-pdf-extraction-pro)
|
||||
- [Email Ingestion (Pro)](#email-ingestion-pro)
|
||||
- [Shared Vehicle Documents (Pro)](#shared-vehicle-documents-pro)
|
||||
- [Community Station Submissions (Pro)](#community-station-submissions-pro)
|
||||
- [Managing Your Subscription](#managing-your-subscription)
|
||||
10. [Mobile Experience](#10-mobile-experience)
|
||||
|
||||
---
|
||||
|
||||
## 1. Getting Started
|
||||
|
||||
### Creating an Account
|
||||
|
||||
Navigate to [motovaultpro.com](https://motovaultpro.com) and click the **Sign Up** button in the top-right corner of the navigation bar.
|
||||
|
||||
**Sign Up Page**
|
||||
|
||||
The registration page displays the MotoVaultPro logo and a clean form with the following fields:
|
||||
|
||||
| Field | Required | Details |
|
||||
|-------|----------|---------|
|
||||
| Email Address | Yes | Your email address (e.g., your.email@example.com) |
|
||||
| Password | Yes | Minimum 8 characters, must include one uppercase letter and one number |
|
||||
| Confirm Password | Yes | Re-enter your password to confirm |
|
||||
| Terms & Conditions | Yes | Checkbox -- you must agree to the Terms & Conditions before creating your account |
|
||||
|
||||
After filling in all fields, click the **Create Account** button.
|
||||
|
||||
If you already have an account, click the **Login** link at the bottom of the form.
|
||||
|
||||
After registration, you will receive a verification email. Click the link in the email to verify your account before logging in.
|
||||
|
||||
### Logging In
|
||||
|
||||
Click the **Login** button in the top-right corner of the navigation bar. You will be redirected to the secure login page powered by Auth0.
|
||||
|
||||
**Login Page**
|
||||
|
||||
Enter your registered email address, then click **Continue**. On the next screen, enter your password and click **Continue** to log in.
|
||||
|
||||
After successful authentication, you will be redirected to the Dashboard.
|
||||
|
||||
### Onboarding
|
||||
|
||||
First-time users see an onboarding flow with three steps:
|
||||
|
||||
1. **Preferences** -- Choose your preferred unit system (Imperial or Metric), distance units, and notification preferences.
|
||||
2. **Add Your First Vehicle** -- Enter your first vehicle's details (you can skip this step and add vehicles later).
|
||||
3. **Complete** -- A welcome screen with quick links to get started exploring the app.
|
||||
|
||||
### Trouble Logging In
|
||||
|
||||
If you are having trouble logging in, try the following password reset and account recovery options.
|
||||
|
||||
---
|
||||
|
||||
## 2. Dashboard
|
||||
|
||||
After logging in, you land on the Dashboard -- your fleet headquarters.
|
||||
|
||||
**What You See**
|
||||
|
||||
The Dashboard displays a "Your Fleet" heading with all your vehicles shown as cards in a grid layout. Each vehicle card shows:
|
||||
|
||||
- **Vehicle icon** -- A small colored indicator badge (varies by vehicle)
|
||||
- **Vehicle name** -- The nickname or full name (e.g., "Beast", "MERLOT")
|
||||
- **Health status** -- A green dot indicates "All clear" (no overdue maintenance); other colors indicate attention needed
|
||||
- **Status text** -- "All clear" or a maintenance alert message
|
||||
- **Odometer reading** -- Current mileage (e.g., "35,000 mi")
|
||||
|
||||
**Click any vehicle card** to go directly to that vehicle's detail page.
|
||||
|
||||
### Quick Actions
|
||||
|
||||
Two action buttons appear in the top-right corner of the Dashboard:
|
||||
|
||||
| Button | Action |
|
||||
|--------|--------|
|
||||
| **+ Add Vehicle** | Opens the Add Vehicle form on the Vehicles page |
|
||||
| **LOG FUEL** | Opens the fuel logging modal to quickly record a fill-up |
|
||||
|
||||
These quick actions let you perform the most common tasks without navigating away from the Dashboard.
|
||||
|
||||
### Navigation Sidebar
|
||||
|
||||
The left sidebar provides access to all sections of the app:
|
||||
|
||||
| Menu Item | Description |
|
||||
|-----------|-------------|
|
||||
| **Dashboard** | Fleet overview (home) |
|
||||
| **Vehicles** | Manage your vehicle collection |
|
||||
| **Fuel Logs** | Track fuel purchases and efficiency |
|
||||
| **Maintenance** | Record service history and set schedules |
|
||||
| **Gas Stations** | Find and save gas stations |
|
||||
| **Documents** | Store vehicle-related documents |
|
||||
| **Settings** | Account, preferences, and data management |
|
||||
|
||||
At the bottom of the sidebar you will see your email address and a **Sign Out** button.
|
||||
|
||||
The header bar at the top shows a notification bell icon and a "Welcome back" greeting with your email.
|
||||
|
||||
---
|
||||
|
||||
## 3. Vehicles
|
||||
|
||||
### Viewing Your Vehicles
|
||||
|
||||
Click **Vehicles** in the sidebar to see the "My Vehicles" page. This page shows:
|
||||
|
||||
- **Search bar** -- Search vehicles by name, make, model, or VIN
|
||||
- **+ Add Vehicle** button -- Top-right corner
|
||||
- **Vehicle cards** in a grid layout (3 columns on desktop), each displaying:
|
||||
- Manufacturer logo (e.g., Chevrolet bowtie, GMC logo)
|
||||
- Vehicle nickname or full name
|
||||
- Year, Make, and Model
|
||||
- License plate number
|
||||
- Current odometer reading (in miles or kilometers)
|
||||
- **Edit** (pencil icon) and **Delete** (trash icon) buttons at the bottom of each card
|
||||
|
||||
### Adding a Vehicle
|
||||
|
||||
Click the **+ Add Vehicle** button to expand the "Add New Vehicle" form directly on the Vehicles page. The form has the following sections:
|
||||
|
||||
**Vehicle Photo**
|
||||
|
||||
Upload a photo of your vehicle. Click **ADD PHOTO** to select an image file.
|
||||
- Accepted formats: JPEG or PNG
|
||||
- Maximum file size: 5MB
|
||||
|
||||
**VIN Number**
|
||||
|
||||
Enter your vehicle's 17-character VIN (Vehicle Identification Number).
|
||||
- Type the VIN manually in the text field, OR
|
||||
- Click the **camera icon** to scan the VIN using your device camera (uses OCR technology)
|
||||
- Click the **Decode VIN** button to automatically populate vehicle details from the VIN
|
||||
|
||||
Note: VIN is optional if you provide a License Plate instead.
|
||||
|
||||
**Vehicle Specifications**
|
||||
|
||||
These fields use cascading dropdowns -- each selection narrows the options for the next field:
|
||||
|
||||
| Field | How It Works |
|
||||
|-------|-------------|
|
||||
| Year | Select the model year from the dropdown |
|
||||
| Make | Available after selecting Year (e.g., Chevrolet, GMC, Ford) |
|
||||
| Model | Available after selecting Make (e.g., Silverado, Camaro, Sierra) |
|
||||
| Trim | Available after selecting Model (e.g., LT Double Cab 4WD) |
|
||||
| Engine | Available after selecting Trim (e.g., 6.6L 401 HP V8) |
|
||||
| Transmission | Available after selecting Trim (e.g., 10-Speed Automatic) |
|
||||
|
||||
**Additional Details**
|
||||
|
||||
| Field | Example | Notes |
|
||||
|-------|---------|-------|
|
||||
| Nickname | Beast, Family Car | A friendly name for your vehicle |
|
||||
| Color | Black, Blue, Red | Vehicle color |
|
||||
| License Plate | ABC-123 | Required if VIN is not provided |
|
||||
| Current Odometer Reading | 50000 | Current mileage in your selected unit |
|
||||
|
||||
**Purchase Information**
|
||||
|
||||
| Field | Example | Notes |
|
||||
|-------|---------|-------|
|
||||
| Purchase Price | 25000 | What you paid for the vehicle |
|
||||
| Purchase Date | mm/dd/yyyy | When you purchased the vehicle |
|
||||
|
||||
Click **Add Vehicle** to save, or **Cancel** to discard.
|
||||
|
||||
### VIN Decode
|
||||
|
||||
> **Pro Feature:** VIN camera scanning and automatic decode require a Pro or Enterprise subscription. Free tier users can still type a VIN manually. See [VIN Camera Scanning and Decode (Pro)](#vin-camera-scanning-and-decode-pro) for full details.
|
||||
|
||||
The VIN Decode feature automatically fills in vehicle details from a VIN:
|
||||
|
||||
1. Enter or scan your 17-character VIN
|
||||
2. Click the **Decode VIN** button
|
||||
3. The system looks up the VIN and auto-populates: Year, Make, Model, Engine, Transmission, and Trim
|
||||
4. Review the pre-filled fields and make any corrections
|
||||
5. Continue filling in the remaining fields (Nickname, Color, etc.)
|
||||
|
||||
### Vehicle Detail Page
|
||||
|
||||
Click any vehicle card (from Dashboard or Vehicles list) to open the Vehicle Detail Page. This page shows everything about a single vehicle:
|
||||
|
||||
**Header Area**
|
||||
- Back arrow and **BACK** link to return to the previous page
|
||||
- Vehicle nickname as the page title (e.g., "Beast")
|
||||
- **Edit Vehicle** button (top-right)
|
||||
- Quick action buttons: **Add Fuel Log** and **Add Maintenance**
|
||||
|
||||
**Vehicle Details Section**
|
||||
- Manufacturer logo
|
||||
- Full vehicle description (e.g., "2022 Chevrolet Silverado 2500HD")
|
||||
- VIN Number
|
||||
- Year, Make, and Model (displayed in a 3-column row)
|
||||
- Trim, Engine, and Transmission (displayed in a 3-column row)
|
||||
- Nickname
|
||||
- Color and License Plate (side by side)
|
||||
- Current Odometer Reading
|
||||
|
||||
**Purchase Information Section**
|
||||
- Purchase Price
|
||||
- Purchase Date
|
||||
|
||||
**Ownership Costs Section**
|
||||
- Tracks insurance, registration, taxes, and other recurring vehicle costs
|
||||
- Shows "No ownership costs recorded yet" until costs are added
|
||||
|
||||
**Vehicle Records Section**
|
||||
- A table showing all records associated with this vehicle (fuel logs, maintenance records)
|
||||
- Columns: Date, Type, Summary, Amount, Actions
|
||||
- **Filter** dropdown to filter by record type (All, Fuel, Maintenance)
|
||||
|
||||
### Editing a Vehicle
|
||||
|
||||
From the Vehicle Detail Page, click the **Edit Vehicle** button. This opens the vehicle form pre-filled with the current values. Make your changes and save.
|
||||
|
||||
From the Vehicles list, click the **pencil icon** on any vehicle card to edit it directly.
|
||||
|
||||
### Deleting a Vehicle
|
||||
|
||||
From the Vehicles list, click the **trash icon** on any vehicle card. You will be asked to confirm the deletion. Deleting a vehicle is permanent and removes all associated records.
|
||||
|
||||
---
|
||||
|
||||
## 4. Fuel Logs
|
||||
|
||||
### Fuel Logs Overview
|
||||
|
||||
Click **Fuel Logs** in the sidebar to see the Fuel Logs page. At the top, you see summary statistics:
|
||||
|
||||
| Metric | Description |
|
||||
|--------|-------------|
|
||||
| **LOGS** | Total number of fuel entries |
|
||||
| **TOTAL FUEL** | Total gallons (or liters) across all fill-ups |
|
||||
| **TOTAL COST** | Total amount spent on fuel |
|
||||
|
||||
Below the summary, a table lists all your fuel log entries. If you have no entries yet, you will see "No fuel logs yet."
|
||||
|
||||
The **+ Add Fuel Log** button is in the top-right corner.
|
||||
|
||||
### Logging Fuel
|
||||
|
||||
Click **+ Add Fuel Log** (or the **LOG FUEL** button from the Dashboard) to open the "Log Fuel" modal. The modal title reads "Add Fuel Log" with a note showing your current unit system (e.g., "Displaying in Imperial (miles, gallons, MPG)").
|
||||
|
||||
**Receipt Scanning**
|
||||
|
||||
At the top of the form, click **SCAN RECEIPT** to use your camera to photograph a fuel receipt. The OCR system will automatically extract:
|
||||
- Fuel amount (gallons)
|
||||
- Cost per gallon
|
||||
- Total cost
|
||||
- Date and time
|
||||
- Fuel grade
|
||||
- Station name
|
||||
|
||||
You can review and edit any extracted values before saving.
|
||||
|
||||
**Form Fields**
|
||||
|
||||
| Field | Required | Description |
|
||||
|-------|----------|-------------|
|
||||
| Select Vehicle | Yes | Choose which vehicle this fill-up is for |
|
||||
| Date & Time | Yes | Pre-filled with the current date and time; click the calendar icon to change |
|
||||
| MPG | Auto | Calculated automatically from distance and fuel amount |
|
||||
| Trip Distance / Odometer Reading | One required | Toggle between entering trip distance (miles driven since last fill) or odometer reading. Click the toggle button to switch modes. |
|
||||
| Fuel Type | Yes | Dropdown: Gasoline, Diesel, Electric, Hybrid, etc. |
|
||||
| Fuel Grade | Optional | Dropdown: 87 (Regular), 89 (Midgrade), 91 (Premium), 93 (Premium), etc. |
|
||||
| Fuel Amount | Yes | Number of gallons (or liters) purchased |
|
||||
| Cost Per Gallon | Yes | Price per gallon (or liter) |
|
||||
| Total Cost | Auto | Calculated from Fuel Amount x Cost Per Gallon. Displays "Enter fuel amount and cost per unit to see total cost." until both values are provided. |
|
||||
| Location | Optional | Type a station name to search and select |
|
||||
| Notes | Optional | Any additional notes about this fill-up |
|
||||
|
||||
Click **Add Fuel Log** to save the entry. The button is disabled until all required fields are completed.
|
||||
|
||||
### Receipt Scanning
|
||||
|
||||
> **Pro Feature:** Receipt scanning requires a Pro or Enterprise subscription. See [Fuel Receipt Scanning (Pro)](#fuel-receipt-scanning-pro) for full details on what is extracted and the review workflow.
|
||||
|
||||
The receipt scanning feature uses OCR technology:
|
||||
|
||||
1. Click **SCAN RECEIPT** at the top of the Log Fuel form
|
||||
2. Use your camera to photograph the receipt
|
||||
3. The system extracts fuel data with confidence indicators
|
||||
4. A review modal appears showing extracted values
|
||||
5. Edit any incorrect values inline
|
||||
6. Click **Accept** to auto-fill the form, or **Reject** to enter manually
|
||||
|
||||
### Editing and Deleting Fuel Logs
|
||||
|
||||
From the fuel logs table, each entry has action buttons:
|
||||
- **Edit** -- Opens the fuel log in edit mode to update any fields
|
||||
- **Delete** -- Removes the fuel log entry (with confirmation)
|
||||
|
||||
---
|
||||
|
||||
## 5. Maintenance
|
||||
|
||||
Click **Maintenance** in the sidebar. This page has two tabs: **RECORDS** and **SCHEDULES**.
|
||||
|
||||
At the top is a **Vehicle** dropdown to select which vehicle you are viewing or adding maintenance for.
|
||||
|
||||
### Maintenance Records
|
||||
|
||||
The **RECORDS** tab shows your maintenance history for the selected vehicle. Below the list is the "Add Maintenance Record" form.
|
||||
|
||||
### Adding a Maintenance Record
|
||||
|
||||
The form on the RECORDS tab includes:
|
||||
|
||||
**Receipt Upload**
|
||||
|
||||
> **Pro Feature:** Maintenance receipt scanning requires a Pro or Enterprise subscription. See [Maintenance Receipt Scanning (Pro)](#maintenance-receipt-scanning-pro) for full details.
|
||||
|
||||
Click the **ADD RECEIPT** button (dashed outline area) to upload or photograph a maintenance receipt. The OCR system can extract:
|
||||
- Category and service type
|
||||
- Cost
|
||||
- Date
|
||||
- Shop name
|
||||
|
||||
**Form Fields**
|
||||
|
||||
| Field | Required | Description |
|
||||
|-------|----------|-------------|
|
||||
| Category | Yes | Dropdown with options: Routine Maintenance, Repair, Performance Upgrade. Each category has specific subtypes. |
|
||||
| Date | Yes | Pre-filled with today's date; click the calendar icon to change |
|
||||
| Odometer Reading | Optional | Vehicle mileage at time of service |
|
||||
| Cost | Optional | Total cost of the service (in $) |
|
||||
| Shop Name | Optional | Name of the service shop |
|
||||
| Notes | Optional | Additional details about the service (max 1,000 characters) |
|
||||
|
||||
Click **Add Record** to save the maintenance record.
|
||||
|
||||
**Maintenance Categories**
|
||||
|
||||
| Category | Example Services |
|
||||
|----------|-----------------|
|
||||
| Routine Maintenance | Oil change, air filter, tire rotation, battery, brakes, coolant flush, transmission fluid, spark plugs, fuel filter, cabin air filter, brake fluid, detailing |
|
||||
| Repair | Engine repair, transmission repair, brake repair, electrical, cooling system, suspension, steering, fuel system, body work, paint, glass |
|
||||
| Performance Upgrade | Engine tuning, suspension upgrade, wheels/tires, brake upgrade, exhaust, intake, lighting, audio |
|
||||
|
||||
### Maintenance Schedules
|
||||
|
||||
Click the **SCHEDULES** tab to set up recurring maintenance reminders.
|
||||
|
||||
### Creating a Schedule
|
||||
|
||||
The "Create Maintenance Schedule" form includes:
|
||||
|
||||
| Field | Required | Description |
|
||||
|-------|----------|-------------|
|
||||
| Category | Yes | Same categories as maintenance records |
|
||||
| Schedule Type | Yes | Three options (radio buttons): |
|
||||
| | | **Interval-based** -- Every X months or miles (e.g., oil change every 5,000 miles or 6 months) |
|
||||
| | | **Fixed date** -- A specific calendar date |
|
||||
| | | **Time since last service** -- Based on when service was last performed |
|
||||
| Interval (Months) | Conditional | Number of months between services. Optional if miles are specified. |
|
||||
| Interval (Miles) | Conditional | Number of miles between services. Optional if months are specified. |
|
||||
| Reminders | Optional | Set up to 3 reminders (Reminder 1, Reminder 2, Reminder 3) via dropdowns |
|
||||
| Email notifications | Optional | Toggle to receive email reminders when service is due |
|
||||
|
||||
Click **Create Schedule** to save.
|
||||
|
||||
Below the form, the "Maintenance Schedules" section lists all active schedules for the selected vehicle, showing when each service is next due.
|
||||
|
||||
---
|
||||
|
||||
## 6. Gas Stations
|
||||
|
||||
Click **Gas Stations** in the sidebar. This page helps you find gas stations near you and save your favorites.
|
||||
|
||||
The page is split into two sections:
|
||||
- **Left**: An interactive Google Map showing station locations as markers
|
||||
- **Right**: Search controls
|
||||
|
||||
### Finding Stations
|
||||
|
||||
**Search Options**
|
||||
|
||||
| Control | Description |
|
||||
|---------|-------------|
|
||||
| **Use Current Location** | Large red button -- uses your device's GPS to center the search on your current location |
|
||||
| **Street** | Enter a street address (e.g., 123 Main St) |
|
||||
| **City** | Enter a city name |
|
||||
| **State** | Select from dropdown |
|
||||
| **ZIP** | Enter a ZIP code |
|
||||
| **Search Radius** | Slider from 1 mi to 25 mi (default: 5 mi) |
|
||||
| **Search Stations** | Click to execute the search |
|
||||
|
||||
You can either use your current location OR manually enter an address. Search results appear below the map.
|
||||
|
||||
**Search Results**
|
||||
|
||||
Below the map, there are three tabs:
|
||||
|
||||
| Tab | Description |
|
||||
|-----|-------------|
|
||||
| **RESULTS (n)** | Stations found by your search, showing count |
|
||||
| **SAVED (n)** | Your saved/favorite stations |
|
||||
| **PREMIUM 93** | Stations verified to carry true 93-octane fuel |
|
||||
|
||||
Each station result shows:
|
||||
- Station name (e.g., "Costco Gas Station", "Mobil")
|
||||
- Street address and city
|
||||
- Star rating (community-verified)
|
||||
- Fuel grade badges (e.g., "93 Octane - w/ Ethanol")
|
||||
- Save/unsave button
|
||||
|
||||
### Saved Stations
|
||||
|
||||
Click the **SAVED** tab to see your favorite stations. Saved stations also appear as yellow star markers on the map. You can:
|
||||
- View station details
|
||||
- Remove a station from your saved list
|
||||
- Navigate on the map by clicking a station card
|
||||
|
||||
### Premium 93 Stations
|
||||
|
||||
Click the **PREMIUM 93** tab to see your "Your Premium 93 Stations" -- stations that have been community-verified to carry genuine 93-octane fuel. This is especially useful for performance vehicles that require premium fuel.
|
||||
|
||||
---
|
||||
|
||||
## 7. Documents
|
||||
|
||||
Click **Documents** in the sidebar. This page stores all your vehicle-related paperwork digitally.
|
||||
|
||||
### Documents Overview
|
||||
|
||||
The page shows the title "Documents" with an **Add Document** button in the top-right corner.
|
||||
|
||||
If you have no documents yet, you will see an empty state:
|
||||
- A document icon
|
||||
- "No Documents Yet"
|
||||
- "You haven't added any documents yet. Documents will appear here once you create them."
|
||||
- A **Go to Vehicles** button (since documents are associated with vehicles)
|
||||
|
||||
When documents exist, they appear in a list/grid with preview thumbnails, titles, document types, and associated vehicles.
|
||||
|
||||
### Adding a Document
|
||||
|
||||
Click **Add Document** to open the "Add Document" modal with these fields:
|
||||
|
||||
| Field | Required | Description |
|
||||
|-------|----------|-------------|
|
||||
| Vehicle | Yes | Select which vehicle this document belongs to (dropdown of your vehicles) |
|
||||
| Document Type | Yes | Select the type (see Document Types below) |
|
||||
| Title | Yes | A descriptive title (e.g., "Honda CBR600RR Service Manual") |
|
||||
| Notes | Optional | Any additional notes about this document |
|
||||
| Upload image/PDF | Yes | Click **Choose File** to upload an image or PDF file |
|
||||
|
||||
Click **Create Document** to save, or **Cancel** to discard.
|
||||
|
||||
### Document Types
|
||||
|
||||
| Type | What to Store |
|
||||
|------|--------------|
|
||||
| Insurance | Insurance policies, cards, declarations pages |
|
||||
| Registration | Vehicle registration documents |
|
||||
| Maintenance Manual | Owner's manuals and service manuals |
|
||||
| Service Records | Service history documentation from dealers/shops |
|
||||
| Recall Notices | Vehicle recall notifications |
|
||||
| Inspection Reports | State inspection or emissions test reports |
|
||||
| Receipts | Purchase receipts for parts, accessories, services |
|
||||
| Other | Any other vehicle-related document |
|
||||
|
||||
**Insurance documents** have additional fields: Insurance Company, Policy Number, Effective Date, Expiration Date, Coverage amounts (Bodily Injury, Property Damage), and Premium.
|
||||
|
||||
**Registration documents** have additional fields: License Plate, Expiration Date, and Registration Cost.
|
||||
|
||||
Documents with expiration dates will show countdown badges so you know when renewals are coming up.
|
||||
|
||||
> **Pro Feature:** When uploading a Maintenance Manual PDF, Pro and Enterprise users can check **Scan for Maintenance Schedule** to automatically extract a complete maintenance schedule from the document. See [Maintenance Manual PDF Extraction (Pro)](#maintenance-manual-pdf-extraction-pro) for the full workflow.
|
||||
|
||||
---
|
||||
|
||||
## 8. Settings
|
||||
|
||||
Click **Settings** in the sidebar to manage your account, preferences, and data.
|
||||
|
||||
### Profile
|
||||
|
||||
The Profile section displays your account information:
|
||||
|
||||
| Field | Description |
|
||||
|-------|-------------|
|
||||
| **Avatar** | Shows your initial in a circle |
|
||||
| **Name** | Your display name (e.g., "Eric Gullickson") |
|
||||
| **Email** | Your account email address |
|
||||
| **Account Status** | Shows "Verified account" if email is verified |
|
||||
| **Display Name** | Your public-facing name |
|
||||
| **Notification Email** | The email address used for notifications (defaults to "Using primary email") |
|
||||
|
||||
Click the **Edit** button to update your display name or notification email.
|
||||
|
||||
### Security and Privacy
|
||||
|
||||
The Security & Privacy row shows "Password, two-factor authentication" with a **Manage** button. Click it to:
|
||||
- Change your password
|
||||
- Set up two-factor authentication
|
||||
- Manage active sessions
|
||||
- Log out all devices
|
||||
|
||||
### My Vehicles
|
||||
|
||||
A summary list of all your vehicles (with count, e.g., "My Vehicles (4)"). Click the **Manage** button to go to the Vehicles page.
|
||||
|
||||
### Subscription
|
||||
|
||||
Shows your current subscription plan with a **Manage** button.
|
||||
|
||||
| Plan | Features |
|
||||
|------|----------|
|
||||
| **FREE** | Basic vehicle management, up to 2 vehicles, basic fuel tracking, document storage |
|
||||
| **Pro** | Up to 10 vehicles, receipt OCR scanning, maintenance schedules, email ingestion |
|
||||
| **Enterprise** | Unlimited vehicles, all Pro features |
|
||||
|
||||
"Upgrade to Pro or Enterprise for more features and vehicle slots."
|
||||
|
||||
Click **Manage** to view plan details, change your subscription, manage payment methods, and view billing history.
|
||||
|
||||
### Notifications
|
||||
|
||||
| Setting | Description | Default |
|
||||
|---------|-------------|---------|
|
||||
| **Push Notifications** | Receive notifications about your vehicles (maintenance due, etc.) | ON |
|
||||
| **Email Updates** | Receive maintenance reminders and updates via email | OFF |
|
||||
|
||||
Toggle each setting on or off.
|
||||
|
||||
### Appearance and Units
|
||||
|
||||
| Setting | Description | Options |
|
||||
|---------|-------------|---------|
|
||||
| **Dark Mode** | Use dark theme for better night viewing | Toggle ON/OFF (default: OFF) |
|
||||
| **Units for distance and capacity** | Choose between measurement systems | **Imperial**: miles, gallons, MPG, USD / **Metric**: km, liters, L/100km, EUR |
|
||||
|
||||
The unit system you select here applies throughout the entire application -- Dashboard, Fuel Logs, Maintenance, and Vehicle Details all update to reflect your preference.
|
||||
|
||||
### Data Import and Export
|
||||
|
||||
| Action | Description | Button |
|
||||
|--------|-------------|--------|
|
||||
| **Import Data** | Upload and restore your vehicle data from a backup file | **Import** |
|
||||
| **Export Data** | Download your vehicle and fuel log data as a backup file | **Export** |
|
||||
|
||||
Export creates a downloadable archive of all your data. Import accepts a previously exported backup file to restore your data.
|
||||
|
||||
### Account Actions
|
||||
|
||||
At the bottom of the Settings page:
|
||||
|
||||
| Button | Action |
|
||||
|--------|--------|
|
||||
| **Sign Out** | Log out of your account |
|
||||
| **DELETE ACCOUNT** | Permanently delete your account and all data. This initiates a 30-day grace period during which you can cancel the deletion by logging back in. |
|
||||
|
||||
---
|
||||
|
||||
## 9. Subscription Tiers and Pro Features
|
||||
|
||||
MotoVaultPro offers three subscription tiers. Higher tiers automatically include all features from lower tiers.
|
||||
|
||||
### Tier Comparison
|
||||
|
||||
| Feature | Free | Pro | Enterprise |
|
||||
|---------|:----:|:---:|:----------:|
|
||||
| **Vehicle Slots** | 2 | 5 | Unlimited |
|
||||
| Vehicle management | Yes | Yes | Yes |
|
||||
| Fuel log tracking | Yes | Yes | Yes |
|
||||
| Document storage | Yes | Yes | Yes |
|
||||
| Gas station finder | Yes | Yes | Yes |
|
||||
| Maintenance records | Yes | Yes | Yes |
|
||||
| Maintenance schedules | Yes | Yes | Yes |
|
||||
| Data import/export | Yes | Yes | Yes |
|
||||
| **VIN camera scan and decode** | -- | Yes | Yes |
|
||||
| **Fuel receipt OCR scanning** | -- | Yes | Yes |
|
||||
| **Maintenance receipt OCR scanning** | -- | Yes | Yes |
|
||||
| **Maintenance manual PDF extraction** | -- | Yes | Yes |
|
||||
| **Email ingestion** (forward receipts) | -- | Yes | Yes |
|
||||
| **Shared vehicle documents** | -- | Yes | Yes |
|
||||
| **Community station submissions** | -- | Yes | Yes |
|
||||
|
||||
When you attempt to use a Pro feature on the Free tier, an **Upgrade Required** dialog appears explaining the feature and offering a direct link to upgrade.
|
||||
|
||||
---
|
||||
|
||||
### VIN Camera Scanning and Decode (Pro)
|
||||
|
||||
**What it does:** Use your device camera to photograph your vehicle's VIN plate, and the system automatically reads the VIN using OCR (Optical Character Recognition) and decodes it from the NHTSA database.
|
||||
|
||||
**How to use it:**
|
||||
|
||||
1. Go to **Vehicles** and click **+ Add Vehicle**
|
||||
2. In the VIN Number field, click the **camera icon**
|
||||
3. Point your camera at the VIN plate on your vehicle (typically on the driver-side dashboard or door jamb)
|
||||
4. The OCR system reads the 17-character VIN from the image
|
||||
5. A **VIN OCR Review modal** appears showing the detected VIN with confidence indicators
|
||||
6. Confirm or correct the VIN, then click **Accept**
|
||||
7. Click the **Decode VIN** button
|
||||
8. The system queries the NHTSA database and auto-populates: Year, Make, Model, Engine, Transmission, and Trim
|
||||
9. Review the pre-filled fields and complete the remaining details
|
||||
|
||||
This eliminates manual data entry errors and ensures accurate vehicle specifications.
|
||||
|
||||
---
|
||||
|
||||
### Fuel Receipt Scanning (Pro)
|
||||
|
||||
**What it does:** Photograph a fuel receipt and the OCR system extracts all relevant data, automatically filling in your fuel log entry.
|
||||
|
||||
**How to use it:**
|
||||
|
||||
1. Open the **Log Fuel** modal (from Dashboard or Fuel Logs page)
|
||||
2. Click the **SCAN RECEIPT** button at the top of the form
|
||||
3. Use your camera to photograph the fuel receipt
|
||||
4. The system processes the image and extracts:
|
||||
|
||||
| Extracted Field | Description |
|
||||
|----------------|-------------|
|
||||
| Fuel Amount | Gallons or liters purchased |
|
||||
| Cost Per Unit | Price per gallon/liter |
|
||||
| Total Cost | Total transaction amount |
|
||||
| Date & Time | Transaction timestamp |
|
||||
| Fuel Grade | Regular, Midgrade, Premium, etc. |
|
||||
| Station Name | Merchant name matched to known stations |
|
||||
|
||||
5. A **Receipt OCR Review modal** appears showing all extracted values with confidence scores
|
||||
6. Each field can be edited inline if the OCR got something wrong
|
||||
7. The station name is automatically matched against known gas stations in the system
|
||||
8. Click **Accept** to auto-fill the Log Fuel form with the extracted values
|
||||
9. Click **Reject** to discard the scan and enter data manually
|
||||
10. Review the pre-filled form and click **Add Fuel Log**
|
||||
|
||||
**Tips for best results:**
|
||||
- Photograph the receipt on a flat, well-lit surface
|
||||
- Ensure the entire receipt is visible in the frame
|
||||
- Avoid wrinkled or faded receipts when possible
|
||||
|
||||
---
|
||||
|
||||
### Maintenance Receipt Scanning (Pro)
|
||||
|
||||
**What it does:** Photograph a maintenance or service receipt to automatically extract service details into a maintenance record.
|
||||
|
||||
**How to use it:**
|
||||
|
||||
1. Go to **Maintenance** and select a vehicle
|
||||
2. On the **RECORDS** tab, click the **ADD RECEIPT** button (dashed outline area)
|
||||
3. Use your camera to photograph the service receipt
|
||||
4. The system processes the image and extracts:
|
||||
|
||||
| Extracted Field | Description |
|
||||
|----------------|-------------|
|
||||
| Category | Service type (Routine, Repair, Performance) |
|
||||
| Subtypes | Specific services performed (e.g., Oil Change, Tire Rotation) |
|
||||
| Cost | Total service cost |
|
||||
| Date | Service date |
|
||||
| Shop Name | Name of the service shop |
|
||||
|
||||
5. A **Maintenance Receipt Review modal** shows extracted values with confidence indicators
|
||||
6. Edit any incorrect values inline
|
||||
7. Click **Accept** to auto-fill the maintenance record form
|
||||
8. Review and click **Add Record**
|
||||
|
||||
---
|
||||
|
||||
### Maintenance Manual PDF Extraction (Pro)
|
||||
|
||||
**What it does:** Upload your vehicle's owner's manual or maintenance manual as a PDF, and the system automatically extracts the recommended maintenance schedule -- creating maintenance schedules with the correct intervals for your specific vehicle.
|
||||
|
||||
**How to use it:**
|
||||
|
||||
1. Go to **Documents** and click **Add Document**
|
||||
2. Select your vehicle and choose **Maintenance Manual** as the document type
|
||||
3. Upload the PDF file
|
||||
4. Check the **Scan for Maintenance Schedule** checkbox (Pro feature -- indicated by a lock icon for Free tier users)
|
||||
5. Click **Create Document**
|
||||
6. The system submits the PDF for asynchronous processing
|
||||
7. A progress indicator shows while the document is being analyzed
|
||||
8. When processing completes, the **Maintenance Schedule Review** screen appears showing:
|
||||
|
||||
| Column | Description |
|
||||
|--------|-------------|
|
||||
| Checkbox | Select which items to create as schedules |
|
||||
| Service Name | Extracted maintenance service (e.g., "Engine Oil and Filter Change") |
|
||||
| Interval | Recommended interval in months and/or miles |
|
||||
| Details | Additional notes or specifications |
|
||||
| Confidence | How confident the system is in the extraction (High/Medium/Low) |
|
||||
|
||||
9. Check the boxes next to the maintenance items you want to create
|
||||
10. Edit any service names, intervals, or details inline
|
||||
11. Click **Create Selected Schedules** to batch-create all selected items as maintenance schedules for your vehicle
|
||||
|
||||
This turns a 50-page owner's manual into a complete set of maintenance reminders in minutes.
|
||||
|
||||
---
|
||||
|
||||
### Email Ingestion (Pro)
|
||||
|
||||
**What it does:** Forward vehicle-related emails (service receipts, insurance documents, registration notices) to a dedicated email address, and they automatically appear in your MotoVaultPro account ready to be associated with a vehicle.
|
||||
|
||||
**How to use it:**
|
||||
|
||||
1. Forward any vehicle-related email to your dedicated MotoVaultPro ingestion address
|
||||
2. The system processes the email and any attachments
|
||||
3. On your **Dashboard**, a **Pending Associations** banner appears showing how many items are waiting
|
||||
4. Click the banner to open the **Pending Association List**
|
||||
5. For each pending item, you see:
|
||||
- A preview of the document or receipt
|
||||
- A vehicle selector dropdown
|
||||
6. Select the correct vehicle for each item and click **Associate**
|
||||
7. Or click **Discard** to remove items you do not want
|
||||
|
||||
**Bulk actions** are available to discard all pending items at once.
|
||||
|
||||
This is especially useful for:
|
||||
- Forwarding digital receipts from auto parts stores
|
||||
- Forwarding service confirmation emails from your mechanic
|
||||
- Forwarding insurance policy documents from your provider
|
||||
- Forwarding registration renewal notices
|
||||
|
||||
---
|
||||
|
||||
### Shared Vehicle Documents (Pro)
|
||||
|
||||
**What it does:** Associate a single document with multiple vehicles. Useful for fleet insurance policies, multi-vehicle service agreements, or shared maintenance contracts.
|
||||
|
||||
**How to use it:**
|
||||
|
||||
1. Open an existing document's detail page
|
||||
2. In the **Shared Vehicles** section, click **Add Vehicle**
|
||||
3. Select additional vehicles from the dropdown
|
||||
4. The document now appears in the Documents section for each associated vehicle
|
||||
5. To remove a vehicle association, click the **Remove** button next to that vehicle
|
||||
|
||||
---
|
||||
|
||||
### Community Station Submissions (Pro)
|
||||
|
||||
**What it does:** Submit new gas stations to the MotoVaultPro community database, helping other enthusiasts find quality fuel locations -- especially stations carrying true 93-octane premium fuel.
|
||||
|
||||
**How to use it:**
|
||||
|
||||
1. Go to **Gas Stations**
|
||||
2. Look for the option to submit a new community station
|
||||
3. Fill in the submission form:
|
||||
|
||||
| Field | Description |
|
||||
|-------|-------------|
|
||||
| Station Name | Name of the gas station |
|
||||
| Location | Address or location |
|
||||
| Fuel Types | Available fuel types and grades |
|
||||
| Amenities | Available amenities (bathrooms, ATM, convenience store, etc.) |
|
||||
| Notes | Any additional information |
|
||||
| Photo | Optional photo of the station |
|
||||
|
||||
4. Submit for community review
|
||||
5. An admin reviews and approves or rejects the submission
|
||||
6. Approved stations appear in the **PREMIUM 93** tab and search results with a community-verified badge
|
||||
|
||||
---
|
||||
|
||||
### Managing Your Subscription
|
||||
|
||||
**Viewing Your Plan**
|
||||
|
||||
Go to **Settings** and find the **Subscription** section. It shows your current plan (FREE, Pro, or Enterprise) with a **Manage** button.
|
||||
|
||||
**Upgrading**
|
||||
|
||||
1. Click **Manage** in the Subscription section
|
||||
2. The Subscription page shows tier comparison cards with pricing
|
||||
3. Toggle between **Monthly** and **Annual** billing (annual saves money)
|
||||
4. Click **Upgrade** on the plan you want
|
||||
5. Enter your payment details using the secure Stripe payment form
|
||||
6. Your new features are available immediately
|
||||
|
||||
**Payment Methods**
|
||||
|
||||
- Payment is processed through Stripe (credit/debit cards)
|
||||
- You can save a card for recurring billing
|
||||
- Update or remove your payment method at any time
|
||||
- View billing history and download invoices as PDFs
|
||||
|
||||
**Billing History**
|
||||
|
||||
The billing history table shows all past invoices with:
|
||||
- Date
|
||||
- Description
|
||||
- Amount
|
||||
- Status (Paid, Pending, Failed)
|
||||
- Download PDF button for each invoice
|
||||
|
||||
**Downgrading**
|
||||
|
||||
If you downgrade from a higher tier, you may need to reduce your vehicles to fit within the lower tier's limit:
|
||||
|
||||
1. Click **Downgrade** on the lower plan
|
||||
2. A **Vehicle Selection dialog** appears if you exceed the new tier's vehicle limit
|
||||
3. Select which vehicles to keep (e.g., keep 2 for Free tier)
|
||||
4. A warning explains that removed vehicles and their data will be deleted
|
||||
5. Confirm the downgrade
|
||||
|
||||
| Tier | Vehicle Limit |
|
||||
|------|:------------:|
|
||||
| Free | 2 |
|
||||
| Pro | 5 |
|
||||
| Enterprise | Unlimited |
|
||||
|
||||
**Cancelling**
|
||||
|
||||
1. On the Subscription page, click **Cancel Subscription**
|
||||
2. A confirmation dialog appears with retention options
|
||||
3. Confirm cancellation
|
||||
4. Your subscription remains active until the end of the current billing period
|
||||
5. After expiration, your account reverts to the Free tier
|
||||
6. Click **Reactivate** at any time before expiration to keep your plan
|
||||
|
||||
---
|
||||
|
||||
## 10. Mobile Experience
|
||||
|
||||
MotoVaultPro is fully responsive and works on both desktop and mobile devices.
|
||||
|
||||
**Mobile Navigation**
|
||||
|
||||
On mobile, the sidebar is replaced by:
|
||||
- A **bottom navigation bar** with icons for: Dashboard, Vehicles, Stations
|
||||
- A **floating action button (FAB)** in the center with quick actions:
|
||||
- Log Fuel
|
||||
- Add Vehicle
|
||||
- Add Document
|
||||
- Add Maintenance
|
||||
- A **hamburger menu** (accessed from the header) that slides up from the bottom, providing access to all sections: Dashboard, Vehicles, Log Fuel, Maintenance, Documents, Settings
|
||||
|
||||
**Mobile Optimizations**
|
||||
- Touch-friendly buttons and targets (minimum 44px)
|
||||
- Swipe gestures for image viewing
|
||||
- Camera integration for VIN scanning and receipt capture
|
||||
- Full-screen forms for data entry
|
||||
- Responsive card layouts that stack vertically on smaller screens
|
||||
|
||||
All features available on desktop are also available on mobile -- no functionality is lost on smaller screens.
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference
|
||||
|
||||
### Keyboard Shortcuts and Tips
|
||||
|
||||
- **Search vehicles** -- Use the search bar on the Vehicles page to quickly find a vehicle by name, make, model, or VIN
|
||||
- **Quick fuel log** -- Click "LOG FUEL" on the Dashboard or "+ Add Fuel Log" on the Fuel Logs page
|
||||
- **Switch vehicles on Maintenance** -- Use the Vehicle dropdown at the top of the Maintenance page to switch between vehicles without leaving the page
|
||||
|
||||
### Common Workflows
|
||||
|
||||
**Record a fuel fill-up**
|
||||
1. Click **LOG FUEL** on the Dashboard (or go to Fuel Logs > + Add Fuel Log)
|
||||
2. Select the vehicle
|
||||
3. Enter the fuel amount and cost per gallon
|
||||
4. Optionally enter trip distance or odometer reading for MPG calculation
|
||||
5. Click **Add Fuel Log**
|
||||
|
||||
**Schedule recurring maintenance**
|
||||
1. Go to **Maintenance**
|
||||
2. Select a vehicle from the dropdown
|
||||
3. Click the **SCHEDULES** tab
|
||||
4. Select a category and schedule type
|
||||
5. Set the interval (months and/or miles)
|
||||
6. Configure reminders
|
||||
7. Click **Create Schedule**
|
||||
|
||||
**Upload a document**
|
||||
1. Go to **Documents**
|
||||
2. Click **Add Document**
|
||||
3. Select a vehicle and document type
|
||||
4. Enter a title
|
||||
5. Upload the file (image or PDF)
|
||||
6. Click **Create Document**
|
||||
|
||||
**Find a gas station**
|
||||
1. Go to **Gas Stations**
|
||||
2. Click **Use Current Location** or enter an address
|
||||
3. Adjust the search radius
|
||||
4. Click **Search Stations**
|
||||
5. Browse results and click the save icon to bookmark your favorites
|
||||
|
||||
**Export your data**
|
||||
1. Go to **Settings**
|
||||
2. Scroll to "Data & Storage"
|
||||
3. Click **Export**
|
||||
4. A backup file will download containing all your vehicle data, fuel logs, and documents
|
||||
|
||||
---
|
||||
|
||||
*MotoVaultPro -- Precision Vehicle Management*
|
||||
*2026 FB Technologies LLC. All rights reserved.*
|
||||
@@ -16,10 +16,14 @@ http {
|
||||
|
||||
root /usr/share/nginx/html;
|
||||
index index.html;
|
||||
|
||||
# Prevent nginx from including internal port in redirects
|
||||
# (Traefik handles external-facing port 443)
|
||||
absolute_redirect off;
|
||||
|
||||
# Handle client-side routing
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
try_files $uri /index.html;
|
||||
}
|
||||
|
||||
# Enable gzip compression
|
||||
|
||||
@@ -1,150 +0,0 @@
|
||||
%PDF-1.4
|
||||
%“Œ‹ž ReportLab Generated PDF document http://www.reportlab.com
|
||||
1 0 obj
|
||||
<<
|
||||
/F1 2 0 R /F2 3 0 R
|
||||
>>
|
||||
endobj
|
||||
2 0 obj
|
||||
<<
|
||||
/BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font
|
||||
>>
|
||||
endobj
|
||||
3 0 obj
|
||||
<<
|
||||
/BaseFont /Helvetica-Bold /Encoding /WinAnsiEncoding /Name /F2 /Subtype /Type1 /Type /Font
|
||||
>>
|
||||
endobj
|
||||
4 0 obj
|
||||
<<
|
||||
/Contents 12 0 R /MediaBox [ 0 0 612 792 ] /Parent 11 0 R /Resources <<
|
||||
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
|
||||
>> /Rotate 0 /Trans <<
|
||||
|
||||
>>
|
||||
/Type /Page
|
||||
>>
|
||||
endobj
|
||||
5 0 obj
|
||||
<<
|
||||
/Contents 13 0 R /MediaBox [ 0 0 612 792 ] /Parent 11 0 R /Resources <<
|
||||
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
|
||||
>> /Rotate 0 /Trans <<
|
||||
|
||||
>>
|
||||
/Type /Page
|
||||
>>
|
||||
endobj
|
||||
6 0 obj
|
||||
<<
|
||||
/Contents 14 0 R /MediaBox [ 0 0 612 792 ] /Parent 11 0 R /Resources <<
|
||||
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
|
||||
>> /Rotate 0 /Trans <<
|
||||
|
||||
>>
|
||||
/Type /Page
|
||||
>>
|
||||
endobj
|
||||
7 0 obj
|
||||
<<
|
||||
/Contents 15 0 R /MediaBox [ 0 0 612 792 ] /Parent 11 0 R /Resources <<
|
||||
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
|
||||
>> /Rotate 0 /Trans <<
|
||||
|
||||
>>
|
||||
/Type /Page
|
||||
>>
|
||||
endobj
|
||||
8 0 obj
|
||||
<<
|
||||
/Contents 16 0 R /MediaBox [ 0 0 612 792 ] /Parent 11 0 R /Resources <<
|
||||
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
|
||||
>> /Rotate 0 /Trans <<
|
||||
|
||||
>>
|
||||
/Type /Page
|
||||
>>
|
||||
endobj
|
||||
9 0 obj
|
||||
<<
|
||||
/PageMode /UseNone /Pages 11 0 R /Type /Catalog
|
||||
>>
|
||||
endobj
|
||||
10 0 obj
|
||||
<<
|
||||
/Author (FB Technologies LLC) /CreationDate (D:20260103171454+00'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260103171454+00'00') /Producer (ReportLab PDF Library - www.reportlab.com)
|
||||
/Subject (\(unspecified\)) /Title (MotoVaultPro Terms of Service) /Trapped /False
|
||||
>>
|
||||
endobj
|
||||
11 0 obj
|
||||
<<
|
||||
/Count 5 /Kids [ 4 0 R 5 0 R 6 0 R 7 0 R 8 0 R ] /Type /Pages
|
||||
>>
|
||||
endobj
|
||||
12 0 obj
|
||||
<<
|
||||
/Filter [ /ASCII85Decode /FlateDecode ] /Length 2145
|
||||
>>
|
||||
stream
|
||||
GatU3gN)%,&:O:Sm-%%*.'uO&(\K@Ti_2CNa,SV]3g1A9"=5<9_#gDQjm0MdOHO;#U>%^F=VS*m4m21Jb(i"Vna6?Z$#m;(bA/3t!*09u$Z?'H)gK-/q"pf_A8+8qHYN5*(YTsUr2M]__sbI_^)'$I"Ve.nl*%*aJ$N*5[p$V*ldC;5i/[,MOmuMWq?j9qD"':$T*-4MIen$B7IY7nFb(>Xk#4S\;-r[]KY)<[]:FlTBVTuCqu0Zr;%Rt<Z@oG8p6KPTpd\?_NbIj38MH&^?$\6BO3d"_q(UeJ@L@4&*C+"X$#E(&j@.6'5@*A(7.g0B(7WCo<#/o7argdNTbRELmR:RF!r,e8<\6LHKtH/J]n,GFU>T0!mQ%pi%K@;^$<2R\48jk5/^lceB+W:>\GNcH7EPC4'_FmiDjY7sO#k<`q9+@e\UGNCo-fUD'c\fh1Bf.4PUp-=morfCXP,h^mJ71SaL7@sC*U6>S"$mJMOi%C_.R13<>eYb'W&SpnWg51'[7+C(E:(^-c\'i-89`'ZUnN,^J)<p$9H*PXhb05_aLnYo&\CCP[GPXb9/tZ8e@R1j8t%r2!Iqo7*[@i+4"9s.+\]kY.!-T-X*;qlncil2X6n"$?hd\YUnhS5bij03OH:22`4eL")1!h[6]%L:b"kGYO"9?(jJW`8<_,dcK\SjN&:Z6S_9*n99Kf&Q\`IO1*rc\WSGbb@?W<<bg(hk`*RMD;/IugAZ4=_R6cRi^X9s@a$Bc5]M.JDnJf``,G6p$P_++aB2gS;'iaUi_]%RtYhmd-*]"<j(3X,hTMgbR5O72M5(fW.8+F9Df/t4#Z1LQ-mG3L67:*+N9RZ!f]bDF5WKJBPit-c;Hm;=[/_VG)8's-[joje"Z0rh%gF_%cXNqZ'nbhEP]L,239;h7q,$25:)@/!35]UlV/7lki7Qnm6ksob"2Y(M1>04K.9pLQ1O^D<E9J/*#$B%ES8<p\pM#7WX%o4-[kit?=D6QP,@oXp_>+hLgH7u@'X*]tMdVXotTQnOL,]>Z.\.<)+r5O!k!bLIEG,1Gn=jQG*N1slEc=+5dlAfA/B8C)eA,D^`*-*Vk@.M+/`6,<.M)&lhY4k+h@o?I:Y%48An6ae#6gi<B$\YHn"LFh'KaWKLh`\qBr(T&C^bZCTZK/P]KVVmGVVG4RD71j_+)!7O_oC&]U]8bl!D7<RB_%9Ar6oKuqMq8r9>bGMblV^fcWfb-JH`eegmfSR.(NZ1AEQQg;`B\&&rDj9<Rc$_Hn-sd*t:24G^c1Xc:&,_H1SU+mUOY52VS9hq^?\sJbK1K^#b_bXNK=<S_^&i18T%s^q\L61:VESKqd]"1>=Rt+f-=W>#;_6ASm:mn5mk-5s"?"'.cN=)Ng$LNPj]-DF$'O'0g^B)Z`PCOFdO&L*//VDt8PR4O8a94X$sSNe#%b</]0D<f%psUUo!`6AU@%WClUJ<b`0ZA<q,,hI0$HE,^<Hj9uGIGdH_K7M$"bFPdOUe?JBt\e,<9oE[K>It;_H_.`mr0aD#),ie*BGYN;`g6uk_pEKaQK+Bq11)*N&J3u^8]>%$.Q,tp3TcD78Iae&T)+/,3J&ge9FAn=a'n;l&:.(31`aEGGCe$EaN`+d)**"PKTi]E<DrBL/%#pG26'"16l\6R"4X%k6jua<sNCLrNfm_&O4DuOs2F<=O\-;kkO+g^'X^lPG?+W"_(3MR3>mX*C\hmISqa#_X,S9htNAXLuA%Drnj0%X`UdK'gaB`gr/Ob%I&KpYO]tcY576YOXRc9^0lCb#I2#G]56[nBIG2B%PO;bd6cngO@)?Z`.d*:!8;du(2IbE9kc18-Bnbpr#oNgLRo/'"uEI;a#BH-X@P8!@5?k0DlPrIWdW5r>m&5]3j4,mC5I&6nhd(.bgC8eZY$E*hpdd3Tg$74"?G>FGU/5g7i-p%aF9P?WY5d;"!+cgNXmOr1`\uj07c!I^sff<1Oh:4=`.^6A]W,:l@?oWR!i;%h+aY>,3_Qer8PZDQ\HArdZXJ-<TT'Qe%+Xf?8$0/FtLmR)!Z%Zk-.nu4bPH\)aZ41r6WU;8?B$TYQ3HNnkBKK?kh/B/P5`<j0UBQ8ACIO9t'7OS0L0+o\VQXqD/p_OK\3S(ZM8C<^C!S)V4Ln,DiZEoW3oB~>endstream
|
||||
endobj
|
||||
13 0 obj
|
||||
<<
|
||||
/Filter [ /ASCII85Decode /FlateDecode ] /Length 2354
|
||||
>>
|
||||
stream
|
||||
Gb!#\?#Sc3&q/*0)"bq\E3tr/+hN.p\(RK@G+0i8('X9G8@6WG8Q8:(Nr/-hL8&0>dDeH[m(G+bbPE>ocC?mNUR28\`;Y6e&q*!BG9::O':LR&*^q<B?dmR'm*E"WA`bWSU1q+K%K.A3s#*N!+qDdli[CLBSFChNofd,gIhb]:DN(I'1o2M3TK?l=.[0$Ps"DXsitn=_n<_Spn(Sr1U+pN1Wj(u+$@>A`O4g]0=$_&64W^179b&6:5PVd=jm"fsU*Q;WE9HSI=@u0q]_VeF4opkaMTKrU9`T[$Er6W73/*]$+rVi(F?6,k"sIDbhL.rIYV@(Vn/o!4h@LWTdW?uU9pOJSn*#BAmd*e1[=>]1H$rC/Y-.3Vo(Ir)rVYp>p?KQY:Hr*5Isol;][PqBP"P8Cb,-H[k[`eR7KA]p18fmZ'k.j(DbiY=YgL-h;l+K/d;,"?19H8+%:r#kb#qp+\/*(5;:'qF$<8['?);VsVl"2[<d1R.IEM5[=rNMr>i5cRQ-#a3:?a8']L2K@cGOOiLN1+TP,>#'.$*Wk_5:Kts/m;kZjk$;WbAFP6R']q"2M![%Lu[Rn%f),+FpKF-nBKQjnoNS*HL0=4?>ecN[E4hiitYRKri`\^hd7c)!4G.6t*jjh.ZsjEQSTh$q$hu^t#F$D^2<Q1QW-R`Yaa$E>4Gnfi/,>^Gjn.JbYjh++3L0^IA0FcmNpF!!KuBM/"J$g&7CV62,R'8_i_o<YqL)KbOrQ"V,E=,%!-BbXu1U+Y`K57[ZDp?[$'DNF0r_3#W51anR]Z;OWNaDKhI9_M?Oii3mq[Ue_Y$D+W6"TeaH^X=-%CO<K&KolAoe+7J>U1TW'++UgBfJ5>6c;pohYE[/J&!<aZoVMdcQN]Bt.6=]YP=$,<"@IZ\J+W,K!onqHBh4N//.h02DPnt&6(B,GH33c[M4Fqo9)l4pe+%>_ImTh"2k4"+DW0F$^*e.05&uEpb4uqh7TB[/KRUpoiRM**id)\n\RZG6?"R-bL>h+SjD(Sg=6R6`_mN^od$3=g;iT.Dk"!lGfeS,0/Xc..`X$__'&Yi4WSU<NK&h(mJ3F-/b=R1/HZeHKP<MA4!1\2<Nb\/5:&:,/[NA*h$9JY!V\e8dTOd/Nj=7-r//'5(Cba/&B+F-6q^D&<])Q`,%ZW8"0."0m4faOTZ.?e+X^"J.":8+#%6+V6),G)OK\KP6':_iU8pAYP0A[>]rn0M[>O3phR,\WrIO`+&HQsJ6rI*@JfW\o5D]bQ7U?7_&"c`0Gi8OJG``SQiE[NMee<o4-Qk=p[u*&-;Y3"3#V]C-?WQ%c#OO.h'V>3N!=FuTW,4cJE@KL>S$6c`9HV$^g+<$^/bX@g4c#W$rOCSDolN-].f-hA#5@P+l;h.V&E4V?T1lubIP`pmS%Hp`][?GPb[K@+/;mFu`2NC(80Elhne6s.;&Qg(e.,]NHWGL:RI5sLA1jL]]B*IbYk^DgGl4c&Hc#5nS\63/eZ,n^VK"jQfaM>J.L%MWI@I$Fb7:2D^[?f*2P$&;WkU$-beQQWn9GGeZJ[)XH=R$KTOIXAq^GhbT9g$ue*f7\A(#Q6h];nk0?m4o]4I*m*WA'LNiTC"A63JOKW@^Ba*5#fporZIPdW6]MP"<Ms1;r*gEgO3eN)!oi@Fu>\1WS(?o[4\i-_9`8K%nG\*:-c$>S[WM($D1C?VS:G(RS;I.!K,-krCjj"rNG>G:[l4P,Vn2bSD8WDCRWrt"e*@(6r>e5[BP!JrRJ>XB2FO>hB(]KQ_Jm[hbg*h&57u_aG1Jc:[@_c.4Wi\cnpE<@tt6JU`8LYHXh;r`2M,BS5Fe3?L,k]-f'@2an`^BrcjPXpS77h((X:raL;enDL'*&W_,nDEu:EJ7EFG9nBj]lnM)*%J"XXRJ9.7M]>;*hi'*>(4YFF##luOH](@<=s,nn!/\qsSY\S.hHsQ;R)-ZKZ``e5-J?=71k;3iSj5&hA:HVRV"o!?;kAOp)4R3n6^7J"LN8fDR*Ut@U,78>%&7r?4-Hu3=#D5=sZ#]F1hf"g63;n?,E(jumr=A[o.l;\Dg2cZ5[d3iH!tKL\pnX[[iBM$Z->6QEIPSG'P<lG&qK@J@*.>>Hc1H<?V5O0dnX$IPU<rshO<7bTo)l)h[0?h_VLT"sKW9&Pak3/tpH9BGUV>>TkQLs&#M!!o_dlr.qUmicnS]9$1%lm(a5Yq2a1HLC&Be+S_OPqgF(u78H[j=Zq^B,8$Uq)'WdUKUi8]QYml5!,O1$-"_s(]r%/p/55GCaBe-a!5mc"trkWi>Hft5CYJ?E<s-n%qSRX1nJh:OEG&'nQX/g2L;C>\usq`=aPRLKelpLM)2DOJfL#5D\>e,~>endstream
|
||||
endobj
|
||||
14 0 obj
|
||||
<<
|
||||
/Filter [ /ASCII85Decode /FlateDecode ] /Length 2256
|
||||
>>
|
||||
stream
|
||||
GauHLgN);`(4FM1m-6VBR47-'S*R^Ii,lTR>`N[LPH)8$,D^Z)`Rk6\^HY?m&kJ4rVbbj)<"N0cQaPGZ-oTWGA"16tP3=NlgO#E+LQX[N%BDcd8:GUPpXS4of0$!9S\kQQ2(s:Q?7b^Tq]NUa>7S'1Ng@/Ml[`%+JZU^c/gMaU=I(5q'_>cY;Z7U]h^J<V#k,.iC=Cr3kjt(iV!V02&DZKbSg?7`g91CPN8fnY+&4^t-O7m$II@,U[HTZ:e*`BGFEYkDSD4d]rX1PiJ8)oY<jukP!'e3$S+"ZLf#\3/]lt#"A!=1]])D7?"hEVq``'9W)$.ts0@]D`f8nWhmSV`,'"\THTuXS+%Cj,0b/1jG\pcK6UNOq#feckK'T=W=c&h(ll^EuLIZ.lu7%S#VRE-0i<(WpVX">jkrJ[(POk3.on#Aj8JutV5>1SMk1WncF@O]*ND9ccNIIX;>/NY>A/<&Wug@A,WV3.u3U]N+0/7iX5<Ij)9.mRh!ST^o2NJg/t=:2/i1^7qtOri`]&l.tCq@,pZ*U9&&X3$&6D7RY2=1"0,@dqSIXALVA)u^jsQ=@aIkE+n?$AZba0A&)`^]iW:<%ed/(e`HVm57!_#C=`p&=?D=*%]NWJlRM2:SB6#AZ:_j+P?&7+!PC+SQ=5<#ln7gGc;%4.O"ES&o9gsQ>?dc'W#iXX&4^!W):Q;WJMqnn`a4c]p(<-a+gtZ9Q>$S&0%Ks*c5KY(SHMlr;.t-6Cl$9nf=i7Tla^(`=)2,Pp08o@g/OIFrECEkeOTi5ZT&Zr2$dh+RS33\O&[bO<M6e-?>saX&/&.SGQ?^D7;Tlg##*hhsK91oeAS*Ot4r`>+?bWJ0)L+@`aW"HL$N&*8rV?A8*OF\Ug,bR)f\g7=H;L'7glH2``$n[V[nWG.#5JG'J%iNaMV=>n`EiAs>?pj4,BF6Xm23)ar2$2?e#r4;3*P2UP"8N+iV:rgZ&sW!Y$]@PMgb>o,ipW"A&tL;4@*nA!SLpt9E6BRZJP2g*<HGIjnG2(gNWo=;#4aHI8U^;Gj17PC@`V*Y=K:hEa9ZoSddIARjo;`r[(D[fQ=BYF^b<A7A[J5#/X]!8'PIt/\_dQ5E0l-gZ4,mrU+PO;Jcngp':.V)SFXUY/oZF,U,m>EaE)#.F%+7!m8c&6RU1lknDGO:FX<e[B.r:FG*@_1+YhLcVthHf>Pm+#HjMZ)`^kkY(j3#Xp_ID8RQ+aHHOAAil4Z>\;IU->,:^p2[@Vq!W?\F\]&[O<"2d0&j`?n`I[s(C=%',pbq+@m-d^O)d'qc]c2-lG0mP;%Q"l3D;^oR[)XL#JGSL=P_%XcCNQl`XV/H,Cosiu/&],<q3&'N$P$LOn?d;)%?jPC>4`9ERNEIDJtQ/dR*jYt"IR1=Y(IZ/7WUdFaA?TJm1jLrPWl4Gs(UH+i&[np39o&K$O_2o4uIJn0?2G:G$$][ILSiH-ZY7)u:.5$c6Ui0]O$#\,dUb&E_oEk0<qbE!t=9i^b`5D$i\I@b[%/`0&`]EF6W+t<W-(ja)kItdt:+(L>eg;=p)^A.XuW);.#UB`Hj1@b[dYjY(aC()9Q_>b/?6N8D'6ViKGmj0$#O\`Y&,2st62SKK0_f"._@/<_WMJhi,hm_fh1bf6q;<Wdr:_f$]_`.YR9Y_-q./*(W*R+95\F07-+:`@4+1KVsm"Ke%!kl,oDSObim5f:D%"G-tl&$;b2AMXY)Ta#/rNS\5:RKT:mg4(6F(t?ga851]4VDrUqc'cHl=d<'e9nRVD'L!O0:<;`c@qc,O#;U9F:7NJNFq@od=*UOb`$gG4iEd\5S'rBILu;`%51`DJg"ai%h'[*>&Yt`!`cp%:Xj5KJ)oKIP(aW4h([_ara:K2Bf98;hKP3,0$K\B@nYV7p4K)?S&s)`<cPmAj47Y9Cn@j'fSN@WH]41FD7)Cn1-V1Y\lc-m0452`TP;.Y3+j1-U1YM/9f2`Fm($'2<kE@Nb5?%kdj:dJG2)^$d<fmRVaRRU?qg'K1GA8S*>/6RQiU'ebliT1"ihTnAk%&(+1tE9:Z2+1l+K&CDp."DBjp0'!j_j!VeZeLWb&K4mein!]N._M[&u4A@;sTj!8%q5_/fq^_=%9;U8+W"+ZA%FR/^c#4.'m?1F.4V^4Y/>f_'Pj+CBoqIp*"bM.-6"`klb>\2Vf/)RNV4aXs@%:^g*10@^BQ/L>jcm_Ce?PoK^CY@=OI-<)t23tD)TgATaer_^)1c+boDI$oo'82"7Tkj!X`I/:n~>endstream
|
||||
endobj
|
||||
15 0 obj
|
||||
<<
|
||||
/Filter [ /ASCII85Decode /FlateDecode ] /Length 2720
|
||||
>>
|
||||
stream
|
||||
GatU4>BALj&q9"FFQJ@L+pto439Oja/3?g>irqFl=8>9#K:,+DN\2[FYMZNROtEpa\B`f.kV=qWIJ^bHO\S:AlfpEfM(X2PI&3$EOM;spdOatPjS?L(HhGHJ%1G+l*mdUR8&s6JR9/U[plV]s1q!jZ(K:>\/^ggg)&7?u9"rC+SC.kK7.qflnWEb<jStp,4!XZ_l1hj&mV+THHV#gAEhH3%[`s+u:D'^X\%H$]NEQ_?"0_U:9XP<s1WC(`)e8>gB0fSAWdhpUYDsJfM\1%K_>SUC<:@F3LLf'l(U@"RL4%=`@C:2o33i)^_R6<@6X!CWS-_JM8hsP-30B]JJC\0SP4a?WA51f8_G?94OiVV/"G2D?JPb\HOlZ[uA:njjh-+D7/5k7]AdirP6Q><fDV/]F&auId+9\QsBi8J-[6R<;#8.=!A8,:5#;XC/g`Ir'!Z>KS,_IH^a[3:dFV&$l^J4<)<)Pb]CI;`FR810]c^dT\M]VaN$);MmP@r$+OJb\>'F>*RBTe0=rb*,QD4onK7g_#>o=VF]3;:i0/#&[JC\[<n8.%'6OHpcL\_me5<\t-:F[H,5s4#9+cUC<%=:]HX/G$+g2IeBqKm]:8[5<]A1I%XB[u4dqP`::.f#a3Wbnaf0-<mKL0iX#Q;,mPgFT\(;b'[8+JsITVUQW#&OIJC)KWBFWkY.`OWSrS(fl)Fh&_S%]L>t`Jc-[o6T`_6][P>%+[2m;l'Oi(*<h&SoST#T0,@G1?ZGscogQ;%k)>"5Slrdi,&@YN_EXZfZNuWVS*1L<iR`R5J-\K9BFfUSQI!%Mbk1$FDpI_C#o<ASQW7Qh\e@s0O^)c_pLS[N+>#0OZWZh:p]l!5t&*4DJW(H.8H5ms3J[07ujo4)kF&sD74nk-;0=)Cq]W","gsX\XH<9k4q1D-mTA6It]O0((idOI?n(O>]Ed%E#?_,:XgGYNLFVW=TNCK?k0uaREPsT=&RnVj)dWCp(Rl$%UW0Knq-*t7_FD18FT.U6n$P3rdNALb$Jp,9Wg8r9C!TjCI!8B-cmIA79.ACT.erRaj&H+*`OhEH2mBT\!e+eS7SD"g.O_[bp4_7N-BV3BJ?j/p[@4$1MG_5N:W:2Qk#!MI54>!27L"<(#+60sUA+$))N$>,=n6s-KAaH*,d?,knpI,>(%@KQphB>)s5KfIbN*fL'[#$SZh@Vo'>kW=LNahr*pkr(Eo6uDqAct-UU0q8b/X-JP<oa6p<ZOGMWEW&rLi/9JLg6F:VJRfl1&]]V),t`DOesTM.9Ir^r/.BI'm)[7d2#6)Gsr9^6"o("ZA/5.)6)FVe7A=T]VpGU,ar,Cl01H/W1^d6?][)jZFuO4b2OZufGu.1^!OjXb.Kg4nT-Wn0^G.O9<*DBlRT4U))c/J0b\MC,K7Jp)4*(7T3PN4#D5$Teai;8__P"8:'5l21Mu;\^c/k4Y%(j#k=;[`nAhh&=)f^N(a*\A2#[u"&L)SnKc>pY`@s;e2%4nHfi>*#;'O?8:fd=Or=?'sE]cuO5FH7u>,=)dm5dsng<OiOAEP8ID4B.:RBhdIU5":5H?f?I?spq;>&NE%qFs/FM2D$90K1`6crN0<q2UhE2+XG38_8;%>%NS_%S3B_e(fHRR>I,&ITNaC9'=DnF`1=B2]E87I$Sa5?QAIZBm'VrCLW^6Q7*R/#@r69'8Qeo,"]`1V(AWS<-4#"Jm(@r%H?4NQ/^[o!.QRNI@)7QNd-;F6(P*%7:/P'oOF<@m@$ERL)".5AqBUU)41ppAJ16H2U1<4+=mdcmXf5=e^SRkEbEa0C$9b_rB5,*BqC&tCi[KPiFE+7O.fJT5>Z?o+QQ]mhdd5B"A]NkIcV&IUMB44?LG>ednnMKP;+Sr5<=R"N1G!tlt%e+C0*8<:8^Xd9<_>6dE$d>XQb7YgGBM"aQr-FNDX"G+\Xno/+'U.kgC?d0mf[X?\ZCA4#;#r?r(M;)2;H>:!Q.8FK4:_'a6F!jPF4kc,*h8FmnMmh/YgLp!WHYY.6`AmdpnC\.<\dSD@N#FRIFl<la&=lAe_ghn=2G[jrPY4^-cV8W2@!"3k_g$[saA?Y>`"kjG>9SNED<%r1^j"ZjF6\TA)H\,PaZMAAkACXq65drj-eX)m6ZGB3fL9(52*G<jWrI*V]P=-)fg=,Zn@de1;s!R"\nG=ul9h>/a"+;d04]LuAWD1#%%)EUDo:YQkMi,cnWIH8UG,Ip:!dI7H3GGqn(LiFG7a$=Nu(q?!l+b2Xf3$[MJFE7_<%Y\9t5F3\mkq$Pa$3SNBclB_D9uc)r-sI]i&$0LbPqC;M-I$Au7W;Mb59'*0Y'B+gkH-e0k.#,/b!^4;(^_V;!A@65N0A,!CRK%ATeo'e=YnoS5>e'(P=*sX.KZ6',#cN;/ocol(/L?5N8I(f"-j]TQ-Viq+9/Y\YDFHFXZA$dFn9!jAfJqkrAONIf:QJfP\Y'i!9(=9%DZo&boSpSr:Q7?_779JMo5:ff\Gq-38%j.RW(4L@['N\2_u@+TV7L[Ld.)ZWaDrS[JNr)i_Y"7_%t"^nV;S]Zd`]u>B'I])k]_DQWAiko#pJ\*o$]O%QFPjhh8]M76os0n]m7(m:1eF-<8,h'fNd@%,!css1pp59dNu!Yd.oW,E/Y_mpKaMo]e@?9I+k2$IPHQ!Dr:mdAYqH9Q;1"<?dP<]/3UPR7c(RV:X`tN@k_+-mY"^543B."5Q%cf,gaEIfYYn3D9~>endstream
|
||||
endobj
|
||||
16 0 obj
|
||||
<<
|
||||
/Filter [ /ASCII85Decode /FlateDecode ] /Length 1302
|
||||
>>
|
||||
stream
|
||||
GatU2gMYb8&:N/3bbJDk[!7k+V^=]7'X1fN&J>69bBc%?2I5`#bG>@7lT;GK>Z$e],EW"",.VbTkKFg_0VuNDr0J/6qZU52`t0W&=@&HG)(][`j'qY/eD7YB2l>!8]+Lmu"fLglj:cML^5/NeApM8`.N%&HDa0.Lq`AG!JZc#hY2Bu)Xcdo0Mf5ip,m9hVoU<V\qqo/JU)\>$dfn%Z<)3[Cc?6PP1jjW6G]tnnNXgdsI.!n9c''DFAlk'8R_9@\6@RG7?\IPd0Jfk]RRRIs:Y2N'H9^C';X0Q7"_OY0RCV:V`Z8Y6<ZW:&[4ioXn:8qf#e4'3oP09tf\6Tukn([8n8!\hZP4II/c&>J\gR.cZhWYYZF7=i<(41u`5ZeGIfXagD2$aU,Y/sio_X['`fhgro,&7TY3f^A%MchTc\<"8>'&$@J1sW0C1Lmmd+-\Q%EbcRX$jJ$C04psSU)CqPQ=Ft]5$<MC*iTdI/P.q[IAquVHc\6`RAA;TDET2`#^h^9!%@MH,Xc0U;C>\Or(KjiRt]RMuhk>lZ#?R\"&Y&7E"nr`_u$Dbn8aO.#eH[cKA7n6ubL,J$;r'(tFpW&*1h;U`RjRds;YOk0oP.'BDiGUhj^,/)$[bdQ,hE34s70K=YWt1q4W;<(7N4;VK.c#s9W<Ppn)&:c;)Er?TH2@+iGHCojPMp&.;^?^NWAq7TXcE]an?@Q,Iih*:*Pg1f+Y-)$G(]CBf=X%OL(((+=kh>&47Orp1.)3K!@C5H+%K=2ZU-Ca12VslrCFB,,N<ZI0/Eb5aEnJFG.:Z0#MSt1a0MOl:1(2K`9D!di\&V_Wf#=+E*3F!0=7M<N2@qDHRQ4,?L=+=>N8)^[J(-dLi"l`>Z74a.>%+6$V!:j9TSi<M^OT?:3b-FG`87a'KEtJ8`C:eY4X6Rupeu6^#%'jG8'G$Z!Rk&Ya$"]E5oBiHE9rk\sTe<W`m.F@aV!s.n07q3eSSNd^G9rJk>hCW6fc^,cdJ2(b?&6@Xb\$0?\IR*#ZqsubM021V9Eug]VeQ,;JS+DSY#T2-PNLJ75""#^8Z(ECXZPXr1q'*9c@s=T0H>B7G[Hq.)BCQgP2]"89SKW;a2UNE;CfI=+e#M`Ki.l-p:GHD$QU!$,sac&[aX7$7BgI9Am(8/#-T#L"08oj)\UQ]+J\XE%Kg0DZ"eiC5atN,IEeU4)PQ9EZpNFYCA_"ADe\ot*`2@7Un`@V#VPSI*pPYQrIi6"g1&&0GubC+mtjTG2HJRq^$4\A"%ZkQe#?ri-BAc\\q<L73inHN:H.t9DMHPg)qZA^~>endstream
|
||||
endobj
|
||||
xref
|
||||
0 17
|
||||
0000000000 65535 f
|
||||
0000000073 00000 n
|
||||
0000000114 00000 n
|
||||
0000000221 00000 n
|
||||
0000000333 00000 n
|
||||
0000000528 00000 n
|
||||
0000000723 00000 n
|
||||
0000000918 00000 n
|
||||
0000001113 00000 n
|
||||
0000001308 00000 n
|
||||
0000001377 00000 n
|
||||
0000001683 00000 n
|
||||
0000001767 00000 n
|
||||
0000004004 00000 n
|
||||
0000006450 00000 n
|
||||
0000008798 00000 n
|
||||
0000011610 00000 n
|
||||
trailer
|
||||
<<
|
||||
/ID
|
||||
[<2ea7118942454ce9d6e3514eaf0def7b><2ea7118942454ce9d6e3514eaf0def7b>]
|
||||
% ReportLab generated PDF document -- digest (http://www.reportlab.com)
|
||||
|
||||
/Info 10 0 R
|
||||
/Root 9 0 R
|
||||
/Size 17
|
||||
>>
|
||||
startxref
|
||||
13004
|
||||
%%EOF
|
||||
BIN
frontend/public/guide/ maintenance-records-desktop.png
Normal file
|
After Width: | Height: | Size: 758 KiB |
BIN
frontend/public/guide/add-vehicle-form-desktop.png
Normal file
|
After Width: | Height: | Size: 604 KiB |
BIN
frontend/public/guide/dashboard-desktop.png
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
frontend/public/guide/documents-desktop.png
Normal file
|
After Width: | Height: | Size: 943 KiB |
BIN
frontend/public/guide/fuel-logs-desktop.png
Normal file
|
After Width: | Height: | Size: 839 KiB |
BIN
frontend/public/guide/gas-stations-desktop.png
Normal file
|
After Width: | Height: | Size: 1012 KiB |
BIN
frontend/public/guide/log-fuel-modal-desktop.png
Normal file
|
After Width: | Height: | Size: 677 KiB |
BIN
frontend/public/guide/login-desktop.png
Normal file
|
After Width: | Height: | Size: 234 KiB |
BIN
frontend/public/guide/maintenance-schedules-desktop.png
Normal file
|
After Width: | Height: | Size: 698 KiB |
BIN
frontend/public/guide/onboarding-desktop.png
Normal file
|
After Width: | Height: | Size: 884 KiB |
BIN
frontend/public/guide/settings-desktop.png
Normal file
|
After Width: | Height: | Size: 671 KiB |
BIN
frontend/public/guide/vehicle-detail-desktop.png
Normal file
|
After Width: | Height: | Size: 553 KiB |
BIN
frontend/public/guide/vin-decode-desktop.png
Normal file
|
After Width: | Height: | Size: 657 KiB |
@@ -47,6 +47,9 @@ const AdminLogsMobileScreen = lazy(() => import('./features/admin/mobile/AdminLo
|
||||
const AdminCommunityStationsPage = lazy(() => import('./features/admin/pages/AdminCommunityStationsPage').then(m => ({ default: m.AdminCommunityStationsPage })));
|
||||
const AdminCommunityStationsMobileScreen = lazy(() => import('./features/admin/mobile/AdminCommunityStationsMobileScreen').then(m => ({ default: m.AdminCommunityStationsMobileScreen })));
|
||||
|
||||
// Public pages (lazy-loaded)
|
||||
const GuidePage = lazy(() => import('./pages/GuidePage/GuidePage').then(m => ({ default: m.GuidePage })));
|
||||
|
||||
// Auth pages (lazy-loaded)
|
||||
const SignupPage = lazy(() => import('./features/auth/pages/SignupPage').then(m => ({ default: m.SignupPage })));
|
||||
const VerifyEmailPage = lazy(() => import('./features/auth/pages/VerifyEmailPage').then(m => ({ default: m.VerifyEmailPage })));
|
||||
@@ -368,7 +371,7 @@ function App() {
|
||||
// Skip on auth routes -- their query params must survive until Auth0 SDK processes them
|
||||
useEffect(() => {
|
||||
const path = window.location.pathname;
|
||||
if (path === '/callback' || path === '/signup' || path === '/verify-email') return;
|
||||
if (path === '/callback' || path === '/signup' || path === '/verify-email' || path === '/guide' || path === '/guide/') return;
|
||||
const screen = routeToScreen[path];
|
||||
if (screen && screen !== activeScreen) {
|
||||
navigateToScreen(screen, { source: 'url-sync' });
|
||||
@@ -380,7 +383,7 @@ function App() {
|
||||
// Auth0 SDK needs for handleRedirectCallback (child effects fire before parent effects)
|
||||
useEffect(() => {
|
||||
const path = window.location.pathname;
|
||||
if (path === '/callback' || path === '/signup' || path === '/verify-email') return;
|
||||
if (path === '/callback' || path === '/signup' || path === '/verify-email' || path === '/guide' || path === '/guide/') return;
|
||||
const targetPath = screenToRoute[activeScreen];
|
||||
if (targetPath && path !== targetPath) {
|
||||
window.history.replaceState(null, '', targetPath);
|
||||
@@ -499,8 +502,9 @@ function App() {
|
||||
const isSignupRoute = location.pathname === '/signup';
|
||||
const isVerifyEmailRoute = location.pathname === '/verify-email';
|
||||
const isOnboardingRoute = location.pathname === '/onboarding';
|
||||
const isGuideRoute = location.pathname === '/guide' || location.pathname === '/guide/';
|
||||
const isAuthRoute = isSignupRoute || isVerifyEmailRoute || isOnboardingRoute;
|
||||
const shouldShowHomePage = !isGarageRoute && !isCallbackRoute && !isAuthRoute;
|
||||
const shouldShowHomePage = !isGarageRoute && !isCallbackRoute && !isAuthRoute && !isGuideRoute;
|
||||
|
||||
const [callbackTimedOut, setCallbackTimedOut] = useState(false);
|
||||
useEffect(() => {
|
||||
@@ -635,6 +639,21 @@ function App() {
|
||||
);
|
||||
}
|
||||
|
||||
if (isGuideRoute) {
|
||||
return (
|
||||
<ThemeProvider>
|
||||
<React.Suspense fallback={
|
||||
<div className="flex items-center justify-center min-h-screen bg-nero">
|
||||
<div className="text-lg text-avus">Loading guide...</div>
|
||||
</div>
|
||||
}>
|
||||
<GuidePage />
|
||||
</React.Suspense>
|
||||
<DebugInfo />
|
||||
</ThemeProvider>
|
||||
);
|
||||
}
|
||||
|
||||
// Signup route is public - no authentication required
|
||||
if (isSignupRoute) {
|
||||
return (
|
||||
|
||||
@@ -14,6 +14,7 @@ import BuildRoundedIcon from '@mui/icons-material/BuildRounded';
|
||||
import PlaceRoundedIcon from '@mui/icons-material/PlaceRounded';
|
||||
import SettingsRoundedIcon from '@mui/icons-material/SettingsRounded';
|
||||
import DescriptionRoundedIcon from '@mui/icons-material/DescriptionRounded';
|
||||
import HelpOutlineRoundedIcon from '@mui/icons-material/HelpOutlineRounded';
|
||||
import MenuIcon from '@mui/icons-material/Menu';
|
||||
import ChevronLeftRoundedIcon from '@mui/icons-material/ChevronLeftRounded';
|
||||
import ChevronRightRoundedIcon from '@mui/icons-material/ChevronRightRounded';
|
||||
@@ -51,6 +52,7 @@ export const Layout: React.FC<LayoutProps> = ({ children, mobileMode = false })
|
||||
{ name: 'Gas Stations', href: '/garage/stations', icon: <PlaceRoundedIcon sx={{ fontSize: 20 }} /> },
|
||||
{ name: 'Documents', href: '/garage/documents', icon: <DescriptionRoundedIcon sx={{ fontSize: 20 }} /> },
|
||||
{ name: 'Settings', href: '/garage/settings', icon: <SettingsRoundedIcon sx={{ fontSize: 20 }} /> },
|
||||
{ name: 'Guide', href: '/guide', icon: <HelpOutlineRoundedIcon sx={{ fontSize: 20 }} /> },
|
||||
];
|
||||
|
||||
const sidebarWidth = sidebarCollapsed ? 64 : 256;
|
||||
|
||||
20
frontend/src/pages/CLAUDE.md
Normal file
@@ -0,0 +1,20 @@
|
||||
# frontend/src/pages/
|
||||
|
||||
Page-level components and routing targets.
|
||||
|
||||
## Files
|
||||
|
||||
| File | What | When to read |
|
||||
| ---- | ---- | ------------ |
|
||||
| `HomePage.tsx` | Public landing page (Home, Features, About, Guide, Sign Up, Login) | Modifying public site |
|
||||
| `SettingsPage.tsx` | Settings page component | User settings |
|
||||
| `SecuritySettingsPage.tsx` | Security settings page | Security/privacy settings |
|
||||
|
||||
## Subdirectories
|
||||
|
||||
| Directory | What | When to read |
|
||||
| --------- | ---- | ------------ |
|
||||
| `GuidePage/` | Public user guide at `/guide` (10 sections, TOC, screenshots) | Guide content or structure |
|
||||
| `HomePage/` | HomePage sub-components (HeroCarousel, FeaturesGrid) | Landing page features |
|
||||
| `admin/` | Admin-only pages | Admin functionality |
|
||||
| `__tests__/` | Page-level integration tests | Testing pages |
|
||||
34
frontend/src/pages/GuidePage/CLAUDE.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# frontend/src/pages/GuidePage/
|
||||
|
||||
Public-facing user guide page at `/guide`. Renders `docs/USER-GUIDE.md` content as styled React components with screenshots.
|
||||
|
||||
## Files
|
||||
|
||||
| File | What | When to read |
|
||||
| ---- | ---- | ------------ |
|
||||
| `GuidePage.tsx` | Main page component with layout, nav bar, and section rendering | Modifying page structure or navigation |
|
||||
| `GuideTableOfContents.tsx` | Sticky sidebar TOC (desktop) / collapsible accordion TOC (mobile) | Modifying TOC behavior or styling |
|
||||
| `guideTypes.ts` | Section metadata (id, title, subSections) used by TOC and anchors | Adding/renaming sections |
|
||||
|
||||
## Subdirectories
|
||||
|
||||
| Directory | What | When to read |
|
||||
| --------- | ---- | ------------ |
|
||||
| `components/` | Shared components (GuideScreenshot, GuideTable) | Modifying screenshot or table rendering |
|
||||
| `sections/` | 10 content section components (one per guide chapter) | Updating guide content |
|
||||
|
||||
## Architecture
|
||||
|
||||
- Static JSX components (no react-markdown dependency); content changes require editing section files directly
|
||||
- Each section is 150-250 lines of JSX; individual files prevent a 2000+ line monolith
|
||||
- GuideScreenshot provides consistent lazy loading (`loading="lazy"`), responsive sizing, and WebP support across all sections
|
||||
- GuideTable renders MUI Table from `headers[]` and `rows[][]` arrays, preventing verbose MUI Table boilerplate in each section
|
||||
- The page has its own public nav bar (matching HomePage style) because it is accessible without authentication
|
||||
- `/guide` route is detected in App.tsx and rendered outside the authenticated `/garage/*` shell
|
||||
|
||||
## Key Patterns
|
||||
|
||||
- Section anchor IDs must match `guideTypes.ts` section IDs for TOC smooth scroll to work
|
||||
- Screenshots stored in `frontend/public/guide/` as static assets with `loading="lazy"`
|
||||
- TOC uses `window.innerWidth < 768` breakpoint: sidebar on desktop, MUI Accordion on mobile
|
||||
- Guide link in HamburgerDrawer uses `window.location.href` (not Zustand navigation) because `/guide` is outside the `/garage/*` shell
|
||||
257
frontend/src/pages/GuidePage/GuidePage.tsx
Normal file
@@ -0,0 +1,257 @@
|
||||
import { useState, useEffect, useCallback, Suspense } from 'react';
|
||||
import { useAuth0 } from '@auth0/auth0-react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { GuideTableOfContents } from './GuideTableOfContents';
|
||||
import { guideSections } from './guideTypes';
|
||||
import {
|
||||
GettingStartedSection,
|
||||
DashboardSection,
|
||||
VehiclesSection,
|
||||
FuelLogsSection,
|
||||
MaintenanceSection,
|
||||
GasStationsSection,
|
||||
DocumentsSection,
|
||||
SettingsSection,
|
||||
SubscriptionSection,
|
||||
MobileExperienceSection,
|
||||
} from './sections';
|
||||
|
||||
export const GuidePage = () => {
|
||||
const { loginWithRedirect, isAuthenticated } = useAuth0();
|
||||
const navigate = useNavigate();
|
||||
const [activeSection, setActiveSection] = useState(guideSections[0].id);
|
||||
const [isScrolled, setIsScrolled] = useState(false);
|
||||
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
|
||||
|
||||
const handleAuthAction = useCallback(() => {
|
||||
if (isAuthenticated) {
|
||||
navigate('/garage');
|
||||
return;
|
||||
}
|
||||
loginWithRedirect({ appState: { returnTo: '/garage' } });
|
||||
}, [isAuthenticated, navigate, loginWithRedirect]);
|
||||
|
||||
const handleSignup = useCallback(() => {
|
||||
navigate('/signup');
|
||||
}, [navigate]);
|
||||
|
||||
// Scroll to hash target after lazy-loaded sections render
|
||||
useEffect(() => {
|
||||
const hash = window.location.hash.slice(1);
|
||||
if (!hash) return;
|
||||
|
||||
// Poll for the element since Suspense sections load asynchronously
|
||||
let attempts = 0;
|
||||
const interval = setInterval(() => {
|
||||
const target = document.getElementById(hash);
|
||||
if (target) {
|
||||
clearInterval(interval);
|
||||
target.scrollIntoView({ behavior: 'smooth' });
|
||||
}
|
||||
if (++attempts >= 20) clearInterval(interval);
|
||||
}, 100);
|
||||
|
||||
return () => clearInterval(interval);
|
||||
}, []);
|
||||
|
||||
// Track scroll position for nav background and active section
|
||||
useEffect(() => {
|
||||
const handleScroll = () => {
|
||||
setIsScrolled(window.scrollY > 50);
|
||||
|
||||
// Determine active section from scroll position
|
||||
const sectionElements = guideSections.map((s) => ({
|
||||
id: s.id,
|
||||
element: document.getElementById(s.id),
|
||||
}));
|
||||
|
||||
for (let i = sectionElements.length - 1; i >= 0; i--) {
|
||||
const { id, element } = sectionElements[i];
|
||||
if (element) {
|
||||
const rect = element.getBoundingClientRect();
|
||||
if (rect.top <= 120) {
|
||||
setActiveSection(id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener('scroll', handleScroll, { passive: true });
|
||||
return () => window.removeEventListener('scroll', handleScroll);
|
||||
}, []);
|
||||
|
||||
const sectionFallback = (
|
||||
<div className="py-8 text-center text-titanio/50">Loading section...</div>
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-nero text-avus">
|
||||
{/* Navigation Bar - matches HomePage style */}
|
||||
<nav
|
||||
className={`fixed top-0 left-0 right-0 z-50 transition-colors duration-300 ${
|
||||
isScrolled ? 'bg-nero/95 backdrop-blur-sm' : 'bg-nero'
|
||||
}`}
|
||||
>
|
||||
<div className="w-full px-4 md:px-8 lg:px-12">
|
||||
<div className="flex justify-between items-center h-16">
|
||||
<div className="flex-shrink-0">
|
||||
<a href="/" className="flex items-center">
|
||||
<img
|
||||
src="/images/logos/motovaultpro-title-slogan.png"
|
||||
alt="MotoVaultPro - Precision Vehicle Management"
|
||||
className="h-8 md:h-10 w-auto"
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{/* Desktop Menu */}
|
||||
<div className="hidden md:flex items-center space-x-8">
|
||||
<a href="/#home" className="text-white/75 hover:text-white transition-colors">
|
||||
Home
|
||||
</a>
|
||||
<a href="/#features" className="text-white/75 hover:text-white transition-colors">
|
||||
Features
|
||||
</a>
|
||||
<a href="/#about" className="text-white/75 hover:text-white transition-colors">
|
||||
About
|
||||
</a>
|
||||
<a
|
||||
href="/guide"
|
||||
className="text-primary-400 font-semibold transition-colors"
|
||||
>
|
||||
Guide
|
||||
</a>
|
||||
<button
|
||||
onClick={handleSignup}
|
||||
className="border border-primary-500/90 text-primary-500 hover:bg-primary-500/10 hover:border-primary-500 font-semibold py-2 px-6 rounded-lg transition-colors duration-300 focus:outline-none focus:ring-2 focus:ring-primary-500/50"
|
||||
>
|
||||
Sign Up
|
||||
</button>
|
||||
<button
|
||||
onClick={handleAuthAction}
|
||||
className="bg-primary-500 hover:bg-primary-600 text-white font-semibold py-2 px-6 rounded-lg transition-colors duration-300 shadow-lg shadow-black/30 focus:outline-none focus:ring-2 focus:ring-primary-500/50"
|
||||
>
|
||||
Login
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Mobile Menu Button */}
|
||||
<div className="md:hidden">
|
||||
<button
|
||||
onClick={() => setMobileMenuOpen(!mobileMenuOpen)}
|
||||
className="text-white/80 hover:text-white focus:outline-none"
|
||||
>
|
||||
<svg
|
||||
className="h-6 w-6"
|
||||
fill="none"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="2"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
{mobileMenuOpen ? (
|
||||
<path d="M6 18L18 6M6 6l12 12" />
|
||||
) : (
|
||||
<path d="M4 6h16M4 12h16M4 18h16" />
|
||||
)}
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Mobile Menu */}
|
||||
{mobileMenuOpen && (
|
||||
<div className="md:hidden py-4 space-y-3 bg-nero/95 backdrop-blur-sm border-t border-white/10">
|
||||
<a href="/" className="block text-white/75 hover:text-white transition-colors py-2">
|
||||
Home
|
||||
</a>
|
||||
<a href="/#features" className="block text-white/75 hover:text-white transition-colors py-2">
|
||||
Features
|
||||
</a>
|
||||
<a href="/#about" className="block text-white/75 hover:text-white transition-colors py-2">
|
||||
About
|
||||
</a>
|
||||
<a href="/guide" className="block text-primary-400 font-semibold py-2">
|
||||
Guide
|
||||
</a>
|
||||
<button
|
||||
onClick={handleSignup}
|
||||
className="w-full border border-primary-500/90 text-primary-500 hover:bg-primary-500/10 font-semibold py-2 px-6 rounded-lg transition-colors duration-300 focus:outline-none focus:ring-2 focus:ring-primary-500/50"
|
||||
>
|
||||
Sign Up
|
||||
</button>
|
||||
<button
|
||||
onClick={handleAuthAction}
|
||||
className="w-full bg-primary-500 hover:bg-primary-600 text-white font-semibold py-2 px-6 rounded-lg transition-colors duration-300 focus:outline-none focus:ring-2 focus:ring-primary-500/50"
|
||||
>
|
||||
Login
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
{/* Page Content */}
|
||||
<div className="pt-20 px-4 md:px-8 lg:px-12 max-w-7xl mx-auto">
|
||||
{/* Page Header */}
|
||||
<div className="py-8 md:py-12 border-b border-white/10 mb-8">
|
||||
<h1 className="text-3xl md:text-4xl font-bold text-avus mb-3">
|
||||
User Guide
|
||||
</h1>
|
||||
<p className="text-lg text-titanio/70">
|
||||
Precision Vehicle Management -- Track every mile. Own every detail.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Layout: TOC sidebar + content */}
|
||||
<div className="flex flex-col md:flex-row gap-8 pb-16">
|
||||
<GuideTableOfContents activeSection={activeSection} />
|
||||
|
||||
<main className="flex-1 min-w-0">
|
||||
<Suspense fallback={sectionFallback}>
|
||||
<GettingStartedSection />
|
||||
</Suspense>
|
||||
<Suspense fallback={sectionFallback}>
|
||||
<DashboardSection />
|
||||
</Suspense>
|
||||
<Suspense fallback={sectionFallback}>
|
||||
<VehiclesSection />
|
||||
</Suspense>
|
||||
<Suspense fallback={sectionFallback}>
|
||||
<FuelLogsSection />
|
||||
</Suspense>
|
||||
<Suspense fallback={sectionFallback}>
|
||||
<MaintenanceSection />
|
||||
</Suspense>
|
||||
<Suspense fallback={sectionFallback}>
|
||||
<GasStationsSection />
|
||||
</Suspense>
|
||||
<Suspense fallback={sectionFallback}>
|
||||
<DocumentsSection />
|
||||
</Suspense>
|
||||
<Suspense fallback={sectionFallback}>
|
||||
<SettingsSection />
|
||||
</Suspense>
|
||||
<Suspense fallback={sectionFallback}>
|
||||
<SubscriptionSection />
|
||||
</Suspense>
|
||||
<Suspense fallback={sectionFallback}>
|
||||
<MobileExperienceSection />
|
||||
</Suspense>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Footer */}
|
||||
<footer className="bg-black text-white py-8 px-4 md:px-8 border-t border-white/10">
|
||||
<div className="max-w-7xl mx-auto text-center">
|
||||
<p className="text-white/50">
|
||||
© {new Date().getFullYear()} FB Technologies LLC. All rights reserved.
|
||||
</p>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
92
frontend/src/pages/GuidePage/GuideTableOfContents.tsx
Normal file
@@ -0,0 +1,92 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { Accordion, AccordionSummary, AccordionDetails } from '@mui/material';
|
||||
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
|
||||
import { guideSections } from './guideTypes';
|
||||
|
||||
interface GuideTableOfContentsProps {
|
||||
activeSection: string;
|
||||
}
|
||||
|
||||
export const GuideTableOfContents = ({ activeSection }: GuideTableOfContentsProps) => {
|
||||
const [isMobile, setIsMobile] = useState(false);
|
||||
const [tocExpanded, setTocExpanded] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const check = () => setIsMobile(window.innerWidth < 768);
|
||||
check();
|
||||
window.addEventListener('resize', check);
|
||||
return () => window.removeEventListener('resize', check);
|
||||
}, []);
|
||||
|
||||
const handleClick = (sectionId: string) => {
|
||||
const element = document.getElementById(sectionId);
|
||||
if (element) {
|
||||
element.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
||||
}
|
||||
if (isMobile) {
|
||||
setTocExpanded(false);
|
||||
}
|
||||
};
|
||||
|
||||
const tocContent = (
|
||||
<nav aria-label="Table of contents">
|
||||
<ul className="space-y-1">
|
||||
{guideSections.map((section) => (
|
||||
<li key={section.id}>
|
||||
<button
|
||||
onClick={() => handleClick(section.id)}
|
||||
className={`w-full text-left px-3 py-3 rounded-md text-sm transition-colors ${
|
||||
activeSection === section.id
|
||||
? 'bg-primary-500/15 text-primary-400 font-semibold'
|
||||
: 'text-titanio/70 hover:text-titanio hover:bg-white/5'
|
||||
}`}
|
||||
>
|
||||
{section.title}
|
||||
</button>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</nav>
|
||||
);
|
||||
|
||||
if (isMobile) {
|
||||
return (
|
||||
<div className="mb-6">
|
||||
<Accordion
|
||||
expanded={tocExpanded}
|
||||
onChange={(_, expanded) => setTocExpanded(expanded)}
|
||||
sx={{
|
||||
backgroundColor: 'rgba(255,255,255,0.03)',
|
||||
border: '1px solid rgba(255,255,255,0.08)',
|
||||
borderRadius: '8px !important',
|
||||
'&:before': { display: 'none' },
|
||||
}}
|
||||
>
|
||||
<AccordionSummary
|
||||
expandIcon={<ExpandMoreIcon sx={{ color: 'rgba(168,184,192,0.7)' }} />}
|
||||
sx={{
|
||||
color: 'rgba(242,243,246,0.9)',
|
||||
fontWeight: 600,
|
||||
minHeight: 48,
|
||||
'& .MuiAccordionSummary-content': { margin: '12px 0' },
|
||||
}}
|
||||
>
|
||||
Table of Contents
|
||||
</AccordionSummary>
|
||||
<AccordionDetails sx={{ pt: 0 }}>
|
||||
{tocContent}
|
||||
</AccordionDetails>
|
||||
</Accordion>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<aside className="sticky top-20 w-64 flex-shrink-0 max-h-[calc(100vh-6rem)] overflow-y-auto pr-4">
|
||||
<h2 className="text-sm font-semibold text-titanio/50 uppercase tracking-wider mb-4 px-3">
|
||||
Contents
|
||||
</h2>
|
||||
{tocContent}
|
||||
</aside>
|
||||
);
|
||||
};
|
||||
26
frontend/src/pages/GuidePage/components/GuideScreenshot.tsx
Normal file
@@ -0,0 +1,26 @@
|
||||
interface GuideScreenshotProps {
|
||||
src: string;
|
||||
alt: string;
|
||||
caption?: string;
|
||||
mobile?: boolean;
|
||||
}
|
||||
|
||||
export const GuideScreenshot = ({ src, alt, caption, mobile }: GuideScreenshotProps) => {
|
||||
return (
|
||||
<figure className={`my-6 ${mobile ? 'max-w-[375px]' : 'max-w-4xl'} mx-auto`}>
|
||||
<div className="rounded-lg overflow-hidden border border-white/10 shadow-lg shadow-black/20">
|
||||
<img
|
||||
src={src}
|
||||
alt={alt}
|
||||
loading="lazy"
|
||||
className="w-full h-auto"
|
||||
/>
|
||||
</div>
|
||||
{caption && (
|
||||
<figcaption className="mt-2 text-center text-sm text-titanio/70 italic">
|
||||
{caption}
|
||||
</figcaption>
|
||||
)}
|
||||
</figure>
|
||||
);
|
||||
};
|
||||
68
frontend/src/pages/GuidePage/components/GuideTable.tsx
Normal file
@@ -0,0 +1,68 @@
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableContainer,
|
||||
TableHead,
|
||||
TableRow,
|
||||
Paper,
|
||||
} from '@mui/material';
|
||||
|
||||
interface GuideTableProps {
|
||||
headers: string[];
|
||||
rows: string[][];
|
||||
}
|
||||
|
||||
export const GuideTable = ({ headers, rows }: GuideTableProps) => {
|
||||
return (
|
||||
<TableContainer
|
||||
component={Paper}
|
||||
sx={{
|
||||
my: 3,
|
||||
backgroundColor: 'rgba(255,255,255,0.03)',
|
||||
border: '1px solid rgba(255,255,255,0.08)',
|
||||
borderRadius: 2,
|
||||
}}
|
||||
>
|
||||
<Table size="small">
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
{headers.map((header, idx) => (
|
||||
<TableCell
|
||||
key={idx}
|
||||
sx={{
|
||||
fontWeight: 600,
|
||||
color: 'rgba(168,184,192,0.9)',
|
||||
borderBottom: '1px solid rgba(255,255,255,0.08)',
|
||||
fontSize: '0.85rem',
|
||||
whiteSpace: 'nowrap',
|
||||
}}
|
||||
>
|
||||
{header}
|
||||
</TableCell>
|
||||
))}
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{rows.map((row, rowIdx) => (
|
||||
<TableRow key={rowIdx}>
|
||||
{row.map((cell, cellIdx) => (
|
||||
<TableCell
|
||||
key={cellIdx}
|
||||
sx={{
|
||||
color: 'rgba(168,184,192,0.75)',
|
||||
borderBottom: '1px solid rgba(255,255,255,0.04)',
|
||||
fontSize: '0.85rem',
|
||||
verticalAlign: 'top',
|
||||
}}
|
||||
>
|
||||
{cell}
|
||||
</TableCell>
|
||||
))}
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
);
|
||||
};
|
||||
114
frontend/src/pages/GuidePage/guideTypes.ts
Normal file
@@ -0,0 +1,114 @@
|
||||
export interface GuideSubSection {
|
||||
id: string;
|
||||
title: string;
|
||||
}
|
||||
|
||||
export interface GuideSection {
|
||||
id: string;
|
||||
title: string;
|
||||
subSections: GuideSubSection[];
|
||||
}
|
||||
|
||||
export const guideSections: GuideSection[] = [
|
||||
{
|
||||
id: 'getting-started',
|
||||
title: '1. Getting Started',
|
||||
subSections: [
|
||||
{ id: 'creating-an-account', title: 'Creating an Account' },
|
||||
{ id: 'logging-in', title: 'Logging In' },
|
||||
{ id: 'onboarding', title: 'Onboarding' },
|
||||
{ id: 'trouble-logging-in', title: 'Trouble Logging In' },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'dashboard',
|
||||
title: '2. Dashboard',
|
||||
subSections: [
|
||||
{ id: 'your-fleet-overview', title: 'Your Fleet Overview' },
|
||||
{ id: 'quick-actions', title: 'Quick Actions' },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'vehicles',
|
||||
title: '3. Vehicles',
|
||||
subSections: [
|
||||
{ id: 'viewing-your-vehicles', title: 'Viewing Your Vehicles' },
|
||||
{ id: 'adding-a-vehicle', title: 'Adding a Vehicle' },
|
||||
{ id: 'vin-decode', title: 'VIN Decode' },
|
||||
{ id: 'vehicle-detail-page', title: 'Vehicle Detail Page' },
|
||||
{ id: 'editing-a-vehicle', title: 'Editing a Vehicle' },
|
||||
{ id: 'deleting-a-vehicle', title: 'Deleting a Vehicle' },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'fuel-logs',
|
||||
title: '4. Fuel Logs',
|
||||
subSections: [
|
||||
{ id: 'fuel-logs-overview', title: 'Fuel Logs Overview' },
|
||||
{ id: 'logging-fuel', title: 'Logging Fuel' },
|
||||
{ id: 'receipt-scanning', title: 'Receipt Scanning' },
|
||||
{ id: 'editing-and-deleting-fuel-logs', title: 'Editing and Deleting Fuel Logs' },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'maintenance',
|
||||
title: '5. Maintenance',
|
||||
subSections: [
|
||||
{ id: 'maintenance-records', title: 'Maintenance Records' },
|
||||
{ id: 'adding-a-maintenance-record', title: 'Adding a Maintenance Record' },
|
||||
{ id: 'maintenance-schedules', title: 'Maintenance Schedules' },
|
||||
{ id: 'creating-a-schedule', title: 'Creating a Schedule' },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'gas-stations',
|
||||
title: '6. Gas Stations',
|
||||
subSections: [
|
||||
{ id: 'finding-stations', title: 'Finding Stations' },
|
||||
{ id: 'saved-stations', title: 'Saved Stations' },
|
||||
{ id: 'premium-93-stations', title: 'Premium 93 Stations' },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'documents',
|
||||
title: '7. Documents',
|
||||
subSections: [
|
||||
{ id: 'documents-overview', title: 'Documents Overview' },
|
||||
{ id: 'adding-a-document', title: 'Adding a Document' },
|
||||
{ id: 'document-types', title: 'Document Types' },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'settings',
|
||||
title: '8. Settings',
|
||||
subSections: [
|
||||
{ id: 'profile', title: 'Profile' },
|
||||
{ id: 'security-and-privacy', title: 'Security and Privacy' },
|
||||
{ id: 'subscription', title: 'Subscription' },
|
||||
{ id: 'notifications', title: 'Notifications' },
|
||||
{ id: 'appearance-and-units', title: 'Appearance and Units' },
|
||||
{ id: 'data-import-and-export', title: 'Data Import and Export' },
|
||||
{ id: 'account-actions', title: 'Account Actions' },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'subscription-tiers',
|
||||
title: '9. Subscription Tiers and Pro Features',
|
||||
subSections: [
|
||||
{ id: 'tier-comparison', title: 'Tier Comparison' },
|
||||
{ id: 'vin-camera-scanning', title: 'VIN Camera Scanning (Pro)' },
|
||||
{ id: 'fuel-receipt-scanning', title: 'Fuel Receipt Scanning (Pro)' },
|
||||
{ id: 'maintenance-receipt-scanning', title: 'Maintenance Receipt Scanning (Pro)' },
|
||||
{ id: 'maintenance-manual-pdf', title: 'Maintenance Manual PDF (Pro)' },
|
||||
{ id: 'email-ingestion', title: 'Email Ingestion (Pro)' },
|
||||
{ id: 'shared-vehicle-documents', title: 'Shared Vehicle Documents (Pro)' },
|
||||
{ id: 'community-station-submissions', title: 'Community Station Submissions (Pro)' },
|
||||
{ id: 'managing-your-subscription', title: 'Managing Your Subscription' },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'mobile-experience',
|
||||
title: '10. Mobile Experience',
|
||||
subSections: [],
|
||||
},
|
||||
];
|
||||
156
frontend/src/pages/GuidePage/sections/DashboardSection.tsx
Normal file
@@ -0,0 +1,156 @@
|
||||
import { GuideTable } from '../components/GuideTable';
|
||||
import { GuideScreenshot } from '../components/GuideScreenshot';
|
||||
|
||||
export const DashboardSection = () => {
|
||||
return (
|
||||
<section id="dashboard" className="py-8 border-b border-white/5 scroll-mt-24">
|
||||
<h2 className="text-2xl font-bold text-avus mb-4">2. Dashboard</h2>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
After logging in, you land on the Dashboard -- your fleet headquarters.
|
||||
</p>
|
||||
|
||||
{/* Your Fleet Overview */}
|
||||
<div id="your-fleet-overview" className="scroll-mt-24">
|
||||
<h3 className="text-xl font-semibold text-avus mb-3 mt-8">Your Fleet Overview</h3>
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
<strong className="text-avus">What You See</strong>
|
||||
</p>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
The Dashboard displays a "Your Fleet" heading with all your vehicles shown as cards in a grid layout. Each vehicle card shows:
|
||||
</p>
|
||||
|
||||
<ul className="list-disc list-inside text-titanio/70 space-y-2 mb-4 ml-4">
|
||||
<li>
|
||||
<strong className="text-avus">Vehicle icon</strong> -- A small colored indicator badge (varies by vehicle)
|
||||
</li>
|
||||
<li>
|
||||
<strong className="text-avus">Vehicle name</strong> -- The nickname or full name (e.g., "Beast", "MERLOT")
|
||||
</li>
|
||||
<li>
|
||||
<strong className="text-avus">Health status</strong> -- A green dot indicates "All clear" (no overdue maintenance); other colors indicate attention needed
|
||||
</li>
|
||||
<li>
|
||||
<strong className="text-avus">Status text</strong> -- "All clear" or a maintenance alert message
|
||||
</li>
|
||||
<li>
|
||||
<strong className="text-avus">Odometer reading</strong> -- Current mileage (e.g., "35,000 mi")
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<GuideScreenshot
|
||||
src="/guide/dashboard-desktop.png"
|
||||
alt="Dashboard showing vehicle fleet overview with health status cards"
|
||||
caption="The Dashboard displays your vehicle fleet with health status and quick actions"
|
||||
/>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
<strong className="text-avus">Click any vehicle card</strong> to go directly to that vehicle's detail page.
|
||||
</p>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
The vehicle health status system provides at-a-glance monitoring of your fleet:
|
||||
</p>
|
||||
|
||||
<ul className="list-disc list-inside text-titanio/70 space-y-2 mb-4 ml-4">
|
||||
<li>
|
||||
<strong className="text-avus">Green</strong> -- All maintenance is current, no action needed
|
||||
</li>
|
||||
<li>
|
||||
<strong className="text-avus">Yellow</strong> -- Maintenance due soon (within the next 500 miles or 1 month)
|
||||
</li>
|
||||
<li>
|
||||
<strong className="text-avus">Red</strong> -- Maintenance overdue or critical attention required
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
The Dashboard layout adapts to your screen size. On desktop, vehicle cards display in a 3-column grid. On tablets, they adjust to 2 columns. On mobile devices, cards stack vertically for easy scrolling.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Quick Actions */}
|
||||
<div id="quick-actions" className="scroll-mt-24">
|
||||
<h3 className="text-xl font-semibold text-avus mb-3 mt-8">Quick Actions</h3>
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
Two action buttons appear in the top-right corner of the Dashboard:
|
||||
</p>
|
||||
|
||||
<GuideTable
|
||||
headers={['Button', 'Action']}
|
||||
rows={[
|
||||
['+ Add Vehicle', 'Opens the Add Vehicle form on the Vehicles page'],
|
||||
['LOG FUEL', 'Opens the fuel logging modal to quickly record a fill-up'],
|
||||
]}
|
||||
/>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
These quick actions let you perform the most common tasks without navigating away from the Dashboard.
|
||||
</p>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
The <strong className="text-avus">LOG FUEL</strong> button opens a modal where you can quickly record a fuel fill-up for any vehicle. This is the fastest way to log fuel after visiting a gas station. The modal pre-fills with the current date and time, and calculates MPG automatically based on your odometer reading.
|
||||
</p>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
The <strong className="text-avus">+ Add Vehicle</strong> button takes you directly to the Vehicles page with the add form expanded, ready for you to enter your new vehicle's details.
|
||||
</p>
|
||||
|
||||
<h4 className="text-lg font-semibold text-avus mb-3 mt-6">Navigation Sidebar</h4>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
The left sidebar provides access to all sections of the app:
|
||||
</p>
|
||||
|
||||
<GuideTable
|
||||
headers={['Menu Item', 'Description']}
|
||||
rows={[
|
||||
['Dashboard', 'Fleet overview (home)'],
|
||||
['Vehicles', 'Manage your vehicle collection'],
|
||||
['Fuel Logs', 'Track fuel purchases and efficiency'],
|
||||
['Maintenance', 'Record service history and set schedules'],
|
||||
['Gas Stations', 'Find and save gas stations'],
|
||||
['Documents', 'Store vehicle-related documents'],
|
||||
['Settings', 'Account, preferences, and data management'],
|
||||
]}
|
||||
/>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
At the bottom of the sidebar you will see your email address and a <strong className="text-avus">Sign Out</strong> button.
|
||||
</p>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
The header bar at the top shows a notification bell icon and a "Welcome back" greeting with your email.
|
||||
</p>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
On mobile devices, the navigation experience changes:
|
||||
</p>
|
||||
|
||||
<ul className="list-disc list-inside text-titanio/70 space-y-2 mb-4 ml-4">
|
||||
<li>
|
||||
The left sidebar is hidden and replaced by a <strong className="text-avus">bottom navigation bar</strong> for quick access to Dashboard, Vehicles, and Stations
|
||||
</li>
|
||||
<li>
|
||||
A <strong className="text-avus">floating action button (FAB)</strong> appears in the center with quick actions for logging fuel, adding vehicles, and more
|
||||
</li>
|
||||
<li>
|
||||
The full menu is accessible via a <strong className="text-avus">hamburger menu</strong> in the header that slides up from the bottom
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<GuideScreenshot
|
||||
src="/guide/dashboard-mobile.png"
|
||||
alt="Dashboard on mobile device showing responsive layout"
|
||||
caption="The Dashboard adapts to mobile screens with a responsive grid layout"
|
||||
mobile
|
||||
/>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
The Dashboard is designed as your central hub for managing your entire fleet. From here, you can monitor vehicle health, access quick actions, and navigate to any section of the application. The responsive design ensures a consistent experience whether you are using a desktop computer, tablet, or mobile phone.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
102
frontend/src/pages/GuidePage/sections/DocumentsSection.tsx
Normal file
@@ -0,0 +1,102 @@
|
||||
import { GuideTable } from '../components/GuideTable';
|
||||
import { GuideScreenshot } from '../components/GuideScreenshot';
|
||||
|
||||
export const DocumentsSection = () => {
|
||||
return (
|
||||
<section id="documents" className="py-8 border-b border-white/5 scroll-mt-24">
|
||||
<h2 className="text-2xl font-bold text-avus mb-4">7. Documents</h2>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
Click <strong className="text-avus">Documents</strong> in the sidebar. This page stores all your vehicle-related paperwork digitally.
|
||||
</p>
|
||||
|
||||
<h3 id="documents-overview" className="text-xl font-semibold text-avus mb-3 mt-8">
|
||||
Documents Overview
|
||||
</h3>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
The page shows the title "Documents" with an <strong className="text-avus">Add Document</strong> button in the top-right corner.
|
||||
</p>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
If you have no documents yet, you will see an empty state:
|
||||
</p>
|
||||
|
||||
<ul className="list-disc list-inside text-titanio/70 space-y-2 mb-4 ml-4">
|
||||
<li>A document icon</li>
|
||||
<li>"No Documents Yet"</li>
|
||||
<li>"You haven't added any documents yet. Documents will appear here once you create them."</li>
|
||||
<li>A <strong className="text-avus">Go to Vehicles</strong> button (since documents are associated with vehicles)</li>
|
||||
</ul>
|
||||
|
||||
<GuideScreenshot
|
||||
src="/guide/documents-desktop.png"
|
||||
alt="Documents page showing document storage"
|
||||
caption="The Documents page for managing vehicle-related paperwork"
|
||||
/>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
When documents exist, they appear in a list/grid with preview thumbnails, titles, document types, and associated vehicles.
|
||||
</p>
|
||||
|
||||
<h3 id="adding-a-document" className="text-xl font-semibold text-avus mb-3 mt-8">
|
||||
Adding a Document
|
||||
</h3>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
Click <strong className="text-avus">Add Document</strong> to open the "Add Document" modal with these fields:
|
||||
</p>
|
||||
|
||||
<GuideTable
|
||||
headers={['Field', 'Required', 'Description']}
|
||||
rows={[
|
||||
['Vehicle', 'Yes', 'Select which vehicle this document belongs to (dropdown of your vehicles)'],
|
||||
['Document Type', 'Yes', 'Select the type (see Document Types below)'],
|
||||
['Title', 'Yes', 'A descriptive title (e.g., "Honda CBR600RR Service Manual")'],
|
||||
['Notes', 'Optional', 'Any additional notes about this document'],
|
||||
['Upload image/PDF', 'Yes', 'Click Choose File to upload an image or PDF file'],
|
||||
]}
|
||||
/>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
Click <strong className="text-avus">Create Document</strong> to save, or <strong className="text-avus">Cancel</strong> to discard.
|
||||
</p>
|
||||
|
||||
<h3 id="document-types" className="text-xl font-semibold text-avus mb-3 mt-8">
|
||||
Document Types
|
||||
</h3>
|
||||
|
||||
<GuideTable
|
||||
headers={['Type', 'What to Store']}
|
||||
rows={[
|
||||
['Insurance', 'Insurance policies, cards, declarations pages'],
|
||||
['Registration', 'Vehicle registration documents'],
|
||||
['Maintenance Manual', 'Owner\'s manuals and service manuals'],
|
||||
['Service Records', 'Service history documentation from dealers/shops'],
|
||||
['Recall Notices', 'Vehicle recall notifications'],
|
||||
['Inspection Reports', 'State inspection or emissions test reports'],
|
||||
['Receipts', 'Purchase receipts for parts, accessories, services'],
|
||||
['Other', 'Any other vehicle-related document'],
|
||||
]}
|
||||
/>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
<strong className="text-avus">Insurance documents</strong> have additional fields: Insurance Company, Policy Number, Effective Date, Expiration Date, Coverage amounts (Bodily Injury, Property Damage), and Premium.
|
||||
</p>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
<strong className="text-avus">Registration documents</strong> have additional fields: License Plate, Expiration Date, and Registration Cost.
|
||||
</p>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
Documents with expiration dates will show countdown badges so you know when renewals are coming up.
|
||||
</p>
|
||||
|
||||
<div className="bg-primary-500/10 border border-primary-500/30 rounded-lg p-4 my-4">
|
||||
<p className="text-titanio/70 leading-relaxed">
|
||||
<strong className="text-avus">Pro Feature:</strong> When uploading a Maintenance Manual PDF, Pro and Enterprise users can check <strong className="text-avus">Scan for Maintenance Schedule</strong> to automatically extract a complete maintenance schedule from the document. See Maintenance Manual PDF Extraction (Pro) for the full workflow.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
142
frontend/src/pages/GuidePage/sections/FuelLogsSection.tsx
Normal file
@@ -0,0 +1,142 @@
|
||||
import { GuideTable } from '../components/GuideTable';
|
||||
import { GuideScreenshot } from '../components/GuideScreenshot';
|
||||
|
||||
export const FuelLogsSection = () => {
|
||||
return (
|
||||
<section id="fuel-logs" className="py-8 border-b border-white/5 scroll-mt-24">
|
||||
<h2 className="text-2xl font-bold text-avus mb-4">4. Fuel Logs</h2>
|
||||
|
||||
{/* Fuel Logs Overview */}
|
||||
<div id="fuel-logs-overview" className="scroll-mt-24">
|
||||
<h3 className="text-xl font-semibold text-avus mb-3 mt-8">Fuel Logs Overview</h3>
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
Click <strong className="text-avus">Fuel Logs</strong> in the sidebar to see the Fuel Logs page. At the top, you see summary statistics:
|
||||
</p>
|
||||
|
||||
<GuideTable
|
||||
headers={['Metric', 'Description']}
|
||||
rows={[
|
||||
['LOGS', 'Total number of fuel entries'],
|
||||
['TOTAL FUEL', 'Total gallons (or liters) across all fill-ups'],
|
||||
['TOTAL COST', 'Total amount spent on fuel'],
|
||||
]}
|
||||
/>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
Below the summary, a table lists all your fuel log entries. If you have no entries yet, you will see "No fuel logs yet."
|
||||
</p>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
The <strong className="text-avus">+ Add Fuel Log</strong> button is in the top-right corner.
|
||||
</p>
|
||||
|
||||
<GuideScreenshot
|
||||
src="/guide/fuel-logs-desktop.png"
|
||||
alt="Fuel Logs page showing summary statistics and fuel log entries table"
|
||||
caption="The Fuel Logs page displays summary statistics and all fuel entries"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Logging Fuel */}
|
||||
<div id="logging-fuel" className="scroll-mt-24">
|
||||
<h3 className="text-xl font-semibold text-avus mb-3 mt-8">Logging Fuel</h3>
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
Click <strong className="text-avus">+ Add Fuel Log</strong> (or the <strong className="text-avus">LOG FUEL</strong> button from the Dashboard) to open the "Log Fuel" modal. The modal title reads "Add Fuel Log" with a note showing your current unit system (e.g., "Displaying in Imperial (miles, gallons, MPG)").
|
||||
</p>
|
||||
|
||||
<h4 className="text-lg font-semibold text-avus mb-3 mt-6">Receipt Scanning</h4>
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
At the top of the form, click <strong className="text-avus">SCAN RECEIPT</strong> to use your camera to photograph a fuel receipt. The OCR system will automatically extract:
|
||||
</p>
|
||||
|
||||
<ul className="list-disc list-inside text-titanio/70 space-y-2 mb-4 ml-4">
|
||||
<li>Fuel amount (gallons)</li>
|
||||
<li>Cost per gallon</li>
|
||||
<li>Total cost</li>
|
||||
<li>Date and time</li>
|
||||
<li>Fuel grade</li>
|
||||
<li>Station name</li>
|
||||
</ul>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
You can review and edit any extracted values before saving.
|
||||
</p>
|
||||
|
||||
<h4 className="text-lg font-semibold text-avus mb-3 mt-6">Form Fields</h4>
|
||||
<GuideTable
|
||||
headers={['Field', 'Required', 'Description']}
|
||||
rows={[
|
||||
['Select Vehicle', 'Yes', 'Choose which vehicle this fill-up is for'],
|
||||
['Date & Time', 'Yes', 'Pre-filled with the current date and time; click the calendar icon to change'],
|
||||
['MPG', 'Auto', 'Calculated automatically from distance and fuel amount'],
|
||||
['Trip Distance / Odometer Reading', 'One required', 'Toggle between entering trip distance (miles driven since last fill) or odometer reading. Click the toggle button to switch modes.'],
|
||||
['Fuel Type', 'Yes', 'Dropdown: Gasoline, Diesel, Electric, Hybrid, etc.'],
|
||||
['Fuel Grade', 'Optional', 'Dropdown: 87 (Regular), 89 (Midgrade), 91 (Premium), 93 (Premium), etc.'],
|
||||
['Fuel Amount', 'Yes', 'Number of gallons (or liters) purchased'],
|
||||
['Cost Per Gallon', 'Yes', 'Price per gallon (or liter)'],
|
||||
['Total Cost', 'Auto', 'Calculated from Fuel Amount x Cost Per Gallon. Displays "Enter fuel amount and cost per unit to see total cost." until both values are provided.'],
|
||||
['Location', 'Optional', 'Type a station name to search and select'],
|
||||
['Notes', 'Optional', 'Any additional notes about this fill-up'],
|
||||
]}
|
||||
/>
|
||||
|
||||
<GuideScreenshot
|
||||
src="/guide/log-fuel-modal-desktop.png"
|
||||
alt="Log Fuel modal with form fields for fuel entry"
|
||||
caption="The Log Fuel modal with all fields for recording a fill-up"
|
||||
/>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
Click <strong className="text-avus">Add Fuel Log</strong> to save the entry. The button is disabled until all required fields are completed.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Receipt Scanning */}
|
||||
<div id="receipt-scanning" className="scroll-mt-24">
|
||||
<h3 className="text-xl font-semibold text-avus mb-3 mt-8">Receipt Scanning</h3>
|
||||
<div className="bg-primary-500/10 border border-primary-500/30 rounded-lg p-4 my-4">
|
||||
<p className="text-titanio/70 leading-relaxed">
|
||||
<strong className="text-avus">Pro Feature:</strong> Receipt scanning requires a Pro or Enterprise subscription. See <a href="#fuel-receipt-scanning" className="text-primary-400 hover:text-primary-300 underline">Fuel Receipt Scanning (Pro)</a> for full details on what is extracted and the review workflow.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
The receipt scanning feature uses OCR technology:
|
||||
</p>
|
||||
|
||||
<ol className="list-decimal list-inside text-titanio/70 space-y-2 mb-4 ml-4">
|
||||
<li>Click <strong className="text-avus">SCAN RECEIPT</strong> at the top of the Log Fuel form</li>
|
||||
<li>Use your camera to photograph the receipt</li>
|
||||
<li>The system extracts fuel data with confidence indicators</li>
|
||||
<li>A review modal appears showing extracted values</li>
|
||||
<li>Edit any incorrect values inline</li>
|
||||
<li>Click <strong className="text-avus">Accept</strong> to auto-fill the form, or <strong className="text-avus">Reject</strong> to enter manually</li>
|
||||
</ol>
|
||||
|
||||
<GuideScreenshot
|
||||
src="/guide/receipt-scan-mobile.png"
|
||||
alt="Mobile device showing receipt scanning with camera"
|
||||
caption="Receipt scanning uses your device camera to extract fuel data"
|
||||
mobile
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Editing and Deleting Fuel Logs */}
|
||||
<div id="editing-and-deleting-fuel-logs" className="scroll-mt-24">
|
||||
<h3 className="text-xl font-semibold text-avus mb-3 mt-8">Editing and Deleting Fuel Logs</h3>
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
From the fuel logs table, each entry has action buttons:
|
||||
</p>
|
||||
|
||||
<ul className="list-disc list-inside text-titanio/70 space-y-2 mb-4 ml-4">
|
||||
<li>
|
||||
<strong className="text-avus">Edit</strong> -- Opens the fuel log in edit mode to update any fields
|
||||
</li>
|
||||
<li>
|
||||
<strong className="text-avus">Delete</strong> -- Removes the fuel log entry (with confirmation)
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
105
frontend/src/pages/GuidePage/sections/GasStationsSection.tsx
Normal file
@@ -0,0 +1,105 @@
|
||||
import { GuideTable } from '../components/GuideTable';
|
||||
import { GuideScreenshot } from '../components/GuideScreenshot';
|
||||
|
||||
export const GasStationsSection = () => {
|
||||
return (
|
||||
<section id="gas-stations" className="py-8 border-b border-white/5 scroll-mt-24">
|
||||
<h2 className="text-2xl font-bold text-avus mb-4">6. Gas Stations</h2>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
Click <strong className="text-avus">Gas Stations</strong> in the sidebar. This page helps you find gas stations near you and save your favorites.
|
||||
</p>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
The page is split into two sections:
|
||||
</p>
|
||||
|
||||
<ul className="list-disc list-inside text-titanio/70 space-y-2 mb-4 ml-4">
|
||||
<li><strong className="text-avus">Left:</strong> An interactive Google Map showing station locations as markers</li>
|
||||
<li><strong className="text-avus">Right:</strong> Search controls</li>
|
||||
</ul>
|
||||
|
||||
<h3 id="finding-stations" className="text-xl font-semibold text-avus mb-3 mt-8">
|
||||
Finding Stations
|
||||
</h3>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
<strong className="text-avus">Search Options</strong>
|
||||
</p>
|
||||
|
||||
<GuideTable
|
||||
headers={['Control', 'Description']}
|
||||
rows={[
|
||||
['Use Current Location', 'Large red button -- uses your device\'s GPS to center the search on your current location'],
|
||||
['Street', 'Enter a street address (e.g., 123 Main St)'],
|
||||
['City', 'Enter a city name'],
|
||||
['State', 'Select from dropdown'],
|
||||
['ZIP', 'Enter a ZIP code'],
|
||||
['Search Radius', 'Slider from 1 mi to 25 mi (default: 5 mi)'],
|
||||
['Search Stations', 'Click to execute the search'],
|
||||
]}
|
||||
/>
|
||||
|
||||
<GuideScreenshot
|
||||
src="/guide/gas-stations-desktop.png"
|
||||
alt="Gas Stations page showing map and search controls"
|
||||
caption="The Gas Stations page with interactive map and search options"
|
||||
/>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
You can either use your current location OR manually enter an address. Search results appear below the map.
|
||||
</p>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
<strong className="text-avus">Search Results</strong>
|
||||
</p>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
Below the map, there are three tabs:
|
||||
</p>
|
||||
|
||||
<GuideTable
|
||||
headers={['Tab', 'Description']}
|
||||
rows={[
|
||||
['RESULTS (n)', 'Stations found by your search, showing count'],
|
||||
['SAVED (n)', 'Your saved/favorite stations'],
|
||||
['PREMIUM 93', 'Stations verified to carry true 93-octane fuel'],
|
||||
]}
|
||||
/>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
Each station result shows:
|
||||
</p>
|
||||
|
||||
<ul className="list-disc list-inside text-titanio/70 space-y-2 mb-4 ml-4">
|
||||
<li>Station name (e.g., "Costco Gas Station", "Mobil")</li>
|
||||
<li>Street address and city</li>
|
||||
<li>Star rating (community-verified)</li>
|
||||
<li>Fuel grade badges (e.g., "93 Octane - w/ Ethanol")</li>
|
||||
<li>Save/unsave button</li>
|
||||
</ul>
|
||||
|
||||
<h3 id="saved-stations" className="text-xl font-semibold text-avus mb-3 mt-8">
|
||||
Saved Stations
|
||||
</h3>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
Click the <strong className="text-avus">SAVED</strong> tab to see your favorite stations. Saved stations also appear as yellow star markers on the map. You can:
|
||||
</p>
|
||||
|
||||
<ul className="list-disc list-inside text-titanio/70 space-y-2 mb-4 ml-4">
|
||||
<li>View station details</li>
|
||||
<li>Remove a station from your saved list</li>
|
||||
<li>Navigate on the map by clicking a station card</li>
|
||||
</ul>
|
||||
|
||||
<h3 id="premium-93-stations" className="text-xl font-semibold text-avus mb-3 mt-8">
|
||||
Premium 93 Stations
|
||||
</h3>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
Click the <strong className="text-avus">PREMIUM 93</strong> tab to see your "Your Premium 93 Stations" -- stations that have been community-verified to carry genuine 93-octane fuel. This is especially useful for performance vehicles that require premium fuel.
|
||||
</p>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
162
frontend/src/pages/GuidePage/sections/GettingStartedSection.tsx
Normal file
@@ -0,0 +1,162 @@
|
||||
import { GuideTable } from '../components/GuideTable';
|
||||
import { GuideScreenshot } from '../components/GuideScreenshot';
|
||||
|
||||
export const GettingStartedSection = () => {
|
||||
return (
|
||||
<section id="getting-started" className="py-8 border-b border-white/5 scroll-mt-24">
|
||||
<h2 className="text-2xl font-bold text-avus mb-4">1. Getting Started</h2>
|
||||
|
||||
{/* Creating an Account */}
|
||||
<div id="creating-an-account" className="scroll-mt-24">
|
||||
<h3 className="text-xl font-semibold text-avus mb-3 mt-8">Creating an Account</h3>
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
Navigate to <a href="https://motovaultpro.com" className="text-primary-400 hover:text-primary-300 underline">motovaultpro.com</a> and click the <strong className="text-avus">Sign Up</strong> button in the top-right corner of the navigation bar.
|
||||
</p>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
<strong className="text-avus">Sign Up Page</strong>
|
||||
</p>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
The registration page displays the MotoVaultPro logo and a clean form with the following fields:
|
||||
</p>
|
||||
|
||||
<GuideTable
|
||||
headers={['Field', 'Required', 'Details']}
|
||||
rows={[
|
||||
['Email Address', 'Yes', 'Your email address (e.g., your.email@example.com)'],
|
||||
['Password', 'Yes', 'Minimum 8 characters, must include one uppercase letter and one number'],
|
||||
['Confirm Password', 'Yes', 'Re-enter your password to confirm'],
|
||||
['Terms & Conditions', 'Yes', 'Checkbox -- you must agree to the Terms & Conditions before creating your account'],
|
||||
]}
|
||||
/>
|
||||
|
||||
<GuideScreenshot
|
||||
src="/guide/signup-desktop.png"
|
||||
alt="Sign Up page with registration form"
|
||||
caption="The Sign Up form with email, password, and terms & conditions fields"
|
||||
/>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
After filling in all fields, click the <strong className="text-avus">Create Account</strong> button.
|
||||
</p>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
If you already have an account, click the <strong className="text-avus">Login</strong> link at the bottom of the form.
|
||||
</p>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
After registration, you will receive a verification email. Click the link in the email to verify your account before logging in.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Logging In */}
|
||||
<div id="logging-in" className="scroll-mt-24">
|
||||
<h3 className="text-xl font-semibold text-avus mb-3 mt-8">Logging In</h3>
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
Click the <strong className="text-avus">Login</strong> button in the top-right corner of the navigation bar. You will be redirected to the secure login page powered by Auth0.
|
||||
</p>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
<strong className="text-avus">Login Page</strong>
|
||||
</p>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
Enter your registered email address, then click <strong className="text-avus">Continue</strong>. On the next screen, enter your password and click <strong className="text-avus">Continue</strong> to log in.
|
||||
</p>
|
||||
|
||||
<GuideScreenshot
|
||||
src="/guide/login-desktop.png"
|
||||
alt="Login page showing email and password entry"
|
||||
caption="The secure Auth0 login page"
|
||||
/>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
After successful authentication, you will be redirected to the Dashboard.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Onboarding */}
|
||||
<div id="onboarding" className="scroll-mt-24">
|
||||
<h3 className="text-xl font-semibold text-avus mb-3 mt-8">Onboarding</h3>
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
First-time users see an onboarding flow with three steps:
|
||||
</p>
|
||||
|
||||
<ol className="list-decimal list-inside text-titanio/70 space-y-2 mb-4 ml-4">
|
||||
<li>
|
||||
<strong className="text-avus">Preferences</strong> -- Choose your preferred unit system (Imperial or Metric), distance units, and notification preferences.
|
||||
</li>
|
||||
<li>
|
||||
<strong className="text-avus">Add Your First Vehicle</strong> -- Enter your first vehicle's details (you can skip this step and add vehicles later).
|
||||
</li>
|
||||
<li>
|
||||
<strong className="text-avus">Complete</strong> -- A welcome screen with quick links to get started exploring the app.
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
<GuideScreenshot
|
||||
src="/guide/onboarding-desktop.png"
|
||||
alt="Onboarding flow showing preferences step"
|
||||
caption="The onboarding flow guides new users through initial setup"
|
||||
/>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
The onboarding experience is designed to get you up and running quickly. During the preferences step, you can configure:
|
||||
</p>
|
||||
|
||||
<ul className="list-disc list-inside text-titanio/70 space-y-2 mb-4 ml-4">
|
||||
<li>Your preferred unit system (Imperial or Metric) for distance, volume, and fuel economy</li>
|
||||
<li>Notification preferences for maintenance reminders</li>
|
||||
<li>Default settings for fuel logging and vehicle tracking</li>
|
||||
</ul>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
The optional vehicle setup step allows you to add your first vehicle immediately, but you can skip it and add vehicles later from the Vehicles page.
|
||||
</p>
|
||||
|
||||
<GuideScreenshot
|
||||
src="/guide/onboarding-mobile.png"
|
||||
alt="Mobile onboarding showing vehicle setup step"
|
||||
caption="The onboarding flow is fully responsive and works on mobile devices"
|
||||
mobile
|
||||
/>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
Once onboarding is complete, you will land on the Dashboard and can begin managing your fleet immediately.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Trouble Logging In */}
|
||||
<div id="trouble-logging-in" className="scroll-mt-24">
|
||||
<h3 className="text-xl font-semibold text-avus mb-3 mt-8">Trouble Logging In</h3>
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
If you are having trouble logging in, try the following password reset and account recovery options.
|
||||
</p>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
Common login issues and solutions:
|
||||
</p>
|
||||
|
||||
<ul className="list-disc list-inside text-titanio/70 space-y-2 mb-4 ml-4">
|
||||
<li>
|
||||
<strong className="text-avus">Forgot Password</strong> -- Use the password reset link to receive a reset email
|
||||
</li>
|
||||
<li>
|
||||
<strong className="text-avus">Account Not Verified</strong> -- Check your email for the verification link sent during signup
|
||||
</li>
|
||||
<li>
|
||||
<strong className="text-avus">Locked Account</strong> -- Contact support if your account has been locked due to multiple failed login attempts
|
||||
</li>
|
||||
<li>
|
||||
<strong className="text-avus">Browser Issues</strong> -- Try clearing your browser cache or using a different browser
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
MotoVaultPro uses Auth0 for secure authentication, ensuring your account credentials are protected with industry-standard security measures including encryption and multi-factor authentication support.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
137
frontend/src/pages/GuidePage/sections/MaintenanceSection.tsx
Normal file
@@ -0,0 +1,137 @@
|
||||
import { GuideTable } from '../components/GuideTable';
|
||||
import { GuideScreenshot } from '../components/GuideScreenshot';
|
||||
|
||||
export const MaintenanceSection = () => {
|
||||
return (
|
||||
<section id="maintenance" className="py-8 border-b border-white/5 scroll-mt-24">
|
||||
<h2 className="text-2xl font-bold text-avus mb-4">5. Maintenance</h2>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
Click <strong className="text-avus">Maintenance</strong> in the sidebar. This page has two tabs: <strong className="text-avus">RECORDS</strong> and <strong className="text-avus">SCHEDULES</strong>.
|
||||
</p>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
At the top is a <strong className="text-avus">Vehicle</strong> dropdown to select which vehicle you are viewing or adding maintenance for.
|
||||
</p>
|
||||
|
||||
{/* Maintenance Records */}
|
||||
<div id="maintenance-records" className="scroll-mt-24">
|
||||
<h3 className="text-xl font-semibold text-avus mb-3 mt-8">Maintenance Records</h3>
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
The <strong className="text-avus">RECORDS</strong> tab shows your maintenance history for the selected vehicle. Below the list is the "Add Maintenance Record" form.
|
||||
</p>
|
||||
|
||||
<GuideScreenshot
|
||||
src="/guide/maintenance-records-desktop.png"
|
||||
alt="Maintenance Records tab showing history and add form"
|
||||
caption="The Maintenance Records tab displays service history and an add form"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Adding a Maintenance Record */}
|
||||
<div id="adding-a-maintenance-record" className="scroll-mt-24">
|
||||
<h3 className="text-xl font-semibold text-avus mb-3 mt-8">Adding a Maintenance Record</h3>
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
The form on the RECORDS tab includes:
|
||||
</p>
|
||||
|
||||
<h4 className="text-lg font-semibold text-avus mb-3 mt-6">Receipt Upload</h4>
|
||||
<div className="bg-primary-500/10 border border-primary-500/30 rounded-lg p-4 my-4">
|
||||
<p className="text-titanio/70 leading-relaxed">
|
||||
<strong className="text-avus">Pro Feature:</strong> Maintenance receipt scanning requires a Pro or Enterprise subscription. See <a href="#maintenance-receipt-scanning" className="text-primary-400 hover:text-primary-300 underline">Maintenance Receipt Scanning (Pro)</a> for full details.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
Click the <strong className="text-avus">ADD RECEIPT</strong> button (dashed outline area) to upload or photograph a maintenance receipt. The OCR system can extract:
|
||||
</p>
|
||||
|
||||
<ul className="list-disc list-inside text-titanio/70 space-y-2 mb-4 ml-4">
|
||||
<li>Category and service type</li>
|
||||
<li>Cost</li>
|
||||
<li>Date</li>
|
||||
<li>Shop name</li>
|
||||
</ul>
|
||||
|
||||
<h4 className="text-lg font-semibold text-avus mb-3 mt-6">Form Fields</h4>
|
||||
<GuideTable
|
||||
headers={['Field', 'Required', 'Description']}
|
||||
rows={[
|
||||
['Category', 'Yes', 'Dropdown with options: Routine Maintenance, Repair, Performance Upgrade. Each category has specific subtypes.'],
|
||||
['Date', 'Yes', 'Pre-filled with today\'s date; click the calendar icon to change'],
|
||||
['Odometer Reading', 'Optional', 'Vehicle mileage at time of service'],
|
||||
['Cost', 'Optional', 'Total cost of the service (in $)'],
|
||||
['Shop Name', 'Optional', 'Name of the service shop'],
|
||||
['Notes', 'Optional', 'Additional details about the service (max 1,000 characters)'],
|
||||
]}
|
||||
/>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
Click <strong className="text-avus">Add Record</strong> to save the maintenance record.
|
||||
</p>
|
||||
|
||||
<h4 className="text-lg font-semibold text-avus mb-3 mt-6">Maintenance Categories</h4>
|
||||
<GuideTable
|
||||
headers={['Category', 'Example Services']}
|
||||
rows={[
|
||||
['Routine Maintenance', 'Oil change, air filter, tire rotation, battery, brakes, coolant flush, transmission fluid, spark plugs, fuel filter, cabin air filter, brake fluid, detailing'],
|
||||
['Repair', 'Engine repair, transmission repair, brake repair, electrical, cooling system, suspension, steering, fuel system, body work, paint, glass'],
|
||||
['Performance Upgrade', 'Engine tuning, suspension upgrade, wheels/tires, brake upgrade, exhaust, intake, lighting, audio'],
|
||||
]}
|
||||
/>
|
||||
|
||||
<GuideScreenshot
|
||||
src="/guide/add-maintenance-mobile.png"
|
||||
alt="Mobile view of Add Maintenance Record form"
|
||||
caption="The Add Maintenance Record form on mobile with category selection"
|
||||
mobile
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Maintenance Schedules */}
|
||||
<div id="maintenance-schedules" className="scroll-mt-24">
|
||||
<h3 className="text-xl font-semibold text-avus mb-3 mt-8">Maintenance Schedules</h3>
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
Click the <strong className="text-avus">SCHEDULES</strong> tab to set up recurring maintenance reminders.
|
||||
</p>
|
||||
|
||||
<GuideScreenshot
|
||||
src="/guide/maintenance-schedules-desktop.png"
|
||||
alt="Maintenance Schedules tab showing schedule creation form and active schedules"
|
||||
caption="The Maintenance Schedules tab for setting up recurring reminders"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Creating a Schedule */}
|
||||
<div id="creating-a-schedule" className="scroll-mt-24">
|
||||
<h3 className="text-xl font-semibold text-avus mb-3 mt-8">Creating a Schedule</h3>
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
The "Create Maintenance Schedule" form includes:
|
||||
</p>
|
||||
|
||||
<GuideTable
|
||||
headers={['Field', 'Required', 'Description']}
|
||||
rows={[
|
||||
['Category', 'Yes', 'Same categories as maintenance records'],
|
||||
['Schedule Type', 'Yes', 'Three options (radio buttons):'],
|
||||
['', '', 'Interval-based -- Every X months or miles (e.g., oil change every 5,000 miles or 6 months)'],
|
||||
['', '', 'Fixed date -- A specific calendar date'],
|
||||
['', '', 'Time since last service -- Based on when service was last performed'],
|
||||
['Interval (Months)', 'Conditional', 'Number of months between services. Optional if miles are specified.'],
|
||||
['Interval (Miles)', 'Conditional', 'Number of miles between services. Optional if months are specified.'],
|
||||
['Reminders', 'Optional', 'Set up to 3 reminders (Reminder 1, Reminder 2, Reminder 3) via dropdowns'],
|
||||
['Email notifications', 'Optional', 'Toggle to receive email reminders when service is due'],
|
||||
]}
|
||||
/>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
Click <strong className="text-avus">Create Schedule</strong> to save.
|
||||
</p>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
Below the form, the "Maintenance Schedules" section lists all active schedules for the selected vehicle, showing when each service is next due.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,69 @@
|
||||
import { GuideScreenshot } from '../components/GuideScreenshot';
|
||||
|
||||
export const MobileExperienceSection = () => {
|
||||
return (
|
||||
<section id="mobile-experience" className="py-8 scroll-mt-24">
|
||||
<h2 className="text-2xl font-bold text-avus mb-4">10. Mobile Experience</h2>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
MotoVaultPro is fully responsive and works on both desktop and mobile devices.
|
||||
</p>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
<strong className="text-avus">Mobile Navigation</strong>
|
||||
</p>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
On mobile, the sidebar is replaced by:
|
||||
</p>
|
||||
|
||||
<ul className="list-disc list-inside text-titanio/70 space-y-2 mb-4 ml-4">
|
||||
<li>
|
||||
A <strong className="text-avus">bottom navigation bar</strong> with icons for: Dashboard, Vehicles, Stations
|
||||
</li>
|
||||
<li>
|
||||
A <strong className="text-avus">floating action button (FAB)</strong> in the center with quick actions:
|
||||
<ul className="list-disc list-inside ml-6 mt-2 space-y-1">
|
||||
<li>Log Fuel</li>
|
||||
<li>Add Vehicle</li>
|
||||
<li>Add Document</li>
|
||||
<li>Add Maintenance</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
A <strong className="text-avus">hamburger menu</strong> (accessed from the header) that slides up from the bottom, providing access to all sections: Dashboard, Vehicles, Log Fuel, Maintenance, Documents, Settings
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<GuideScreenshot
|
||||
src="/guide/mobile-bottom-nav.png"
|
||||
alt="Mobile bottom navigation bar with FAB quick actions"
|
||||
caption="The mobile bottom navigation bar and floating action button"
|
||||
mobile
|
||||
/>
|
||||
|
||||
<GuideScreenshot
|
||||
src="/guide/mobile-hamburger.png"
|
||||
alt="Mobile hamburger drawer menu"
|
||||
caption="The mobile hamburger menu provides access to all sections"
|
||||
mobile
|
||||
/>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
<strong className="text-avus">Mobile Optimizations</strong>
|
||||
</p>
|
||||
|
||||
<ul className="list-disc list-inside text-titanio/70 space-y-2 mb-4 ml-4">
|
||||
<li>Touch-friendly buttons and targets (minimum 44px)</li>
|
||||
<li>Swipe gestures for image viewing</li>
|
||||
<li>Camera integration for VIN scanning and receipt capture</li>
|
||||
<li>Full-screen forms for data entry</li>
|
||||
<li>Responsive card layouts that stack vertically on smaller screens</li>
|
||||
</ul>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
All features available on desktop are also available on mobile -- no functionality is lost on smaller screens.
|
||||
</p>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
148
frontend/src/pages/GuidePage/sections/SettingsSection.tsx
Normal file
@@ -0,0 +1,148 @@
|
||||
import { GuideTable } from '../components/GuideTable';
|
||||
import { GuideScreenshot } from '../components/GuideScreenshot';
|
||||
|
||||
export const SettingsSection = () => {
|
||||
return (
|
||||
<section id="settings" className="py-8 border-b border-white/5 scroll-mt-24">
|
||||
<h2 className="text-2xl font-bold text-avus mb-4">8. Settings</h2>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
Click <strong className="text-avus">Settings</strong> in the sidebar to manage your account, preferences, and data.
|
||||
</p>
|
||||
|
||||
<h3 id="profile" className="text-xl font-semibold text-avus mb-3 mt-8">
|
||||
Profile
|
||||
</h3>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
The Profile section displays your account information:
|
||||
</p>
|
||||
|
||||
<GuideTable
|
||||
headers={['Field', 'Description']}
|
||||
rows={[
|
||||
['Avatar', 'Shows your initial in a circle'],
|
||||
['Name', 'Your display name (e.g., "Eric Gullickson")'],
|
||||
['Email', 'Your account email address'],
|
||||
['Account Status', 'Shows "Verified account" if email is verified'],
|
||||
['Display Name', 'Your public-facing name'],
|
||||
['Notification Email', 'The email address used for notifications (defaults to "Using primary email")'],
|
||||
]}
|
||||
/>
|
||||
|
||||
<GuideScreenshot
|
||||
src="/guide/settings-desktop.png"
|
||||
alt="Settings page showing profile and account options"
|
||||
caption="The Settings page with profile, security, subscription, and preferences"
|
||||
/>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
Click the <strong className="text-avus">Edit</strong> button to update your display name or notification email.
|
||||
</p>
|
||||
|
||||
<h3 id="security-and-privacy" className="text-xl font-semibold text-avus mb-3 mt-8">
|
||||
Security and Privacy
|
||||
</h3>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
The Security & Privacy row shows "Password, two-factor authentication" with a <strong className="text-avus">Manage</strong> button. Click it to:
|
||||
</p>
|
||||
|
||||
<ul className="list-disc list-inside text-titanio/70 space-y-2 mb-4 ml-4">
|
||||
<li>Change your password</li>
|
||||
<li>Set up two-factor authentication</li>
|
||||
<li>Manage active sessions</li>
|
||||
<li>Log out all devices</li>
|
||||
</ul>
|
||||
|
||||
<h3 id="subscription" className="text-xl font-semibold text-avus mb-3 mt-8">
|
||||
Subscription
|
||||
</h3>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
Shows your current subscription plan with a <strong className="text-avus">Manage</strong> button.
|
||||
</p>
|
||||
|
||||
<GuideTable
|
||||
headers={['Plan', 'Features']}
|
||||
rows={[
|
||||
['FREE', 'Basic vehicle management, up to 2 vehicles, basic fuel tracking, document storage'],
|
||||
['Pro', 'Up to 10 vehicles, receipt OCR scanning, maintenance schedules, email ingestion'],
|
||||
['Enterprise', 'Unlimited vehicles, all Pro features'],
|
||||
]}
|
||||
/>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
"Upgrade to Pro or Enterprise for more features and vehicle slots."
|
||||
</p>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
Click <strong className="text-avus">Manage</strong> to view plan details, change your subscription, manage payment methods, and view billing history.
|
||||
</p>
|
||||
|
||||
<h3 id="notifications" className="text-xl font-semibold text-avus mb-3 mt-8">
|
||||
Notifications
|
||||
</h3>
|
||||
|
||||
<GuideTable
|
||||
headers={['Setting', 'Description', 'Default']}
|
||||
rows={[
|
||||
['Push Notifications', 'Receive notifications about your vehicles (maintenance due, etc.)', 'ON'],
|
||||
['Email Updates', 'Receive maintenance reminders and updates via email', 'OFF'],
|
||||
]}
|
||||
/>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
Toggle each setting on or off.
|
||||
</p>
|
||||
|
||||
<h3 id="appearance-and-units" className="text-xl font-semibold text-avus mb-3 mt-8">
|
||||
Appearance and Units
|
||||
</h3>
|
||||
|
||||
<GuideTable
|
||||
headers={['Setting', 'Description', 'Options']}
|
||||
rows={[
|
||||
['Dark Mode', 'Use dark theme for better night viewing', 'Toggle ON/OFF (default: OFF)'],
|
||||
['Units for distance and capacity', 'Choose between measurement systems', 'Imperial: miles, gallons, MPG, USD / Metric: km, liters, L/100km, EUR'],
|
||||
]}
|
||||
/>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
The unit system you select here applies throughout the entire application -- Dashboard, Fuel Logs, Maintenance, and Vehicle Details all update to reflect your preference.
|
||||
</p>
|
||||
|
||||
<h3 id="data-import-and-export" className="text-xl font-semibold text-avus mb-3 mt-8">
|
||||
Data Import and Export
|
||||
</h3>
|
||||
|
||||
<GuideTable
|
||||
headers={['Action', 'Description', 'Button']}
|
||||
rows={[
|
||||
['Import Data', 'Upload and restore your vehicle data from a backup file', 'Import'],
|
||||
['Export Data', 'Download your vehicle and fuel log data as a backup file', 'Export'],
|
||||
]}
|
||||
/>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
Export creates a downloadable archive of all your data. Import accepts a previously exported backup file to restore your data.
|
||||
</p>
|
||||
|
||||
<h3 id="account-actions" className="text-xl font-semibold text-avus mb-3 mt-8">
|
||||
Account Actions
|
||||
</h3>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
At the bottom of the Settings page:
|
||||
</p>
|
||||
|
||||
<GuideTable
|
||||
headers={['Button', 'Action']}
|
||||
rows={[
|
||||
['Sign Out', 'Log out of your account'],
|
||||
['DELETE ACCOUNT', 'Permanently delete your account and all data. This initiates a 30-day grace period during which you can cancel the deletion by logging back in.'],
|
||||
]}
|
||||
/>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
384
frontend/src/pages/GuidePage/sections/SubscriptionSection.tsx
Normal file
@@ -0,0 +1,384 @@
|
||||
import { GuideTable } from '../components/GuideTable';
|
||||
|
||||
export const SubscriptionSection = () => {
|
||||
return (
|
||||
<section id="subscription-tiers" className="py-8 border-b border-white/5 scroll-mt-24">
|
||||
<h2 className="text-2xl font-bold text-avus mb-4">9. Subscription Tiers and Pro Features</h2>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
MotoVaultPro offers three subscription tiers. Higher tiers automatically include all features from lower tiers.
|
||||
</p>
|
||||
|
||||
<h3 id="tier-comparison" className="text-xl font-semibold text-avus mb-3 mt-8">
|
||||
Tier Comparison
|
||||
</h3>
|
||||
|
||||
<GuideTable
|
||||
headers={['Feature', 'Free', 'Pro', 'Enterprise']}
|
||||
rows={[
|
||||
['Vehicle Slots', '2', '5', 'Unlimited'],
|
||||
['Vehicle management', 'Yes', 'Yes', 'Yes'],
|
||||
['Fuel log tracking', 'Yes', 'Yes', 'Yes'],
|
||||
['Document storage', 'Yes', 'Yes', 'Yes'],
|
||||
['Gas station finder', 'Yes', 'Yes', 'Yes'],
|
||||
['Maintenance records', 'Yes', 'Yes', 'Yes'],
|
||||
['Maintenance schedules', 'Yes', 'Yes', 'Yes'],
|
||||
['Data import/export', 'Yes', 'Yes', 'Yes'],
|
||||
['VIN camera scan and decode', '--', 'Yes', 'Yes'],
|
||||
['Fuel receipt OCR scanning', '--', 'Yes', 'Yes'],
|
||||
['Maintenance receipt OCR scanning', '--', 'Yes', 'Yes'],
|
||||
['Maintenance manual PDF extraction', '--', 'Yes', 'Yes'],
|
||||
['Email ingestion (forward receipts)', '--', 'Yes', 'Yes'],
|
||||
['Shared vehicle documents', '--', 'Yes', 'Yes'],
|
||||
['Community station submissions', '--', 'Yes', 'Yes'],
|
||||
]}
|
||||
/>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
When you attempt to use a Pro feature on the Free tier, an <strong className="text-avus">Upgrade Required</strong> dialog appears explaining the feature and offering a direct link to upgrade.
|
||||
</p>
|
||||
|
||||
<h3 id="vin-camera-scanning" className="text-xl font-semibold text-avus mb-3 mt-8">
|
||||
VIN Camera Scanning and Decode (Pro)
|
||||
</h3>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
<strong className="text-avus">What it does:</strong> Use your device camera to photograph your vehicle's VIN plate, and the system automatically reads the VIN using OCR (Optical Character Recognition) and decodes it from the NHTSA database.
|
||||
</p>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
<strong className="text-avus">How to use it:</strong>
|
||||
</p>
|
||||
|
||||
<ol className="list-decimal list-inside text-titanio/70 space-y-2 mb-4 ml-4">
|
||||
<li>Go to <strong className="text-avus">Vehicles</strong> and click <strong className="text-avus">+ Add Vehicle</strong></li>
|
||||
<li>In the VIN Number field, click the <strong className="text-avus">camera icon</strong></li>
|
||||
<li>Point your camera at the VIN plate on your vehicle (typically on the driver-side dashboard or door jamb)</li>
|
||||
<li>The OCR system reads the 17-character VIN from the image</li>
|
||||
<li>A <strong className="text-avus">VIN OCR Review modal</strong> appears showing the detected VIN with confidence indicators</li>
|
||||
<li>Confirm or correct the VIN, then click <strong className="text-avus">Accept</strong></li>
|
||||
<li>Click the <strong className="text-avus">Decode VIN</strong> button</li>
|
||||
<li>The system queries the NHTSA database and auto-populates: Year, Make, Model, Engine, Transmission, and Trim</li>
|
||||
<li>Review the pre-filled fields and complete the remaining details</li>
|
||||
</ol>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
This eliminates manual data entry errors and ensures accurate vehicle specifications.
|
||||
</p>
|
||||
|
||||
<h3 id="fuel-receipt-scanning" className="text-xl font-semibold text-avus mb-3 mt-8">
|
||||
Fuel Receipt Scanning (Pro)
|
||||
</h3>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
<strong className="text-avus">What it does:</strong> Photograph a fuel receipt and the OCR system extracts all relevant data, automatically filling in your fuel log entry.
|
||||
</p>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
<strong className="text-avus">How to use it:</strong>
|
||||
</p>
|
||||
|
||||
<ol className="list-decimal list-inside text-titanio/70 space-y-2 mb-4 ml-4">
|
||||
<li>Open the <strong className="text-avus">Log Fuel</strong> modal (from Dashboard or Fuel Logs page)</li>
|
||||
<li>Click the <strong className="text-avus">SCAN RECEIPT</strong> button at the top of the form</li>
|
||||
<li>Use your camera to photograph the fuel receipt</li>
|
||||
<li>The system processes the image and extracts relevant data</li>
|
||||
</ol>
|
||||
|
||||
<GuideTable
|
||||
headers={['Extracted Field', 'Description']}
|
||||
rows={[
|
||||
['Fuel Amount', 'Gallons or liters purchased'],
|
||||
['Cost Per Unit', 'Price per gallon/liter'],
|
||||
['Total Cost', 'Total transaction amount'],
|
||||
['Date & Time', 'Transaction timestamp'],
|
||||
['Fuel Grade', 'Regular, Midgrade, Premium, etc.'],
|
||||
['Station Name', 'Merchant name matched to known stations'],
|
||||
]}
|
||||
/>
|
||||
|
||||
<ol start={5} className="list-decimal list-inside text-titanio/70 space-y-2 mb-4 ml-4">
|
||||
<li>A <strong className="text-avus">Receipt OCR Review modal</strong> appears showing all extracted values with confidence scores</li>
|
||||
<li>Each field can be edited inline if the OCR got something wrong</li>
|
||||
<li>The station name is automatically matched against known gas stations in the system</li>
|
||||
<li>Click <strong className="text-avus">Accept</strong> to auto-fill the Log Fuel form with the extracted values</li>
|
||||
<li>Click <strong className="text-avus">Reject</strong> to discard the scan and enter data manually</li>
|
||||
<li>Review the pre-filled form and click <strong className="text-avus">Add Fuel Log</strong></li>
|
||||
</ol>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
<strong className="text-avus">Tips for best results:</strong>
|
||||
</p>
|
||||
|
||||
<ul className="list-disc list-inside text-titanio/70 space-y-2 mb-4 ml-4">
|
||||
<li>Photograph the receipt on a flat, well-lit surface</li>
|
||||
<li>Ensure the entire receipt is visible in the frame</li>
|
||||
<li>Avoid wrinkled or faded receipts when possible</li>
|
||||
</ul>
|
||||
|
||||
<h3 id="maintenance-receipt-scanning" className="text-xl font-semibold text-avus mb-3 mt-8">
|
||||
Maintenance Receipt Scanning (Pro)
|
||||
</h3>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
<strong className="text-avus">What it does:</strong> Photograph a maintenance or service receipt to automatically extract service details into a maintenance record.
|
||||
</p>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
<strong className="text-avus">How to use it:</strong>
|
||||
</p>
|
||||
|
||||
<ol className="list-decimal list-inside text-titanio/70 space-y-2 mb-4 ml-4">
|
||||
<li>Go to <strong className="text-avus">Maintenance</strong> and select a vehicle</li>
|
||||
<li>On the <strong className="text-avus">RECORDS</strong> tab, click the <strong className="text-avus">ADD RECEIPT</strong> button (dashed outline area)</li>
|
||||
<li>Use your camera to photograph the service receipt</li>
|
||||
<li>The system processes the image and extracts relevant data</li>
|
||||
</ol>
|
||||
|
||||
<GuideTable
|
||||
headers={['Extracted Field', 'Description']}
|
||||
rows={[
|
||||
['Category', 'Service type (Routine, Repair, Performance)'],
|
||||
['Subtypes', 'Specific services performed (e.g., Oil Change, Tire Rotation)'],
|
||||
['Cost', 'Total service cost'],
|
||||
['Date', 'Service date'],
|
||||
['Shop Name', 'Name of the service shop'],
|
||||
]}
|
||||
/>
|
||||
|
||||
<ol start={5} className="list-decimal list-inside text-titanio/70 space-y-2 mb-4 ml-4">
|
||||
<li>A <strong className="text-avus">Maintenance Receipt Review modal</strong> shows extracted values with confidence indicators</li>
|
||||
<li>Edit any incorrect values inline</li>
|
||||
<li>Click <strong className="text-avus">Accept</strong> to auto-fill the maintenance record form</li>
|
||||
<li>Review and click <strong className="text-avus">Add Record</strong></li>
|
||||
</ol>
|
||||
|
||||
<h3 id="maintenance-manual-pdf" className="text-xl font-semibold text-avus mb-3 mt-8">
|
||||
Maintenance Manual PDF Extraction (Pro)
|
||||
</h3>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
<strong className="text-avus">What it does:</strong> Upload your vehicle's owner's manual or maintenance manual as a PDF, and the system automatically extracts the recommended maintenance schedule -- creating maintenance schedules with the correct intervals for your specific vehicle.
|
||||
</p>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
<strong className="text-avus">How to use it:</strong>
|
||||
</p>
|
||||
|
||||
<ol className="list-decimal list-inside text-titanio/70 space-y-2 mb-4 ml-4">
|
||||
<li>Go to <strong className="text-avus">Documents</strong> and click <strong className="text-avus">Add Document</strong></li>
|
||||
<li>Select your vehicle and choose <strong className="text-avus">Maintenance Manual</strong> as the document type</li>
|
||||
<li>Upload the PDF file</li>
|
||||
<li>Check the <strong className="text-avus">Scan for Maintenance Schedule</strong> checkbox (Pro feature -- indicated by a lock icon for Free tier users)</li>
|
||||
<li>Click <strong className="text-avus">Create Document</strong></li>
|
||||
<li>The system submits the PDF for asynchronous processing</li>
|
||||
<li>A progress indicator shows while the document is being analyzed</li>
|
||||
<li>When processing completes, the <strong className="text-avus">Maintenance Schedule Review</strong> screen appears</li>
|
||||
</ol>
|
||||
|
||||
<GuideTable
|
||||
headers={['Column', 'Description']}
|
||||
rows={[
|
||||
['Checkbox', 'Select which items to create as schedules'],
|
||||
['Service Name', 'Extracted maintenance service (e.g., "Engine Oil and Filter Change")'],
|
||||
['Interval', 'Recommended interval in months and/or miles'],
|
||||
['Details', 'Additional notes or specifications'],
|
||||
['Confidence', 'How confident the system is in the extraction (High/Medium/Low)'],
|
||||
]}
|
||||
/>
|
||||
|
||||
<ol start={9} className="list-decimal list-inside text-titanio/70 space-y-2 mb-4 ml-4">
|
||||
<li>Check the boxes next to the maintenance items you want to create</li>
|
||||
<li>Edit any service names, intervals, or details inline</li>
|
||||
<li>Click <strong className="text-avus">Create Selected Schedules</strong> to batch-create all selected items as maintenance schedules for your vehicle</li>
|
||||
</ol>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
This turns a 50-page owner's manual into a complete set of maintenance reminders in minutes.
|
||||
</p>
|
||||
|
||||
<h3 id="email-ingestion" className="text-xl font-semibold text-avus mb-3 mt-8">
|
||||
Email Ingestion (Pro)
|
||||
</h3>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
<strong className="text-avus">What it does:</strong> Forward vehicle-related emails (service receipts, insurance documents, registration notices) to a dedicated email address, and they automatically appear in your MotoVaultPro account ready to be associated with a vehicle.
|
||||
</p>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
<strong className="text-avus">How to use it:</strong>
|
||||
</p>
|
||||
|
||||
<ol className="list-decimal list-inside text-titanio/70 space-y-2 mb-4 ml-4">
|
||||
<li>Forward any vehicle-related email to your dedicated MotoVaultPro ingestion address</li>
|
||||
<li>The system processes the email and any attachments</li>
|
||||
<li>On your <strong className="text-avus">Dashboard</strong>, a <strong className="text-avus">Pending Associations</strong> banner appears showing how many items are waiting</li>
|
||||
<li>Click the banner to open the <strong className="text-avus">Pending Association List</strong></li>
|
||||
<li>For each pending item, you see a preview of the document or receipt and a vehicle selector dropdown</li>
|
||||
<li>Select the correct vehicle for each item and click <strong className="text-avus">Associate</strong></li>
|
||||
<li>Or click <strong className="text-avus">Discard</strong> to remove items you do not want</li>
|
||||
</ol>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
<strong className="text-avus">Bulk actions</strong> are available to discard all pending items at once.
|
||||
</p>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
This is especially useful for:
|
||||
</p>
|
||||
|
||||
<ul className="list-disc list-inside text-titanio/70 space-y-2 mb-4 ml-4">
|
||||
<li>Forwarding digital receipts from auto parts stores</li>
|
||||
<li>Forwarding service confirmation emails from your mechanic</li>
|
||||
<li>Forwarding insurance policy documents from your provider</li>
|
||||
<li>Forwarding registration renewal notices</li>
|
||||
</ul>
|
||||
|
||||
<h3 id="shared-vehicle-documents" className="text-xl font-semibold text-avus mb-3 mt-8">
|
||||
Shared Vehicle Documents (Pro)
|
||||
</h3>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
<strong className="text-avus">What it does:</strong> Associate a single document with multiple vehicles. Useful for fleet insurance policies, multi-vehicle service agreements, or shared maintenance contracts.
|
||||
</p>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
<strong className="text-avus">How to use it:</strong>
|
||||
</p>
|
||||
|
||||
<ol className="list-decimal list-inside text-titanio/70 space-y-2 mb-4 ml-4">
|
||||
<li>Open an existing document's detail page</li>
|
||||
<li>In the <strong className="text-avus">Shared Vehicles</strong> section, click <strong className="text-avus">Add Vehicle</strong></li>
|
||||
<li>Select additional vehicles from the dropdown</li>
|
||||
<li>The document now appears in the Documents section for each associated vehicle</li>
|
||||
<li>To remove a vehicle association, click the <strong className="text-avus">Remove</strong> button next to that vehicle</li>
|
||||
</ol>
|
||||
|
||||
<h3 id="community-station-submissions" className="text-xl font-semibold text-avus mb-3 mt-8">
|
||||
Community Station Submissions (Pro)
|
||||
</h3>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
<strong className="text-avus">What it does:</strong> Submit new gas stations to the MotoVaultPro community database, helping other enthusiasts find quality fuel locations -- especially stations carrying true 93-octane premium fuel.
|
||||
</p>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
<strong className="text-avus">How to use it:</strong>
|
||||
</p>
|
||||
|
||||
<ol className="list-decimal list-inside text-titanio/70 space-y-2 mb-4 ml-4">
|
||||
<li>Go to <strong className="text-avus">Gas Stations</strong></li>
|
||||
<li>Look for the option to submit a new community station</li>
|
||||
<li>Fill in the submission form</li>
|
||||
</ol>
|
||||
|
||||
<GuideTable
|
||||
headers={['Field', 'Description']}
|
||||
rows={[
|
||||
['Station Name', 'Name of the gas station'],
|
||||
['Location', 'Address or location'],
|
||||
['Fuel Types', 'Available fuel types and grades'],
|
||||
['Amenities', 'Available amenities (bathrooms, ATM, convenience store, etc.)'],
|
||||
['Notes', 'Any additional information'],
|
||||
['Photo', 'Optional photo of the station'],
|
||||
]}
|
||||
/>
|
||||
|
||||
<ol start={4} className="list-decimal list-inside text-titanio/70 space-y-2 mb-4 ml-4">
|
||||
<li>Submit for community review</li>
|
||||
<li>An admin reviews and approves or rejects the submission</li>
|
||||
<li>Approved stations appear in the <strong className="text-avus">PREMIUM 93</strong> tab and search results with a community-verified badge</li>
|
||||
</ol>
|
||||
|
||||
<h3 id="managing-your-subscription" className="text-xl font-semibold text-avus mb-3 mt-8">
|
||||
Managing Your Subscription
|
||||
</h3>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
<strong className="text-avus">Viewing Your Plan</strong>
|
||||
</p>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
Go to <strong className="text-avus">Settings</strong> and find the <strong className="text-avus">Subscription</strong> section. It shows your current plan (FREE, Pro, or Enterprise) with a <strong className="text-avus">Manage</strong> button.
|
||||
</p>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
<strong className="text-avus">Upgrading</strong>
|
||||
</p>
|
||||
|
||||
<ol className="list-decimal list-inside text-titanio/70 space-y-2 mb-4 ml-4">
|
||||
<li>Click <strong className="text-avus">Manage</strong> in the Subscription section</li>
|
||||
<li>The Subscription page shows tier comparison cards with pricing</li>
|
||||
<li>Toggle between <strong className="text-avus">Monthly</strong> and <strong className="text-avus">Annual</strong> billing (annual saves money)</li>
|
||||
<li>Click <strong className="text-avus">Upgrade</strong> on the plan you want</li>
|
||||
<li>Enter your payment details using the secure Stripe payment form</li>
|
||||
<li>Your new features are available immediately</li>
|
||||
</ol>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
<strong className="text-avus">Payment Methods</strong>
|
||||
</p>
|
||||
|
||||
<ul className="list-disc list-inside text-titanio/70 space-y-2 mb-4 ml-4">
|
||||
<li>Payment is processed through Stripe (credit/debit cards)</li>
|
||||
<li>You can save a card for recurring billing</li>
|
||||
<li>Update or remove your payment method at any time</li>
|
||||
<li>View billing history and download invoices as PDFs</li>
|
||||
</ul>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
<strong className="text-avus">Billing History</strong>
|
||||
</p>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
The billing history table shows all past invoices with:
|
||||
</p>
|
||||
|
||||
<ul className="list-disc list-inside text-titanio/70 space-y-2 mb-4 ml-4">
|
||||
<li>Date</li>
|
||||
<li>Description</li>
|
||||
<li>Amount</li>
|
||||
<li>Status (Paid, Pending, Failed)</li>
|
||||
<li>Download PDF button for each invoice</li>
|
||||
</ul>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
<strong className="text-avus">Downgrading</strong>
|
||||
</p>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
If you downgrade from a higher tier, you may need to reduce your vehicles to fit within the lower tier's limit:
|
||||
</p>
|
||||
|
||||
<ol className="list-decimal list-inside text-titanio/70 space-y-2 mb-4 ml-4">
|
||||
<li>Click <strong className="text-avus">Downgrade</strong> on the lower plan</li>
|
||||
<li>A <strong className="text-avus">Vehicle Selection dialog</strong> appears if you exceed the new tier's vehicle limit</li>
|
||||
<li>Select which vehicles to keep (e.g., keep 2 for Free tier)</li>
|
||||
<li>A warning explains that removed vehicles and their data will be deleted</li>
|
||||
<li>Confirm the downgrade</li>
|
||||
</ol>
|
||||
|
||||
<GuideTable
|
||||
headers={['Tier', 'Vehicle Limit']}
|
||||
rows={[
|
||||
['Free', '2'],
|
||||
['Pro', '5'],
|
||||
['Enterprise', 'Unlimited'],
|
||||
]}
|
||||
/>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
<strong className="text-avus">Cancelling</strong>
|
||||
</p>
|
||||
|
||||
<ol className="list-decimal list-inside text-titanio/70 space-y-2 mb-4 ml-4">
|
||||
<li>On the Subscription page, click <strong className="text-avus">Cancel Subscription</strong></li>
|
||||
<li>A confirmation dialog appears with retention options</li>
|
||||
<li>Confirm cancellation</li>
|
||||
<li>Your subscription remains active until the end of the current billing period</li>
|
||||
<li>After expiration, your account reverts to the Free tier</li>
|
||||
<li>Click <strong className="text-avus">Reactivate</strong> at any time before expiration to keep your plan</li>
|
||||
</ol>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
221
frontend/src/pages/GuidePage/sections/VehiclesSection.tsx
Normal file
@@ -0,0 +1,221 @@
|
||||
import { GuideTable } from '../components/GuideTable';
|
||||
import { GuideScreenshot } from '../components/GuideScreenshot';
|
||||
|
||||
export const VehiclesSection = () => {
|
||||
return (
|
||||
<section id="vehicles" className="py-8 border-b border-white/5 scroll-mt-24">
|
||||
<h2 className="text-2xl font-bold text-avus mb-4">3. Vehicles</h2>
|
||||
|
||||
{/* Viewing Your Vehicles */}
|
||||
<div id="viewing-your-vehicles" className="scroll-mt-24">
|
||||
<h3 className="text-xl font-semibold text-avus mb-3 mt-8">Viewing Your Vehicles</h3>
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
Click <strong className="text-avus">Vehicles</strong> in the sidebar to see the "My Vehicles" page. This page shows:
|
||||
</p>
|
||||
|
||||
<ul className="list-disc list-inside text-titanio/70 space-y-2 mb-4 ml-4">
|
||||
<li>
|
||||
<strong className="text-avus">Search bar</strong> -- Search vehicles by name, make, model, or VIN
|
||||
</li>
|
||||
<li>
|
||||
<strong className="text-avus">+ Add Vehicle</strong> button -- Top-right corner
|
||||
</li>
|
||||
<li>
|
||||
<strong className="text-avus">Vehicle cards</strong> in a grid layout (3 columns on desktop), each displaying:
|
||||
<ul className="list-disc list-inside ml-6 mt-2 space-y-1">
|
||||
<li>Manufacturer logo (e.g., Chevrolet bowtie, GMC logo)</li>
|
||||
<li>Vehicle nickname or full name</li>
|
||||
<li>Year, Make, and Model</li>
|
||||
<li>License plate number</li>
|
||||
<li>Current odometer reading (in miles or kilometers)</li>
|
||||
<li><strong className="text-avus">Edit</strong> (pencil icon) and <strong className="text-avus">Delete</strong> (trash icon) buttons at the bottom of each card</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<GuideScreenshot
|
||||
src="/guide/vehicles-list-desktop.png"
|
||||
alt="Vehicles page showing grid of vehicle cards with details"
|
||||
caption="The Vehicles page displays all your vehicles in a searchable grid"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Adding a Vehicle */}
|
||||
<div id="adding-a-vehicle" className="scroll-mt-24">
|
||||
<h3 className="text-xl font-semibold text-avus mb-3 mt-8">Adding a Vehicle</h3>
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
Click the <strong className="text-avus">+ Add Vehicle</strong> button to expand the "Add New Vehicle" form directly on the Vehicles page. The form has the following sections:
|
||||
</p>
|
||||
|
||||
<h4 className="text-lg font-semibold text-avus mb-3 mt-6">Vehicle Photo</h4>
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
Upload a photo of your vehicle. Click <strong className="text-avus">ADD PHOTO</strong> to select an image file.
|
||||
</p>
|
||||
<ul className="list-disc list-inside text-titanio/70 space-y-2 mb-4 ml-4">
|
||||
<li>Accepted formats: JPEG or PNG</li>
|
||||
<li>Maximum file size: 5MB</li>
|
||||
</ul>
|
||||
|
||||
<h4 className="text-lg font-semibold text-avus mb-3 mt-6">VIN Number</h4>
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
Enter your vehicle's 17-character VIN (Vehicle Identification Number).
|
||||
</p>
|
||||
<ul className="list-disc list-inside text-titanio/70 space-y-2 mb-4 ml-4">
|
||||
<li>Type the VIN manually in the text field, OR</li>
|
||||
<li>Click the <strong className="text-avus">camera icon</strong> to scan the VIN using your device camera (uses OCR technology)</li>
|
||||
<li>Click the <strong className="text-avus">Decode VIN</strong> button to automatically populate vehicle details from the VIN</li>
|
||||
</ul>
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
Note: VIN is optional if you provide a License Plate instead.
|
||||
</p>
|
||||
|
||||
<h4 className="text-lg font-semibold text-avus mb-3 mt-6">Vehicle Specifications</h4>
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
These fields use cascading dropdowns -- each selection narrows the options for the next field:
|
||||
</p>
|
||||
|
||||
<GuideTable
|
||||
headers={['Field', 'How It Works']}
|
||||
rows={[
|
||||
['Year', 'Select the model year from the dropdown'],
|
||||
['Make', 'Available after selecting Year (e.g., Chevrolet, GMC, Ford)'],
|
||||
['Model', 'Available after selecting Make (e.g., Silverado, Camaro, Sierra)'],
|
||||
['Trim', 'Available after selecting Model (e.g., LT Double Cab 4WD)'],
|
||||
['Engine', 'Available after selecting Trim (e.g., 6.6L 401 HP V8)'],
|
||||
['Transmission', 'Available after selecting Trim (e.g., 10-Speed Automatic)'],
|
||||
]}
|
||||
/>
|
||||
|
||||
<GuideScreenshot
|
||||
src="/guide/add-vehicle-form-desktop.png"
|
||||
alt="Add Vehicle form showing cascading dropdowns for specifications"
|
||||
caption="The Add Vehicle form with cascading dropdowns for easy data entry"
|
||||
/>
|
||||
|
||||
<h4 className="text-lg font-semibold text-avus mb-3 mt-6">Additional Details</h4>
|
||||
<GuideTable
|
||||
headers={['Field', 'Example', 'Notes']}
|
||||
rows={[
|
||||
['Nickname', 'Beast, Family Car', 'A friendly name for your vehicle'],
|
||||
['Color', 'Black, Blue, Red', 'Vehicle color'],
|
||||
['License Plate', 'ABC-123', 'Required if VIN is not provided'],
|
||||
['Current Odometer Reading', '50000', 'Current mileage in your selected unit'],
|
||||
]}
|
||||
/>
|
||||
|
||||
<h4 className="text-lg font-semibold text-avus mb-3 mt-6">Purchase Information</h4>
|
||||
<GuideTable
|
||||
headers={['Field', 'Example', 'Notes']}
|
||||
rows={[
|
||||
['Purchase Price', '25000', 'What you paid for the vehicle'],
|
||||
['Purchase Date', 'mm/dd/yyyy', 'When you purchased the vehicle'],
|
||||
]}
|
||||
/>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
Click <strong className="text-avus">Add Vehicle</strong> to save, or <strong className="text-avus">Cancel</strong> to discard.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* VIN Decode */}
|
||||
<div id="vin-decode" className="scroll-mt-24">
|
||||
<h3 className="text-xl font-semibold text-avus mb-3 mt-8">VIN Decode</h3>
|
||||
<div className="bg-primary-500/10 border border-primary-500/30 rounded-lg p-4 my-4">
|
||||
<p className="text-titanio/70 leading-relaxed">
|
||||
<strong className="text-avus">Pro Feature:</strong> VIN camera scanning and automatic decode require a Pro or Enterprise subscription. Free tier users can still type a VIN manually. See <a href="#vin-camera-scanning" className="text-primary-400 hover:text-primary-300 underline">VIN Camera Scanning and Decode (Pro)</a> for full details.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
The VIN Decode feature automatically fills in vehicle details from a VIN:
|
||||
</p>
|
||||
|
||||
<ol className="list-decimal list-inside text-titanio/70 space-y-2 mb-4 ml-4">
|
||||
<li>Enter or scan your 17-character VIN</li>
|
||||
<li>Click the <strong className="text-avus">Decode VIN</strong> button</li>
|
||||
<li>The system looks up the VIN and auto-populates: Year, Make, Model, Engine, Transmission, and Trim</li>
|
||||
<li>Review the pre-filled fields and make any corrections</li>
|
||||
<li>Continue filling in the remaining fields (Nickname, Color, etc.)</li>
|
||||
</ol>
|
||||
|
||||
<GuideScreenshot
|
||||
src="/guide/vin-decode-desktop.png"
|
||||
alt="VIN Decode feature showing auto-populated vehicle specifications"
|
||||
caption="The VIN Decode feature automatically fills in vehicle details from the NHTSA database"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Vehicle Detail Page */}
|
||||
<div id="vehicle-detail-page" className="scroll-mt-24">
|
||||
<h3 className="text-xl font-semibold text-avus mb-3 mt-8">Vehicle Detail Page</h3>
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
Click any vehicle card (from Dashboard or Vehicles list) to open the Vehicle Detail Page. This page shows everything about a single vehicle:
|
||||
</p>
|
||||
|
||||
<h4 className="text-lg font-semibold text-avus mb-3 mt-6">Header Area</h4>
|
||||
<ul className="list-disc list-inside text-titanio/70 space-y-2 mb-4 ml-4">
|
||||
<li>Back arrow and <strong className="text-avus">BACK</strong> link to return to the previous page</li>
|
||||
<li>Vehicle nickname as the page title (e.g., "Beast")</li>
|
||||
<li><strong className="text-avus">Edit Vehicle</strong> button (top-right)</li>
|
||||
<li>Quick action buttons: <strong className="text-avus">Add Fuel Log</strong> and <strong className="text-avus">Add Maintenance</strong></li>
|
||||
</ul>
|
||||
|
||||
<h4 className="text-lg font-semibold text-avus mb-3 mt-6">Vehicle Details Section</h4>
|
||||
<ul className="list-disc list-inside text-titanio/70 space-y-2 mb-4 ml-4">
|
||||
<li>Manufacturer logo</li>
|
||||
<li>Full vehicle description (e.g., "2022 Chevrolet Silverado 2500HD")</li>
|
||||
<li>VIN Number</li>
|
||||
<li>Year, Make, and Model (displayed in a 3-column row)</li>
|
||||
<li>Trim, Engine, and Transmission (displayed in a 3-column row)</li>
|
||||
<li>Nickname</li>
|
||||
<li>Color and License Plate (side by side)</li>
|
||||
<li>Current Odometer Reading</li>
|
||||
</ul>
|
||||
|
||||
<GuideScreenshot
|
||||
src="/guide/vehicle-detail-desktop.png"
|
||||
alt="Vehicle Detail page showing complete vehicle information and records"
|
||||
caption="The Vehicle Detail page displays all information and records for a single vehicle"
|
||||
/>
|
||||
|
||||
<h4 className="text-lg font-semibold text-avus mb-3 mt-6">Purchase Information Section</h4>
|
||||
<ul className="list-disc list-inside text-titanio/70 space-y-2 mb-4 ml-4">
|
||||
<li>Purchase Price</li>
|
||||
<li>Purchase Date</li>
|
||||
</ul>
|
||||
|
||||
<h4 className="text-lg font-semibold text-avus mb-3 mt-6">Ownership Costs Section</h4>
|
||||
<ul className="list-disc list-inside text-titanio/70 space-y-2 mb-4 ml-4">
|
||||
<li>Tracks insurance, registration, taxes, and other recurring vehicle costs</li>
|
||||
<li>Shows "No ownership costs recorded yet" until costs are added</li>
|
||||
</ul>
|
||||
|
||||
<h4 className="text-lg font-semibold text-avus mb-3 mt-6">Vehicle Records Section</h4>
|
||||
<ul className="list-disc list-inside text-titanio/70 space-y-2 mb-4 ml-4">
|
||||
<li>A table showing all records associated with this vehicle (fuel logs, maintenance records)</li>
|
||||
<li>Columns: Date, Type, Summary, Amount, Actions</li>
|
||||
<li><strong className="text-avus">Filter</strong> dropdown to filter by record type (All, Fuel, Maintenance)</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{/* Editing a Vehicle */}
|
||||
<div id="editing-a-vehicle" className="scroll-mt-24">
|
||||
<h3 className="text-xl font-semibold text-avus mb-3 mt-8">Editing a Vehicle</h3>
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
From the Vehicle Detail Page, click the <strong className="text-avus">Edit Vehicle</strong> button. This opens the vehicle form pre-filled with the current values. Make your changes and save.
|
||||
</p>
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
From the Vehicles list, click the <strong className="text-avus">pencil icon</strong> on any vehicle card to edit it directly.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Deleting a Vehicle */}
|
||||
<div id="deleting-a-vehicle" className="scroll-mt-24">
|
||||
<h3 className="text-xl font-semibold text-avus mb-3 mt-8">Deleting a Vehicle</h3>
|
||||
<p className="text-titanio/70 leading-relaxed mb-4">
|
||||
From the Vehicles list, click the <strong className="text-avus">trash icon</strong> on any vehicle card. You will be asked to confirm the deletion. Deleting a vehicle is permanent and removes all associated records.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
12
frontend/src/pages/GuidePage/sections/index.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { lazy } from 'react';
|
||||
|
||||
export const GettingStartedSection = lazy(() => import('./GettingStartedSection').then(m => ({ default: m.GettingStartedSection })));
|
||||
export const DashboardSection = lazy(() => import('./DashboardSection').then(m => ({ default: m.DashboardSection })));
|
||||
export const VehiclesSection = lazy(() => import('./VehiclesSection').then(m => ({ default: m.VehiclesSection })));
|
||||
export const FuelLogsSection = lazy(() => import('./FuelLogsSection').then(m => ({ default: m.FuelLogsSection })));
|
||||
export const MaintenanceSection = lazy(() => import('./MaintenanceSection').then(m => ({ default: m.MaintenanceSection })));
|
||||
export const GasStationsSection = lazy(() => import('./GasStationsSection').then(m => ({ default: m.GasStationsSection })));
|
||||
export const DocumentsSection = lazy(() => import('./DocumentsSection').then(m => ({ default: m.DocumentsSection })));
|
||||
export const SettingsSection = lazy(() => import('./SettingsSection').then(m => ({ default: m.SettingsSection })));
|
||||
export const SubscriptionSection = lazy(() => import('./SubscriptionSection').then(m => ({ default: m.SubscriptionSection })));
|
||||
export const MobileExperienceSection = lazy(() => import('./MobileExperienceSection').then(m => ({ default: m.MobileExperienceSection })));
|
||||
@@ -6,10 +6,9 @@ import { FeaturesGrid } from './HomePage/FeaturesGrid';
|
||||
import { motion } from 'framer-motion';
|
||||
|
||||
export const HomePage = () => {
|
||||
const { loginWithRedirect, isAuthenticated, logout } = useAuth0();
|
||||
const { loginWithRedirect, isAuthenticated } = useAuth0();
|
||||
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
|
||||
const [isScrolled, setIsScrolled] = useState(false);
|
||||
const [sessionCleared, setSessionCleared] = useState(false);
|
||||
const navigate = useNavigate();
|
||||
|
||||
useEffect(() => {
|
||||
@@ -42,22 +41,6 @@ export const HomePage = () => {
|
||||
navigate('/signup');
|
||||
};
|
||||
|
||||
const handleClearSession = async () => {
|
||||
try {
|
||||
const { indexedDBStorage } = await import('../core/utils/indexeddb-storage');
|
||||
await indexedDBStorage.clearAll();
|
||||
Object.keys(localStorage).forEach(key => {
|
||||
if (key.startsWith('@@auth0')) localStorage.removeItem(key);
|
||||
});
|
||||
logout({ openUrl: false });
|
||||
setSessionCleared(true);
|
||||
setTimeout(() => setSessionCleared(false), 3000);
|
||||
} catch (error) {
|
||||
console.error('[HomePage] Failed to clear session:', error);
|
||||
window.location.reload();
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-nero text-avus">
|
||||
{/* Navigation Bar */}
|
||||
@@ -89,6 +72,12 @@ export const HomePage = () => {
|
||||
<a href="#about" className="text-white/75 hover:text-white transition-colors">
|
||||
About
|
||||
</a>
|
||||
<a
|
||||
href="/guide"
|
||||
className="text-white/75 hover:text-white transition-colors"
|
||||
>
|
||||
Guide
|
||||
</a>
|
||||
<button
|
||||
onClick={handleSignup}
|
||||
className="border border-primary-500/90 text-primary-500 hover:bg-primary-500/10 hover:border-primary-500 font-semibold py-2 px-6 rounded-lg transition-colors duration-300 focus:outline-none focus:ring-2 focus:ring-primary-500/50"
|
||||
@@ -101,12 +90,6 @@ export const HomePage = () => {
|
||||
>
|
||||
Login
|
||||
</button>
|
||||
<button
|
||||
onClick={handleClearSession}
|
||||
className="text-white/40 hover:text-white/70 text-xs transition-colors min-h-[44px] min-w-[44px] flex items-center"
|
||||
>
|
||||
{sessionCleared ? 'Session cleared' : 'Trouble logging in?'}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Mobile Menu Button */}
|
||||
@@ -160,6 +143,12 @@ export const HomePage = () => {
|
||||
>
|
||||
About
|
||||
</a>
|
||||
<a
|
||||
href="/guide"
|
||||
className="block text-white/75 hover:text-white transition-colors py-2"
|
||||
>
|
||||
Guide
|
||||
</a>
|
||||
<button
|
||||
onClick={handleSignup}
|
||||
className="w-full border border-primary-500/90 text-primary-500 hover:bg-primary-500/10 font-semibold py-2 px-6 rounded-lg transition-colors duration-300 focus:outline-none focus:ring-2 focus:ring-primary-500/50"
|
||||
@@ -172,12 +161,6 @@ export const HomePage = () => {
|
||||
>
|
||||
Login
|
||||
</button>
|
||||
<button
|
||||
onClick={handleClearSession}
|
||||
className="w-full text-white/40 hover:text-white/70 text-xs py-2 min-h-[44px] transition-colors"
|
||||
>
|
||||
{sessionCleared ? 'Session cleared' : 'Trouble logging in?'}
|
||||
</button>
|
||||
</motion.div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -5,31 +5,34 @@ interface FeatureCardProps {
|
||||
description: string;
|
||||
imageSrc: string;
|
||||
imageAlt: string;
|
||||
href: string;
|
||||
}
|
||||
|
||||
export const FeatureCard = ({ title, description, imageSrc, imageAlt }: FeatureCardProps) => {
|
||||
export const FeatureCard = ({ title, description, imageSrc, imageAlt, href }: FeatureCardProps) => {
|
||||
return (
|
||||
<motion.div
|
||||
className="group cursor-pointer"
|
||||
className="group"
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true, margin: '-50px' }}
|
||||
transition={{ duration: 0.5 }}
|
||||
whileHover={{ y: -5 }}
|
||||
>
|
||||
<div className="overflow-hidden rounded-lg bg-white/5 border border-white/10 shadow-lg shadow-black/30 hover:border-white/20 hover:shadow-xl hover:shadow-black/40 transition-all duration-300">
|
||||
<div className="relative h-56 overflow-hidden">
|
||||
<img
|
||||
src={imageSrc}
|
||||
alt={imageAlt}
|
||||
className="w-full h-full object-cover group-hover:scale-110 transition-transform duration-500"
|
||||
/>
|
||||
<a href={href} className="block">
|
||||
<div className="overflow-hidden rounded-lg bg-white/5 border border-white/10 shadow-lg shadow-black/30 hover:border-white/20 hover:shadow-xl hover:shadow-black/40 transition-all duration-300">
|
||||
<div className="relative h-56 overflow-hidden">
|
||||
<img
|
||||
src={imageSrc}
|
||||
alt={imageAlt}
|
||||
className="w-full h-full object-cover group-hover:scale-110 transition-transform duration-500"
|
||||
/>
|
||||
</div>
|
||||
<div className="p-6">
|
||||
<h3 className="text-xl font-bold text-avus mb-2">{title}</h3>
|
||||
<p className="text-titanio leading-relaxed">{description}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="p-6">
|
||||
<h3 className="text-xl font-bold text-avus mb-2">{title}</h3>
|
||||
<p className="text-titanio leading-relaxed">{description}</p>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</motion.div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -26,6 +26,7 @@ type Feature = {
|
||||
title: string;
|
||||
description: string;
|
||||
image: UnsplashImageSpec;
|
||||
href: string;
|
||||
};
|
||||
|
||||
// Centralize Unsplash identifiers so you only update them in one place if needed.
|
||||
@@ -69,6 +70,7 @@ const features: readonly Feature[] = [
|
||||
{
|
||||
title: 'Vehicle Management',
|
||||
description: 'Track all your vehicles in one centralized location with detailed information and history.',
|
||||
href: '/guide#vehicles',
|
||||
image: {
|
||||
photoId: '1503376780353-7e6692767b70',
|
||||
alt: 'Vehicle Management',
|
||||
@@ -77,6 +79,7 @@ const features: readonly Feature[] = [
|
||||
{
|
||||
title: 'Fuel Log Tracking',
|
||||
description: 'Monitor fuel consumption, costs, and efficiency across all your vehicles.',
|
||||
href: '/guide#fuel-logs',
|
||||
image: {
|
||||
photoId: '1529369623266-f5264b696110',
|
||||
alt: 'Fuel Log Tracking',
|
||||
@@ -85,6 +88,7 @@ const features: readonly Feature[] = [
|
||||
{
|
||||
title: 'Maintenance Records',
|
||||
description: 'Keep detailed maintenance logs and never miss scheduled service appointments.',
|
||||
href: '/guide#maintenance',
|
||||
image: {
|
||||
photoId: '1486262715619-67b85e0b08d3',
|
||||
alt: 'Maintenance Records',
|
||||
@@ -93,6 +97,7 @@ const features: readonly Feature[] = [
|
||||
{
|
||||
title: 'Document Storage',
|
||||
description: 'Store and organize all vehicle documents, receipts, and important paperwork.',
|
||||
href: '/guide#documents',
|
||||
image: {
|
||||
photoId: '1568605117036-5fe5e7bab0b7',
|
||||
alt: 'Document Storage',
|
||||
@@ -101,6 +106,7 @@ const features: readonly Feature[] = [
|
||||
{
|
||||
title: 'Fuel Stations',
|
||||
description: 'Find and track your favorite fuel locations. Community verified stations with Premium 93 Octane.',
|
||||
href: '/guide#gas-stations',
|
||||
image: {
|
||||
photoId: '1572281335102-5f780686ee91',
|
||||
alt: 'Fuel Stations',
|
||||
@@ -110,6 +116,7 @@ const features: readonly Feature[] = [
|
||||
{
|
||||
title: 'Reports & Analytics',
|
||||
description: 'Generate detailed reports on costs, mileage, and vehicle performance.',
|
||||
href: '/guide#dashboard',
|
||||
image: {
|
||||
photoId: '1551288049-bebda4e38f71',
|
||||
alt: 'Reports & Analytics',
|
||||
@@ -118,6 +125,7 @@ const features: readonly Feature[] = [
|
||||
{
|
||||
title: 'Reminders',
|
||||
description: 'Set up automated reminders for maintenance, registration, and insurance renewals.',
|
||||
href: '/guide#maintenance-schedules',
|
||||
image: {
|
||||
photoId: '1434494878577-86c23bcb06b9',
|
||||
alt: 'Reminders',
|
||||
@@ -126,6 +134,7 @@ const features: readonly Feature[] = [
|
||||
{
|
||||
title: 'Data Export',
|
||||
description: 'Export your data in various formats for reporting and record keeping.',
|
||||
href: '/guide#data-import-and-export',
|
||||
image: {
|
||||
photoId: '1460925895917-afdab827c52f',
|
||||
alt: 'Data Export',
|
||||
@@ -152,6 +161,7 @@ export const FeaturesGrid = () => {
|
||||
description={feature.description}
|
||||
imageSrc={buildUnsplashUrl(feature.image)}
|
||||
imageAlt={feature.image.alt}
|
||||
href={feature.href}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
||||
98
frontend/src/pages/__tests__/GuidePage.test.tsx
Normal file
@@ -0,0 +1,98 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
|
||||
jest.mock('@auth0/auth0-react', () => ({
|
||||
useAuth0: () => ({
|
||||
isAuthenticated: false,
|
||||
loginWithRedirect: jest.fn(),
|
||||
}),
|
||||
}));
|
||||
|
||||
jest.mock('react-router-dom', () => ({
|
||||
useNavigate: () => jest.fn(),
|
||||
}));
|
||||
|
||||
// Mock MUI Accordion to avoid jsdom layout issues
|
||||
jest.mock('@mui/material', () => {
|
||||
const actual = jest.requireActual('@mui/material');
|
||||
return {
|
||||
...actual,
|
||||
Accordion: ({ children, expanded }: any) => (
|
||||
<div data-testid="accordion" data-expanded={expanded}>
|
||||
{children}
|
||||
</div>
|
||||
),
|
||||
AccordionSummary: ({ children }: any) => <div>{children}</div>,
|
||||
AccordionDetails: ({ children }: any) => <div>{children}</div>,
|
||||
};
|
||||
});
|
||||
|
||||
jest.mock('@mui/icons-material/ExpandMore', () => ({
|
||||
__esModule: true,
|
||||
default: () => <span data-testid="expand-icon" />,
|
||||
}));
|
||||
|
||||
import { GuidePage } from '../GuidePage/GuidePage';
|
||||
import { guideSections } from '../GuidePage/guideTypes';
|
||||
|
||||
describe('GuidePage', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('renders page heading and subheading', () => {
|
||||
render(<GuidePage />);
|
||||
expect(screen.getByText('User Guide')).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByText(/Precision Vehicle Management/)
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders all 10 section headings', () => {
|
||||
render(<GuidePage />);
|
||||
|
||||
const expectedHeadings = [
|
||||
'1. Getting Started',
|
||||
'2. Dashboard',
|
||||
'3. Vehicles',
|
||||
'4. Fuel Logs',
|
||||
'5. Maintenance',
|
||||
'6. Gas Stations',
|
||||
'7. Documents',
|
||||
'8. Settings',
|
||||
'9. Subscription Tiers and Pro Features',
|
||||
'10. Mobile Experience',
|
||||
];
|
||||
|
||||
expectedHeadings.forEach((heading) => {
|
||||
expect(screen.getByRole('heading', { name: heading })).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
it('renders TOC with correct section titles', () => {
|
||||
render(<GuidePage />);
|
||||
|
||||
guideSections.forEach((section) => {
|
||||
const matches = screen.getAllByText(section.title);
|
||||
expect(matches.length).toBeGreaterThanOrEqual(1);
|
||||
});
|
||||
});
|
||||
|
||||
it('renders navigation bar with Guide link highlighted', () => {
|
||||
render(<GuidePage />);
|
||||
|
||||
const guideLinks = screen.getAllByText('Guide');
|
||||
expect(guideLinks.length).toBeGreaterThanOrEqual(1);
|
||||
});
|
||||
|
||||
it('renders GuideScreenshot components with loading="lazy"', () => {
|
||||
render(<GuidePage />);
|
||||
|
||||
const images = document.querySelectorAll('img[loading="lazy"]');
|
||||
expect(images.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it('renders footer with copyright', () => {
|
||||
render(<GuidePage />);
|
||||
expect(screen.getByText(/FB Technologies LLC/)).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
@@ -20,6 +20,7 @@ import LocalGasStationRoundedIcon from '@mui/icons-material/LocalGasStationRound
|
||||
import DescriptionRoundedIcon from '@mui/icons-material/DescriptionRounded';
|
||||
import BuildRoundedIcon from '@mui/icons-material/BuildRounded';
|
||||
import SettingsRoundedIcon from '@mui/icons-material/SettingsRounded';
|
||||
import HelpOutlineRoundedIcon from '@mui/icons-material/HelpOutlineRounded';
|
||||
import { MobileScreen } from '../../../core/store/navigation';
|
||||
|
||||
// iOS swipeable drawer configuration
|
||||
@@ -41,6 +42,7 @@ interface MenuItem {
|
||||
// Menu items from bottom to top (reversed order in array for rendering)
|
||||
const menuItems: MenuItem[] = [
|
||||
{ screen: 'Settings', label: 'Settings', icon: <SettingsRoundedIcon /> },
|
||||
{ screen: 'Guide' as MobileScreen, label: 'Guide', icon: <HelpOutlineRoundedIcon /> },
|
||||
{ screen: 'Documents', label: 'Documents', icon: <DescriptionRoundedIcon /> },
|
||||
{ screen: 'Maintenance', label: 'Maintenance', icon: <BuildRoundedIcon /> },
|
||||
{ screen: 'Log Fuel', label: 'Log Fuel', icon: <LocalGasStationRoundedIcon /> },
|
||||
@@ -57,6 +59,12 @@ export const HamburgerDrawer: React.FC<HamburgerDrawerProps> = ({
|
||||
const theme = useTheme();
|
||||
|
||||
const handleNavigate = (screen: MobileScreen) => {
|
||||
// Guide is a public route outside /garage/* shell
|
||||
if (screen === ('Guide' as MobileScreen)) {
|
||||
window.location.href = '/guide';
|
||||
onClose();
|
||||
return;
|
||||
}
|
||||
onNavigate(screen);
|
||||
onClose();
|
||||
};
|
||||
|
||||