Skip to content

Commit

Permalink
Merge pull request #36 from chingu-voyages/layout-predrag
Browse files Browse the repository at this point in the history
Added local storage. Added functional search bar. Added a list of tasks to do. Minor fixes
  • Loading branch information
Mandla-tech authored Oct 4, 2024
2 parents 79ada29 + c67e153 commit 3c55344
Show file tree
Hide file tree
Showing 11 changed files with 208 additions and 77 deletions.
32 changes: 26 additions & 6 deletions expense-splitter/TODO.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,27 @@
some reminder for myself (Predrag)
some reminders for myself (Predrag)

- try to extract modal logic into a custom hook
- simplify GroupMembers.jsx by making members automatically wrap inside container so that you can remove "view all" btn
- replace icons in Total budget/Total expense/Remaining budget cards to be empty not filled, and replace the bugged shopping cart icon with something else
- see with Fari to make array of colors that look nice and are the same theme, like sand colors or something. this is for the chart colors on groups page
- inside GroupMembers.jsx make it so that member cards will wrap automatically and the container expands downwards automatically. for some reason, this is not the case right now by default. member cards should not overflow outside the container
MINOR

- check whether DarkModeToggle.jsx toggle functionality can be written in more declarative way
- [IN PROGRESS] see with Fari to make array of colors that look nice and are the same theme, like sand colors or something. this is for the chart colors on groups page
- [IN PROGRESS] color pallete for dark mode

CASH MEETING

- AGREEMENT TO DELAY FOR NOW UNTIL ALL PREVIOUS TASKS ARE DONE discuss purpose of table inside group details and how to handle adding an expense
- CASH [STEP TO BE DONE?] discuss implementing groups in the sidebar as well and the ability to add new groups from the sidebar [SHOW IMAGE]
- [STEP TO BE DONE?] implement editing groups total budget and expense from groups details page
- CASH [STEP TO BE DONE?] fix styling and align everything well in GroupMembers.jsx
- CASH [STEP TO BE DONE?] inside GroupMembers.jsx members section where you can add and remove members, make a bg change on hover and replace minus for removing members with x and make bg of x more red and do hover too
- PREDRAG [STEP TO BE DONE?] try to extract modal logic into a custom hook
- PREDRAG [STEP TO BE DONE?] replace icons in Total budget/Total expense/Remaining budget cards to be empty not filled, and replace the bugged shopping cart icon with something else
- PREDRAG [STEP TO BE DONE?] refactor the modal in GroupMembers.jsx and all logic related to "member number". it should be contribution, what % of it.
- PREDRAG [STEP TO BE DONE?] add number of dollars that is percentage inside chart
- CASH [STEP TO BE DONE?] implement editable description component both for individual group and individual friend
- CASH [STEP TO BE DONE?] complete the layout on all pages
- PREDRAG [STEP TO BE DONE?] when there are no members in a group, the Budget Split component is bugged, fix it. ad text that says "there are no members for chart to display"
- CASH [STEP TO BE DONE?] create styling for a btn for theme toggling and put it in place instead of "need help" btn
- CASH [STEP TO BE DONE?] make logo clickable, it should take user to homepage
- AGREEMENT TO REMOVE discuss removing "montly" and "view all" btns in groups details page
- AGREEMENT TO REMOVE [IMAGE] discuss displayed list of friends on the homepage
- AGREEMENT TO DISCUSS FURTHER WITH THE REST OF THE TEAM discuss friends details page, NEEDS BIG CHANGES
14 changes: 7 additions & 7 deletions expense-splitter/src/components/DarkModeToggle.jsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
import { useEffect, useState } from 'react';
import { useEffect, useState } from "react";

