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 +