diff --git a/client/src/components/Chart.jsx b/client/src/components/Chart.jsx
index f3456be..cf34ab1 100644
--- a/client/src/components/Chart.jsx
+++ b/client/src/components/Chart.jsx
@@ -1,10 +1,15 @@
-import React, { useEffect, useState } from 'react';
+import React, { useEffect, useState, useContext } from 'react';
import BackButton from "./BackButton.jsx";
import { auth, onAuthStateChanged } from "../config/initializeFirestore.js";
import '../App.css';
import HamburgerMenu from "./HamburgerMenu.jsx";
+import { AppContext } from '../context/AppContext.jsx';
+import ExpenseChartJoyride from './ExpenseChartJoyride.jsx';
+
+
function App() {
+ const {runChartTour, setRunChartTour} = useContext(AppContext);
const [userId, setUserId] = useState("");
const [userEmail, setUserEmail] = useState("");
const [dimensions, setDimensions] = useState({
@@ -40,6 +45,7 @@ function App() {
return (
+ < ExpenseChartJoyride />
SimpliTrac
diff --git a/client/src/components/ExpenseChartJoyride.jsx b/client/src/components/ExpenseChartJoyride.jsx
new file mode 100644
index 0000000..f5a66b9
--- /dev/null
+++ b/client/src/components/ExpenseChartJoyride.jsx
@@ -0,0 +1,62 @@
+import React, { useContext } from 'react';
+import Joyride, { STATUS } from 'react-joyride';
+import { AppContext } from '../context/AppContext';
+
+const steps = [
+ {
+ target: 'body',
+ content: 'Welcome to the Expense Chart! This guide will walk you through the features of this powerful visualization tool.',
+ placement: 'center',
+ disableBeacon: true,
+ },
+ {
+ target: '#report-frame',
+ content: 'This is your expense chart. It provides a detailed view of your spending patterns.',
+ },
+ {
+ target: '#report-frame',
+ content: 'In the top left corner, you can switch between Mobile and Desktop views.',
+ },
+ {
+ target: '#report-frame',
+ content: 'The three-dot menu in the top right allows you to export your data in various formats.',
+ },
+ {
+ target: '#report-frame',
+ content: 'Use the date range selector at the top to filter your expenses for specific time periods.',
+ },
+ {
+ target: 'body',
+ content: 'Explore your spending patterns and gain insights into your financial habits. Remember to refer back to these features as you use the chart!',
+ placement: 'center',
+ },
+];
+
+const ExpenseChartJoyride = () => {
+ const { runChartTour, setRunChartTour } = useContext(AppContext);
+
+ const handleJoyrideCallback = (data) => {
+ const { status } = data;
+ if ([STATUS.FINISHED, STATUS.SKIPPED].includes(status)) {
+ setRunChartTour(false);
+ }
+ };
+
+ return (
+
+ );
+};
+
+export default ExpenseChartJoyride;
\ No newline at end of file
diff --git a/client/src/components/ExpensesTable.jsx b/client/src/components/ExpensesTable.jsx
index d17da8e..13716d1 100644
--- a/client/src/components/ExpensesTable.jsx
+++ b/client/src/components/ExpensesTable.jsx
@@ -6,6 +6,7 @@ import { AppContext } from "../context/AppContext.jsx";
import Transaction from "../models/Transaction.js";
import User from "../models/User.js";
import Updating from "./Updating.jsx";
+import ExpenseChartJoyride from "./ExpenseChartJoyride.jsx";
const ExpensesForm = () => {
const { user, formData, setFormData, setUser, ocrData, setOcrData, setServerResponse, isUpdating, setIsUpdating } = useContext(AppContext);
@@ -106,98 +107,101 @@ const ExpensesForm = () => {
};
return (
-
- {isUpdating && } {/* Show overlay when isUpdating is true */}
-
- Date
- }
- />
-
-
-
- Vendor
- (
- {
- const newValue = selectedOption?.value || '';
- field.onChange(newValue);
- if (newValue && !vendors.some(v => v.value === newValue)) {
- setVendors([...vendors, { value: newValue, label: newValue }]);
- }
- }}
- value={vendors.find(v => v.value === field.value) || null}
- />
- )}
- />
- {errors.vendor && {errors.vendor.message}}
-
-
-
- Category
- (
- {
- const newValue = selectedOption?.value || '';
- field.onChange(newValue);
- if (newValue && !categories.some(c => c.value === newValue)) {
- setCategories([...categories, { value: newValue, label: newValue }]);
- }
- }}
- value={categories.find(c => c.value === field.value) || null}
- />
- )}
- />
- {errors.category && {errors.category.message}}
-
-
-
- Amount
- {
- const numberChecker = /^-?\d*(\.\d*)?$/;
- return numberChecker.test(value) ? true : 'Please enter a valid amount. Enter a number without the "$" sign';
- }
- }}
- render={({ field, fieldState: { error } }) => (
- <>
-
- {error && {error.message}}
- >
- )}
- />
-
-
-
-
+ <>
+ < ExpenseChartJoyride />
+
+ {isUpdating && } {/* Show overlay when isUpdating is true */}
+
+ Date
+ }
+ />
+
+
+
+ Vendor
+ (
+ {
+ const newValue = selectedOption?.value || '';
+ field.onChange(newValue);
+ if (newValue && !vendors.some(v => v.value === newValue)) {
+ setVendors([...vendors, { value: newValue, label: newValue }]);
+ }
+ }}
+ value={vendors.find(v => v.value === field.value) || null}
+ />
+ )}
+ />
+ {errors.vendor && {errors.vendor.message}}
+
+
+
+ Category
+ (
+ {
+ const newValue = selectedOption?.value || '';
+ field.onChange(newValue);
+ if (newValue && !categories.some(c => c.value === newValue)) {
+ setCategories([...categories, { value: newValue, label: newValue }]);
+ }
+ }}
+ value={categories.find(c => c.value === field.value) || null}
+ />
+ )}
+ />
+ {errors.category && {errors.category.message}}
+
+
+
+ Amount
+ {
+ const numberChecker = /^-?\d*(\.\d*)?$/;
+ return numberChecker.test(value) ? true : 'Please enter a valid amount. Enter a number without the "$" sign';
+ }
+ }}
+ render={({ field, fieldState: { error } }) => (
+ <>
+
+ {error && {error.message}}
+ >
+ )}
+ />
+
+
+
+
+ >
);
};
diff --git a/client/src/components/HamburgerMenu.jsx b/client/src/components/HamburgerMenu.jsx
index 2fa1897..7149d33 100644
--- a/client/src/components/HamburgerMenu.jsx
+++ b/client/src/components/HamburgerMenu.jsx
@@ -24,7 +24,9 @@ const HamburgerMenu = () => {
renderNewScreen,
showCategories,
toggleCategoriesList,
- user, setRunTour
+ user,
+ setRunTour,
+ setRunChartTour
} = useContext(AppContext);
const {isOpen, onOpen, onClose} = useDisclosure();
@@ -86,7 +88,14 @@ const HamburgerMenu = () => {
variant="ghost"
w="100%"
data-tour="expense-chart"
- onClick={() => renderNewScreen("chart")}>Expense Chart
+ onClick={() => {
+ renderNewScreen("chart");
+ setRunChartTour(true);
+ setShowHamburger(false);
+ }}
+ >
+ Expense Chart
+