function DarkModeToggle() {
const [darkMode, setDarkMode] = useState(false);

useEffect(() => {
// Check local storage for the theme on initial render
const isDarkMode = localStorage.getItem('theme') === 'dark';
const isDarkMode = localStorage.getItem("theme") === "dark";
setDarkMode(isDarkMode);
document.documentElement.classList.toggle('dark', isDarkMode);
document.documentElement.classList.toggle("dark", isDarkMode);
}, []);

const toggleDarkMode = () => {
const newDarkMode = !darkMode;
setDarkMode(newDarkMode);
document.documentElement.classList.toggle('dark', newDarkMode);
localStorage.setItem('theme', newDarkMode ? 'dark' : 'light');
document.documentElement.classList.toggle("dark", newDarkMode);
localStorage.setItem("theme", newDarkMode ? "dark" : "light");
};

return (
<button
onClick={toggleDarkMode}
className="bg-gray-200 dark:bg-gray-800 p-2 rounded-full text-sm"
className="bg-gray-200 dark:bg-gray-800 p-2 rounded-full text-sm dark:text-white"
>
{darkMode ? '🌙' : '☀️'}
{darkMode ? "🌙 Light mode" : "☀️ Dark mode"}
</button>
);
}
Expand Down
27 changes: 15 additions & 12 deletions expense-splitter/src/components/Groups/GroupChart.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const renderCustomizedLabel = ({
outerRadius,
percent,
}) => {
const radius = innerRadius + (outerRadius - innerRadius) * 0.5;
const radius = innerRadius + (outerRadius - innerRadius) * 0.6;
const x = cx + radius * Math.cos(-midAngle * (Math.PI / 180));
const y = cy + radius * Math.sin(-midAngle * (Math.PI / 180));

Expand All @@ -25,7 +25,7 @@ const renderCustomizedLabel = ({
fill="#FFFFFF"
textAnchor="middle"
dominantBaseline="central"
className="text-sm font-bold text-secondary"
className="text-md font-bold text-secondary"
>
{(percent * 100).toFixed(0)}%
</text>
Expand All @@ -49,21 +49,23 @@ function GroupChart({ groupId }) {
}));

return (
<section className="flex flex-col items-center justify-center w-custom-wide-chart h-custom-height-chart bg-white dark:bg-dark-secondary dark:border p-6 ml-8 rounded-lg shadow">
<section className="flex flex-col items-center justify-center w-custom-wide-chart bg-white dark:bg-dark-secondary dark:border p-6 ml-8 rounded-lg shadow">
<div className="w-full flex justify-between">
<p className="text-lg font-bold text-secondary ml-8 dark:text-primary">Budget Split</p>
<button className="text-body font-medium text-primary bg-blizzard-blue w-30 h-8 mr-8 py-1 px-4 rounded-lg">
{/* under btn to be removed perhaps due to simplification of the app */}
{/* <button className="text-body font-medium text-primary bg-blizzard-blue w-30 h-8 mr-8 py-1 px-4 rounded-lg">
Members ▼
</button>
</button> */}
</div>

<PieChart width={171} height={171}>
{/* chart size */}
<PieChart width={250} height={250}>
<Pie
data={data}
cx={85.5}
cy={81.9}
innerRadius={20.5}
outerRadius={57}
cx={120}
cy={130}
innerRadius={30.5}
outerRadius={90}
fill="#8884d8"
paddingAngle={1}
dataKey="value"
Expand All @@ -79,9 +81,10 @@ function GroupChart({ groupId }) {
</PieChart>

{/* Custom legend */}
<div className="mb-6 p-4 w-52 h-30 rounded-lg bg-white shadow-custom">
{/* bg-white removed */}
<div className="p-3 flex rounded-lg shadow-custom flex-wrap justify-start">
{data.map((entry, index) => (
<div key={index} className="flex my-2 items-center space-x-4">
<div key={index} className="flex my-2 items-center mx-2 space-x-3 p-1 ">
<span
className="w-3 h-3 rounded-full"
style={{ backgroundColor: COLORS[index] }}
Expand Down
62 changes: 35 additions & 27 deletions expense-splitter/src/components/Groups/GroupMembers.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { MdGroups } from "react-icons/md";
import GroupsEachMember from "./GroupsEachMember";
import { useParams } from "react-router-dom";
import { useSelector, useDispatch } from "react-redux";
Expand Down Expand Up @@ -75,20 +74,37 @@ function GroupMembers() {
return (
<section className="bg-white dark:bg-dark-secondary dark:border p-6 ml-8 rounded-lg shadow w-custom-width">
<div className="flex justify-between items-center mb-4 ml-4">
<p className="text-lg font-bold text-secondary dark:text-primary">Members</p>
<button
<p className="text-lg font-bold text-secondary dark:text-primary">
Members
</p>
{/* under btn to be removed perhaps due to simplification of the app */}
{/* <button
className="w-20 h-8 rounded-lg text-body font-medium
bg-blizzard-blue text-primary duration-300"
>
View all
</button>
</button> */}
</div>

<div className="flex p-2 space-x-4">
{/* map method */}
{/* note to self, add bg-red-500 to line under to better checking for aligments */}
<article className="flex flex-wrap justify-start">

<div className="bg-white dark:bg-dark-secondary rounded-2xl flex items-center flex-col">
<button
onClick={() => setIsModalOpen(true)}
className="w-14 h-14 rounded-full shadow-lg bg-primary dark:bg-dark-bg text-4xl text-white dark:text-dark-text hover:bg-primary"
>
+
</button>
<p className="font-bold text-legend dark:text-dark-text">Add</p>
</div>
{group.members.map((member) => (
<div key={member.id} className="flex flex-col items-center">
<Link to={`/friends/${member.name}`} className="hover:bg-slate-200">
<div
key={member.id}
// note to self, add bg-red-200 to line under to better checking for aligments
className="bg-red-200 flex flex-col items-center m-1"
>
<Link to={`/friends/${member.name}`} className="hover:bg-slate-100 transition-colors rounded-md bg-red-400">
<GroupsEachMember
member={{
name: member.name,
Expand All @@ -104,26 +120,20 @@ function GroupMembers() {
</button>
</div>
))}
</article>

<button
onClick={() => setIsModalOpen(true)}
className="flex-col flex items-center "
>
<MdGroups className="rounded-full w-14 h-14 bg-blizzard-blue p-3 text-primary" />
<p className="text-legend font-bold text-secondary dark:text-primary">Add</p>
</button>
</div>

{/* MODAL */}
{isModalOpen && (
<section
id="modal-overlay"
className="fixed inset-0 bg-black bg-opacity-20 flex justify-center items-center"
onClick={handleModalClickOutside}
>

<article className="bg-white dark:bg-dark-secondary p-6 rounded-lg w-96">
<div className="flex justify-between items-center">
<h2 className="text-2xl mb-4 font-bold dark:text-dark-text">Add New Member</h2>
<h2 className="text-2xl mb-4 font-bold dark:text-dark-text">
Add New Member
</h2>
<button
className="bg-white shadow rounded-full w-8 h-8 text-red-500 mb-4"
onClick={() => setIsModalOpen(false)}
Expand All @@ -134,8 +144,9 @@ function GroupMembers() {

<form onSubmit={handleSubmit} className="space-y-3">
<div>

<label className="text-body font-semibold dark:text-dark-text">Member Name</label>
<label className="text-body font-semibold dark:text-dark-text">
Name
</label>

<input
type="text"
Expand All @@ -150,17 +161,16 @@ function GroupMembers() {
</div>

<div>

<label className="text-body font-semibold dark:text-dark-text">Member Number</label>
<label className="text-body font-semibold dark:text-dark-text">
Member Number
</label>

<input
type="text"
name="number"
value={newMember.number}
onChange={handleAddMemberInputChange}

className="border p-2 w-full dark:bg-dark-input"

placeholder="Enter member number"
required
style={{ fontSize: "14px" }}
Expand All @@ -169,9 +179,7 @@ function GroupMembers() {

<button
type="submit"

className="px-4 py-2 bg-primary text-white rounded-xl dark:bg-dark-primary"

>
Add Member
</button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ function GroupsEachMember({ member }) {
/>

<p className="font-bold text-legend dark:text-dark-text">{member.name}</p>

</section>
);
}
Expand Down
9 changes: 4 additions & 5 deletions expense-splitter/src/components/Layout.jsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
import { Outlet } from "react-router-dom";


// components
import Sidebar from "./Sidebar";
// import Header from "./Header";

function Layout() {
return (
<div className="flex bg-blizzard-blue dark:bg-dark-bg">
<section className="flex bg-blizzard-blue dark:bg-dark-bg">
<Sidebar />
{/* <Members /> */}

<div className="w-full ml-16 md:ml-56">
{/* <Header /> */}

<Outlet />
</div>
</div>
</section>
);
}

Expand Down
27 changes: 27 additions & 0 deletions expense-splitter/src/components/SearchBar.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { IoIosSearch } from "react-icons/io";
import { useState } from "react";

function SearchBar({ onSearch }) {
const [searchQuery, setSearchQuery] = useState("");

const handleSearch = (e) => {
const value = e.target.value;
setSearchQuery(value);
onSearch(value); // Call the parent handler to filter groups
};

return (
<div className=" relative w-full max-w-xs">
<IoIosSearch className="absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400" />
<input
type="text"
value={searchQuery}
onChange={handleSearch}
placeholder="Search groups"
className="pl-10 pr-4 py-2 rounded-lg border w-full focus:outline-none focus:ring-2 focus:ring-primary dark:bg-dark-input"
/>
</div>
);
}

export default SearchBar;
4 changes: 3 additions & 1 deletion expense-splitter/src/features/groupsSlice.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ const initialState = {
{ id: 1, name: "Mark", contribution: 0 },
{ id: 2, name: "Jason", contribution: 0 },
{ id: 3, name: "Conan", contribution: 0 },
],
{ id: 4, name: "Mark", contribution: 0 },
{ id: 5, name: "Jason", contribution: 0 },
]
},
],
};
Expand Down
24 changes: 24 additions & 0 deletions expense-splitter/src/features/localStorageUtils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// localStorageUtils.js

export const loadState = () => {
try {
const serializedState = localStorage.getItem("appState");
if (serializedState === null) {
return undefined; // Let reducers initialize the app state
}
return JSON.parse(serializedState); // Parse the state
} catch (err) {
console.error("Error loading state:", err);
return undefined;
}
};

export const saveState = (state) => {
try {
const serializedState = JSON.stringify(state);
localStorage.setItem("appState", serializedState);
} catch (err) {
console.error("Error saving state:", err);
}
};

Loading

0 comments on commit 3c55344

Please sign in to comment.