diff --git a/package.json b/package.json
index 49490c5..6e6c745 100644
--- a/package.json
+++ b/package.json
@@ -9,6 +9,8 @@
"@testing-library/user-event": "^13.5.0",
"bootstrap": "^5.3.7",
"chart.js": "^4.5.0",
+ "classnames": "^2.5.1",
+ "emoji-picker-react": "^4.13.2",
"faker": "^6.6.6",
"react": "^19.1.0",
"react-bootstrap": "^2.10.10",
diff --git a/src/components/CategorySign/CategorySign.jsx b/src/components/CategorySign/CategorySign.jsx
new file mode 100644
index 0000000..85b37d0
--- /dev/null
+++ b/src/components/CategorySign/CategorySign.jsx
@@ -0,0 +1,69 @@
+import { useTheme } from "../../contexts/ThemeContext";
+import { Button } from "react-bootstrap";
+import styles from "./CategorySign.module.css";
+import classNames from "classnames";
+
+const CategorySign = ({ icon, title, subcategories }) => {
+ const { theme } = useTheme();
+ return (
+
+ );
+};
+
+export default CategorySign;
diff --git a/src/components/CategorySign/CategorySign.module.css b/src/components/CategorySign/CategorySign.module.css
new file mode 100644
index 0000000..f199a05
--- /dev/null
+++ b/src/components/CategorySign/CategorySign.module.css
@@ -0,0 +1,7 @@
+.hideScrollbar {
+ scrollbar-width: none;
+ -ms-overflow-style: none;
+}
+.hideScrollbar::-webkit-scrollbar {
+ display: none;
+}
diff --git a/src/components/EmojiPickerButton/EmojiPickerButton.jsx b/src/components/EmojiPickerButton/EmojiPickerButton.jsx
new file mode 100644
index 0000000..cf7b193
--- /dev/null
+++ b/src/components/EmojiPickerButton/EmojiPickerButton.jsx
@@ -0,0 +1,58 @@
+import React, { useState, useRef } from "react";
+import { Button, Overlay, Popover, InputGroup } from "react-bootstrap";
+import EmojiPicker from "emoji-picker-react";
+import { useTheme } from "../../contexts/ThemeContext";
+
+const EmojiPickerButton = () => {
+ const { theme } = useTheme();
+ const [showPicker, setShowPicker] = useState(false);
+ const [inputValue, setInputValue] = useState("😀");
+ const target = useRef(null);
+
+ const handleEmojiSelect = (emoji) => {
+ setInputValue(emoji.emoji);
+ setShowPicker(false);
+ };
+
+ return (
+
+
+ setShowPicker(!showPicker)}
+ >
+ {inputValue}
+
+
+ setShowPicker(false)}
+ >
+
+
+
+
+
+
+
+
+ );
+};
+
+export default EmojiPickerButton;
diff --git a/src/components/NavigationBar/NavigationBar.jsx b/src/components/NavigationBar/NavigationBar.jsx
index 1fa9177..9837f63 100644
--- a/src/components/NavigationBar/NavigationBar.jsx
+++ b/src/components/NavigationBar/NavigationBar.jsx
@@ -4,14 +4,14 @@ import SettingsModal from "../../modals/SettingsModal/SettingsModal";
const NavigationBar = () => {
return (
-
Wallet
-
+
);
};
diff --git a/src/modals/AddCategoryModal/AddCategoryModal.jsx b/src/modals/AddCategoryModal/AddCategoryModal.jsx
new file mode 100644
index 0000000..5932bf8
--- /dev/null
+++ b/src/modals/AddCategoryModal/AddCategoryModal.jsx
@@ -0,0 +1,70 @@
+import { useState } from "react";
+import { useTheme } from "../../contexts/ThemeContext";
+import { Modal, Button, Card, Form } from "react-bootstrap";
+import EmojiPickerButton from "../../components/EmojiPickerButton/EmojiPickerButton";
+
+const AddCategoryModal = ({ variant, ...props }) => {
+ const { theme } = useTheme();
+ const [show, setShow] = useState(false);
+ const handleClose = () => setShow(false);
+ const handleShow = () => setShow(true);
+ const [title, setTitle] = useState("");
+ return (
+ <>
+
+ New Category
+
+
+
+
+ New Category
+
+ ✕
+
+
+
+
+
+
+ setTitle(e.target.value)}
+ className="mb-3"
+ />
+
+
+
+ SUBCATEGORIES
+
+ {}}
+ className="w-100 text-start mb-3"
+ >
+ Add subcategory
+
+
+ Add
+
+
+
+
+ >
+ );
+};
+export default AddCategoryModal;
diff --git a/src/modals/AnalyticsModal/AnalyticsModal.jsx b/src/modals/AnalyticsModal/AnalyticsModal.jsx
index f93193d..c0eae45 100644
--- a/src/modals/AnalyticsModal/AnalyticsModal.jsx
+++ b/src/modals/AnalyticsModal/AnalyticsModal.jsx
@@ -145,7 +145,7 @@ const AnalyticsModal = () => {
-
+
diff --git a/src/modals/CategoriesModal/CategoriesModal.jsx b/src/modals/CategoriesModal/CategoriesModal.jsx
new file mode 100644
index 0000000..2934435
--- /dev/null
+++ b/src/modals/CategoriesModal/CategoriesModal.jsx
@@ -0,0 +1,113 @@
+import { useState } from "react";
+import { useTheme } from "../../contexts/ThemeContext";
+import {
+ Modal,
+ Button,
+ Form,
+ InputGroup,
+ Tabs,
+ Tab,
+ Dropdown,
+ DropdownButton,
+} from "react-bootstrap";
+import styles from "./CategoriesModal.module.css";
+import CategorySign from "../../components/CategorySign/CategorySign";
+import AddCategoryModal from "../../modals/AddCategoryModal/AddCategoryModal";
+
+const CategoriesModal = ({ variant }) => {
+ const { theme } = useTheme();
+ const [show, setShow] = useState(false);
+ const handleClose = () => setShow(false);
+ const handleShow = () => setShow(true);
+ return (
+ <>
+
+ © Categories
+ ❯
+
+
+
+
+
+
+ ❯
+ Settings
+
+
Categories
+
+
+
+
+
+ Reorder
+
+
+
+
+ ☌
+
+
+
+
+
+
+
+
+ asdf
+
+
+
+
+
+
+
+
+
+
+ >
+ );
+};
+export default CategoriesModal;
diff --git a/src/modals/CategoriesModal/CategoriesModal.module.css b/src/modals/CategoriesModal/CategoriesModal.module.css
new file mode 100644
index 0000000..8626f1c
--- /dev/null
+++ b/src/modals/CategoriesModal/CategoriesModal.module.css
@@ -0,0 +1,11 @@
+.scrollableContent {
+ height: calc(100vh - 220px);
+ bottom: 0;
+ overflow-y: auto;
+}
+
+@media (max-width: 768px) {
+ .scrollableContent {
+ height: calc(100vh - 280px);
+ }
+}
diff --git a/src/modals/SettingsModal/SettingsModal.jsx b/src/modals/SettingsModal/SettingsModal.jsx
index d2ae274..78aea82 100644
--- a/src/modals/SettingsModal/SettingsModal.jsx
+++ b/src/modals/SettingsModal/SettingsModal.jsx
@@ -2,6 +2,7 @@ import { useState } from "react";
import { useTheme } from "../../contexts/ThemeContext";
import { ListGroup, Modal, Button } from "react-bootstrap";
import ThemeToggle from "../../components/ThemeToggle";
+import CategoriesModal from "../../modals/CategoriesModal/CategoriesModal";
const SettingsModal = () => {
const { theme } = useTheme();
@@ -39,6 +40,17 @@ const SettingsModal = () => {
+
+ DATA
+
+
+
+
+
+
+
+ APPLICATION
+