Skip to content

Commit

Permalink
Merge pull request #27 from chingu-voyages/layout-predrag
Browse files Browse the repository at this point in the history
minor changes to styling / tailwind theme improvement / navigation improvement / new components / reusability
  • Loading branch information
Mandla-tech authored Sep 20, 2024
2 parents 59794f5 + f14e1d3 commit 4108452
Show file tree
Hide file tree
Showing 16 changed files with 531 additions and 63 deletions.
320 changes: 315 additions & 5 deletions expense-splitter/package-lock.json

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion expense-splitter/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
"react-dom": "^18.3.1",
"react-icons": "^5.3.0",
"react-redux": "^9.1.2",
"react-router-dom": "^6.26.2"
"react-router-dom": "^6.26.2",
"recharts": "^2.12.7"
},
"devDependencies": {
"@eslint/js": "^9.9.0",
Expand Down
4 changes: 2 additions & 2 deletions expense-splitter/src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { BrowserRouter, Route, Routes } from "react-router-dom";
import Layout from "./components/Layout";
import Home from "./pages/Home";
import Groups from "./pages/Groups";
import Product from "./pages/Product";
import Friends from "./pages/friends";

function App() {
return (
Expand All @@ -12,7 +12,7 @@ function App() {
<Route path="/" element={<Layout />}>
<Route index element={<Home />} />
<Route path="groups" element={<Groups />} />
<Route path="product" element={<Product />} />
<Route path="friends" element={<Friends />} />
</Route>
</Routes>
</BrowserRouter>
Expand Down
103 changes: 103 additions & 0 deletions expense-splitter/src/components/GroupChart.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import { PieChart, Pie, Cell } from "recharts";

const data = [
{ name: "Fari", value: 50 },
{ name: "Luigi", value: 25 },
{ name: "Mina", value: 25 },
];

const COLORS = ["#4F46E5", "blue", "#F97316"];

const renderCustomizedLabel = ({
cx,
cy,
midAngle,
innerRadius,
outerRadius,
percent,
}) => {
const radius = innerRadius + (outerRadius - innerRadius) * 0.5;
const x = cx + radius * Math.cos(-midAngle * (Math.PI / 180));
const y = cy + radius * Math.sin(-midAngle * (Math.PI / 180));

return (
<text
x={x}
y={y}
fill="#FFFFFF"
textAnchor="middle"
dominantBaseline="central"
className=" font-semibold text-xl"
>
{(percent * 100).toFixed(0)}%
</text>
);
};

function GroupChart() {
return (
<section className="flex flex-col items-center justify-center w-96 bg-white p-6 rounded-lg shadow">
<div className="w-full flex justify-between">
<p className="font-semibold text-xl">Budget Split</p>
<button>Monthly ▼</button>
</div>

<PieChart width={300} height={270}>
<Pie
data={data}
cx={150}
cy={130}
innerRadius={50}
outerRadius={100}
fill="#8884d8"
paddingAngle={1}
dataKey="value"
labelLine={false}
label={renderCustomizedLabel}
>
{data.map((entry, index) => (
<Cell key={`cell-${index}`} fill={COLORS[index % COLORS.length]} />
))}
</Pie>
{/* out of the box Legend, ignore for now */}
{/* <Legend verticalAlign="bottom" align="center" height={50} /> */}
</PieChart>

{/* Custom legend */}
<div className="mb-4 p-4 px-8 shadow w-3/5 ">
{data.map((entry, index) => (
<div key={index} className="flex my-2 items-center space-x-3">
<span
className="w-3 h-3 rounded-full"
style={{ backgroundColor: COLORS[index] }}
></span>
<span className="text-black">{entry.name}</span>
</div>
))}
</div>
</section>
);
}

export default GroupChart;

// CHART EXPLANATION CODE, "RECHARTS" PACKAGE IS USED FOR CHARTS
// ----------------------------------------------------
// <PieChart>: Defines the overall chart's width and height.

// <Pie>:
// -This component takes data and builds a donut chart based on the value field of each entry.
// -cx and cy control the center of the pie chart.
// -innerRadius and outerRadius control the donut's thickness.
// -paddingAngle adds space between the slices.
// -dataKey="value" is the key used to calculate the size of the pie slices (in this case, the value field).
// -label shows the percentage labels inside the pie slices, using the renderCustomizedLabel function.
// ----------------------
// <Cell>:
// -Each slice of the pie is rendered as a Cell, and each cell gets a color from the COLORS array.
// -fill={COLORS[index % COLORS.length]} dynamically applies the color based on the index of each slice.
// ----------------------
// Legend Component (currently):

// -It’s the built-in Recharts Legend placed at the bottom (verticalAlign="bottom") and center (align="center").
// -This is currently active but will be replaced by a custom legend for better control.
4 changes: 2 additions & 2 deletions expense-splitter/src/components/GroupExpenseBar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ const ExpenseBar = ({ expense, budget }) => {
const expensePercentage = (expense / budget) * 100;

return (
<section className="flex flex-col justify-between w-full max-w-lg ml-8 rounded-lg p-6 bg-white shadow-md">
<section className="flex flex-col justify-between w-full max-w-lg rounded-lg p-6 bg-white shadow-md">
<div className="flex justify-between items-center mb-6">
<p className="text-lg font-semibold text-secondary">Expense vs budget</p>
<button className="text-sm font-medium text-gray-400 hover:text-secondary">Monthly ▼</button>
Expand Down Expand Up @@ -33,7 +33,7 @@ const ExpenseBar = ({ expense, budget }) => {
</article>

{/* legend */}
<article className="w-1/4 flex flex-col items-start space-y-2 p-4 w-52 h-20 rounded-lg bg-white shadow-xl">
<article className="flex flex-col items-start space-y-2 p-4 w-52 h-20 rounded-lg bg-white shadow-xl">
<div className="flex items-center">
<span className="w-3 h-3 rounded-full bg-primary mr-2"></span>
<span className="text-sm font-semibold text-gray-600">Expense</span>
Expand Down
4 changes: 2 additions & 2 deletions expense-splitter/src/components/GroupExpenseTable.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ const expenses = [

function GroupExpenseTable() {
return (
<div className="overflow-x-auto rounded-lg">
<section className="overflow-x-auto rounded-lg">
<table className="table-auto text-left">
<thead className="border border-gray uppercase bg-orange-100 text-sm text-gray-400">
<tr>
Expand Down Expand Up @@ -216,7 +216,7 @@ function GroupExpenseTable() {
))}
</tbody>
</table>
</div>
</section>
);
}

Expand Down
8 changes: 4 additions & 4 deletions expense-splitter/src/components/GroupMembers.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { MdGroups } from "react-icons/md";
import EachMember from "./EachMember";
import GroupsEachMember from "./GroupsEachMember";

// for icons, go to this page https://react-icons.github.io/react-icons/ the search for the icon you need. package is already installed, you just need to import the icon, just like the one above, on line 1. on the webpage, when you click on the icon and open it, you will see the code you need to copy paste to import it. to use the icon, you just put it in JSX like its a normal component. follow the <MdGroups/> example below

Expand All @@ -17,7 +17,7 @@ const members = [

function GroupMembers() {
return (
<div className="bg-white p-4 rounded-lg shadow max-w-lg ml-8">
<section className="bg-white p-4 rounded-lg shadow max-w-lg">
<div className="flex justify-between items-center mb-4 ml-4">
<p className="text-lg font-semibold text-secondary">Members</p>
<button className="px-3 py-1 rounded-lg text-sm font-semibold
Expand All @@ -27,15 +27,15 @@ function GroupMembers() {
<div className="flex p-2 space-x-4">
{/* map method */}
{members.map((member, index) => (
<EachMember member={member} index={index} />
<GroupsEachMember key={index} member={member} index={index} />
))}

<button className="flex-col flex items-center ">
<MdGroups className="rounded-full w-14 h-14 bg-blizzard-blue p-3 text-primary" />
<p className="font-medium text-secondary">Add</p>
</button>
</div>
</div>
</section>
);
}

Expand Down
4 changes: 2 additions & 2 deletions expense-splitter/src/components/GroupName.jsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
function GroupName() {
return (
<div className="flex items-center space-x-10 p-8">
<section className="flex items-center space-x-10 ">
<img className="w-20 h-20 rounded-full object-cover " src="https://freedomdestinations.co.uk/wp-content/uploads/Diamond-Head-Crater-Honolulu.jpg" alt="group-logo" />
<h1 className="text-2xl font-semibold text-secondary">Name of group</h1>
</div>
</section>
);
}

Expand Down
20 changes: 12 additions & 8 deletions expense-splitter/src/components/GroupSmallExpenseCard.jsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
import { MdGroups } from "react-icons/md";

// for icons, go to this page https://react-icons.github.io/react-icons/ the search for the icon you need. package is already installed, you just need to import the icon, just like the one above, on line 1. on the webpage, when you click on the icon and open it, you will see the code you need to copy paste to import it. to use the icon, you just put it in JSX like its a normal component. follow the <MdGroups/> example below

function GroupSmallExpenseCard() {
function GroupSmallExpenseCard({ icon: Icon, label, value, button }) {
return (
<div className="bg-white p-4 rounded-lg shadow flex items-center space-x-4 max-w-xs ml-8">
<MdGroups className="bg-blizzard-blue rounded-full w-14 h-14 p-2 text-primary" />
<section className="bg-white p-4 rounded-lg shadow flex items-start space-x-4 max-w-xs min-w-80">
<Icon className="bg-blizzard-blue rounded-full w-14 h-14 p-3 text-primary" />

<span>
<p className="text-sm font-medium text-gray-400">Total budget</p>
<p className="font-semibold text-2xl text-secondary">1000 $</p>
<p className="text-sm font-medium text-gray-400">{label}</p>
<p className="font-semibold text-2xl text-secondary">{value}</p>
</span>
</div>

{button && (
<button className="relative top-0 left-16 py-1 px-3 bg-blizzard-blue text-primary rounded-lg ">
{button}
</button>
)}
</section>
);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
function EachMember({ member, index }) {
function GroupsEachMember({ member, index }) {
return (
<div
<section
key={index}
className="relative flex flex-col w-20 items-center text-center"
>
Expand All @@ -13,8 +13,8 @@ function EachMember({ member, index }) {
<button className="bg-red-200 flex items-center justify-center rounded-full font-extrabold text-lg text-red-500 w-6 h-6 pb-1 bottom-20 relative left-7">
-
</button>
</div>
</section>
);
}

export default EachMember;
export default GroupsEachMember;
16 changes: 9 additions & 7 deletions expense-splitter/src/components/Sidebar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import { NavLink } from "react-router-dom";

function Sidebar() {
const SIDEBAR_LINKS = [
{ id: 1, path: "/", name: "Dashboard", icon: MdGroups },
{ id: 1, path: "/", name: "Home", icon: MdGroups },
{ id: 2, path: "/groups", name: "Groups", icon: IoMdPerson },
{ id: 3, path: "/product", name: "Product", icon: IoWalletSharp },
{ id: 3, path: "/friends", name: "Friends", icon: IoWalletSharp },
];

(isActive) => "nav-link" + (!isActive ? " unselected" : "");
Expand All @@ -34,22 +34,24 @@ function Sidebar() {
key={index}
to={link.path}
className={({ isActive }) =>
`flex items-center px-4 py-5 space-x-5 ${
isActive ? "text-primary font-bold text-xl" : "text-gray-500 text-sm"
`flex items-center px-4 py-5 space-x-5 text-xl font-extrabold ${
isActive ? "text-primary bg-blizzard-blue " : "text-gray-500"
}`
}
>
<span>{link.icon()}</span>
<span className="text-sm text-gray-500 font-medium hidden md:flex">
<span className="text-md text-gray-500 font-medium hidden md:flex">
{link.name}
</span>
</NavLink>
))}
</nav>

<div className="w-full absolute bottom-5 left-0 px-4 py-2 cursor-pointer text-center">
<p className="w-full flex items-center justify-center space-x-2 text-sm text-white py-2 px-4
bg-primary rounded-xl hover:bg-secondary hover:text-blizzard-blue transition duration-300 ease-in-out">
<p
className="w-full flex items-center justify-center space-x-2 text-sm text-white py-2 px-4
bg-primary rounded-xl hover:bg-secondary hover:text-blizzard-blue transition duration-300 ease-in-out"
>
<span>?</span>
<span className="hidden md:flex">Need help</span>
</p>
Expand Down
9 changes: 9 additions & 0 deletions expense-splitter/src/pages/Friends.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
function Friends() {
return (
<div className="text-5xl">
Friends
</div>
)
}

export default Friends
34 changes: 29 additions & 5 deletions expense-splitter/src/pages/Groups.jsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,44 @@
import GroupChart from "../components/GroupChart";
import ExpenseBar from "../components/GroupExpenseBar";
import GroupExpenseTable from "../components/GroupExpenseTable";
import GroupMembers from "../components/GroupMembers";
import GroupName from "../components/GroupName";
import GroupSmallExpenseCard from "../components/GroupSmallExpenseCard";
// icons
import { FaPiggyBank } from "react-icons/fa6";
import { FaCartShopping } from "react-icons/fa6";
import { GiReceiveMoney } from "react-icons/gi";

function Groups() {
return (
<div className="flex flex-col gap-8 m-6">
<section className="flex flex-col gap-8 m-6">
<GroupName />
<GroupSmallExpenseCard />
<ExpenseBar expense={300} budget={1000} />

<div className="flex gap-6 flex-col xl:flex-row">
<GroupSmallExpenseCard
icon={FaPiggyBank}
label="Total budget"
value="1000 $"
button="Edit"
></GroupSmallExpenseCard>
<GroupSmallExpenseCard
icon={FaCartShopping}
label="Total expense"
value="700 $"
></GroupSmallExpenseCard>
<GroupSmallExpenseCard
icon={GiReceiveMoney}
label="Remaining budget"
value="300 $"
></GroupSmallExpenseCard>
</div>

<ExpenseBar expense={900} budget={1000} />
<GroupChart />
<GroupMembers />
<GroupExpenseTable />
</div>
</section>
);

}

export default Groups;
4 changes: 2 additions & 2 deletions expense-splitter/src/pages/Home.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
function Home() {
return (
<div>
{/* Home */}
<div className="text-5xl">
Home Page
</div>
)
}
Expand Down
9 changes: 0 additions & 9 deletions expense-splitter/src/pages/Product.jsx

This file was deleted.

Loading

0 comments on commit 4108452

Please sign in to comment.