diff --git a/README.md b/README.md index 0ba00886..0fa50ea8 100644 --- a/README.md +++ b/README.md @@ -85,6 +85,8 @@ Keyboard shortcuts can be triggered when no input field is selected. | Clone current budget | C | | Create new budget | A | | Export data | S | +| Go to older budget | PageDown | +| Go to newer budget | PageUp | ### CSV data model: diff --git a/src/components/BudgetPage.tsx b/src/components/BudgetPage.tsx index b87454ae..e8e6d5ef 100644 --- a/src/components/BudgetPage.tsx +++ b/src/components/BudgetPage.tsx @@ -63,6 +63,8 @@ function BudgetPage() { useHotkeys("s", () => handleExport(), { preventDefault: true }); useHotkeys("a", () => handleNew(), { preventDefault: true }); useHotkeys("c", () => handleClone(), { preventDefault: true }); + useHotkeys("pageup", () => handleGoForward(), { preventDefault: true }); + useHotkeys("pagedown", () => handleGoBack(), { preventDefault: true }); const calcBudgetListName = (list: Budget[]) => { setBudgetNameList( @@ -227,6 +229,26 @@ function BudgetPage() { setBudget(filteredList[0]); }; + const handleGoBack = () => { + const sortedList = budgetList.sort((a, b) => a.name.localeCompare(b.name)); + if (budget) { + const index = sortedList.findIndex((b) => b.name.includes(budget.name)); + if (index !== 0) { + handleSelect([sortedList[index - 1] as unknown as Option[]]); + } + } + }; + + const handleGoForward = () => { + const sortedList = budgetList.sort((a, b) => a.name.localeCompare(b.name)); + if (budget) { + const index = sortedList.findIndex((b) => b.name.includes(budget.name)); + if (index !== sortedList.length - 1) { + handleSelect([sortedList[index + 1] as unknown as Option[]]); + } + } + }; + const handleImport = (e: React.ChangeEvent) => { setLoading(true); const importedFiles = e.target.files; @@ -417,6 +439,12 @@ function BudgetPage() { onExport={() => { handleExport(); }} + onGoBack={() => { + handleGoBack(); + }} + onGoForward={() => { + handleGoForward(); + }} onNew={() => { handleNew(); }} diff --git a/src/components/NavBar.tsx b/src/components/NavBar.tsx index 0a176584..4a066687 100644 --- a/src/components/NavBar.tsx +++ b/src/components/NavBar.tsx @@ -5,35 +5,46 @@ import Container from "react-bootstrap/Container"; import Form from "react-bootstrap/Form"; import Nav from "react-bootstrap/Nav"; import Navbar from "react-bootstrap/Navbar"; -import { BsPlusLg, BsXLg, BsUpload, BsDownload } from "react-icons/bs"; +import { + BsPlusLg, + BsXLg, + BsUpload, + BsDownload, + BsArrowLeft, + BsArrowRight, +} from "react-icons/bs"; import { FaRegClone } from "react-icons/fa"; import { Typeahead } from "react-bootstrap-typeahead"; import { Option } from "react-bootstrap-typeahead/types/types"; interface NavBarProps { - selected?: string | null; - id?: string | null; budgetNameList: { id: string; name: string }[]; - onRename: (name?: string | null) => void; - onExport: () => void; + id?: string | null; + selected?: string | null; onClone: () => void; + onExport: () => void; + onGoBack: () => void; + onGoForward: () => void; + onImport: (e: React.ChangeEvent) => void; onNew: () => void; onRemove: (name: string) => void; + onRename: (name?: string | null) => void; onSelect: (budget: Option[]) => void; - onImport: (e: React.ChangeEvent) => void; } function NavBar({ - selected: initialSelectedName, - id: initialId, budgetNameList: initialBudgetNameList, - onRename, + id: initialId, + selected: initialSelectedName, onClone, onExport, + onGoBack, + onGoForward, + onImport, onNew, onRemove, + onRename, onSelect, - onImport, }: NavBarProps) { const inputRef = useRef(null); const typeRef = useRef(); @@ -85,6 +96,14 @@ function NavBar({ } }; + const handleGoBack = () => { + onGoBack(); + }; + + const handleGoForward = () => { + onGoForward(); + }; + const editName = (event: React.ChangeEvent) => { const newName = event.target.value; if (newName) { @@ -94,28 +113,62 @@ function NavBar({ return ( - + {initialBudgetNameList && initialBudgetNameList.length < 1 && ( - - guitos - + guitos )} - {initialSelectedName && ( -