Skip to content

Commit

Permalink
Add budget pie chart - styling fixes
Browse files Browse the repository at this point in the history
Bump 0.2.2
  • Loading branch information
jordojordo committed Aug 6, 2024
1 parent 0f06965 commit c7cf019
Show file tree
Hide file tree
Showing 9 changed files with 107 additions and 26 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Overview

Horus Holdings is a sophisticated cash flow management tool designed to help users track their incomes and expenses, providing a clear visualization of their cash flow over time.
Horus Holdings is a cash flow management tool designed to help users track their incomes and expenses, providing a clear visualization of their cash flow over time.

Named after the Egyptian god Horus, who symbolizes protection, stability, and prosperity, this application aims to bring financial clarity and control to its users. By offering robust user authentication, Horus Holdings ensures that each user's financial data remains secure and private, echoing the protective nature of its namesake.

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "horusholdings",
"private": true,
"version": "0.2.1",
"version": "0.2.2",
"type": "module",
"scripts": {
"dev": "concurrently \"vite\" \"cd ./server && yarn dev\"",
Expand Down
1 change: 0 additions & 1 deletion public/vite.svg

This file was deleted.

3 changes: 2 additions & 1 deletion server/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,9 @@ app.use(
resave: false,
saveUninitialized: false,
cookie: {
secure: false,
secure: !isDevelopment,
httpOnly: true,
sameSite: isDevelopment ? 'lax' : 'none',
},
})
);
Expand Down
1 change: 1 addition & 0 deletions src/assets/style/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -99,5 +99,6 @@ h1 {

.content {
margin-top: 60px;
padding: 0;
}
}
10 changes: 10 additions & 0 deletions src/assets/style/AuthForm.css
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,14 @@
justify-content: center;
gap: 2rem;
margin-top: 2rem;
}

@media (max-width: 725px) {
.auth-container {
min-height: calc(100vh - 100px);
}

.auth-form {
width: 100%;
}
}
22 changes: 22 additions & 0 deletions src/assets/style/FlowChart.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
.flow-chart-container {
display: flex;
flex-direction: column;
width: 100%;
}

.pie {
max-width: 600px;
width: 100%;
margin: 0 auto;
}

.line,
.bar {
width: 100%;
}

@media (max-width: 725px) {
.pie {
max-width: 100%;
}
}
65 changes: 47 additions & 18 deletions src/components/FlowChart.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useEffect, useState, useCallback } from 'react';
import axios from 'axios';
import dayjs, { Dayjs } from 'dayjs';
import { Bar, Line } from 'react-chartjs-2';
import { Bar, Line, Pie } from 'react-chartjs-2';
import {
Chart as ChartJS,
CategoryScale,
Expand All @@ -12,6 +12,7 @@ import {
Legend,
PointElement,
LineElement,
ArcElement
} from 'chart.js';

import { useWebSocketContext } from '../context/WebSocketContext';
Expand All @@ -21,6 +22,8 @@ import DateRange from './DateRange';
import { Expense } from '../types/Expense';
import { Income } from '../types/Income';

import '../assets/style/FlowChart.css';

ChartJS.register(
CategoryScale,
LinearScale,
Expand All @@ -29,7 +32,8 @@ ChartJS.register(
Tooltip,
Legend,
PointElement,
LineElement
LineElement,
ArcElement
);

interface ChartData {
Expand All @@ -56,6 +60,14 @@ interface ChartData {
tension: number;
}[];
};
pieData: {
labels: string[];
datasets: {
label: string;
backgroundColor: string[];
data: number[];
}[];
};
}

const FlowChart: React.FC = () => {
Expand Down Expand Up @@ -237,6 +249,9 @@ const FlowChart: React.FC = () => {
},
};

const totalIncome = incomeData.reduce((sum, val) => sum + val, 0);
const totalExpenses = expenseData.reduce((sum, val) => sum + val, 0);

return {
labels,
barData: {
Expand Down Expand Up @@ -279,10 +294,20 @@ const FlowChart: React.FC = () => {
},
],
},
pieData: {
labels: ['Total Income', 'Total Expenses'],
datasets: [
{
label: 'Budget Overview',
backgroundColor: ['rgba(44, 182, 125, 0.4)', 'rgba(255, 127, 80, 0.4)'],
data: [totalIncome, totalExpenses],
},
],
},
};
};

const { barData, lineData } = processChartData(
const { barData, lineData, pieData } = processChartData(
incomes,
expenses,
startDate,
Expand All @@ -291,29 +316,33 @@ const FlowChart: React.FC = () => {

const options = {
responsive: true,
plugins: {
legend: { position: 'top' as const },
title: {
display: true,
text: 'Cash Flow Overview',
},
},
plugins: { legend: { position: 'top' as const } },
};


const handleDateRangeChange = (start: Dayjs, end: Dayjs) => {
setStartDate(start);
setEndDate(end);
};

return (
<div>
<DateRange
initialStartDate={startDate}
initialEndDate={endDate}
onDateRangeChange={handleDateRangeChange}
/>
<Bar data={barData} options={options} />
<Line data={lineData} options={options} />
<div className="flow-chart-container">
<div className="mb-10">
<DateRange
initialStartDate={startDate}
initialEndDate={endDate}
onDateRangeChange={handleDateRangeChange}
/>
</div>
<div className="pie mb-5">
<Pie data={pieData} options={options} />
</div>
<div className="line mb-5">
<Line data={lineData} options={options} />
</div>
<div className="bar">
<Bar data={barData} options={options} />
</div>
</div>
);
};
Expand Down
27 changes: 23 additions & 4 deletions src/components/Navbar.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState } from 'react';
import React, { useState, useEffect, useRef } from 'react';
import { Link } from 'react-router-dom';

import { MenuOutlined } from '@ant-design/icons';
Expand All @@ -13,6 +13,7 @@ const Navbar: React.FC = () => {
const { user, logout } = useAuth();
const { width } = useViewport();
const [isMenuOpen, setIsMenuOpen] = useState(false);
const menuRef = useRef<HTMLDivElement>(null);

const isMobile = width < 725;

Expand All @@ -32,6 +33,24 @@ const Navbar: React.FC = () => {
setIsMenuOpen(!isMenuOpen);
};

const handleClickOutside = (event: MouseEvent) => {
if ( menuRef.current && !menuRef.current.contains(event.target as Node) ) {
setIsMenuOpen(false);
}
};

useEffect(() => {
if ( isMenuOpen ) {
document.addEventListener('mousedown', handleClickOutside);
} else {
document.removeEventListener('mousedown', handleClickOutside);
}

return () => {
document.removeEventListener('mousedown', handleClickOutside);
};
}, [isMenuOpen]);

return (
<nav className="navbar">
<div className="navbar-container">
Expand All @@ -49,7 +68,7 @@ const Navbar: React.FC = () => {
</button>
)}
</header>
<div className={`navbar-links ${ isMenuOpen ? 'active' : '' }`}>
<div ref={menuRef} className={`navbar-links ${ isMenuOpen ? 'active' : '' }`}>
{user ? (
<>
<Link to="/dashboard" onClick={toggleMenu} className="text-bold">Dashboard</Link>
Expand All @@ -61,8 +80,8 @@ const Navbar: React.FC = () => {
</>
) : (
<>
<Link to="/login" className="text-bold">Login</Link>
<Link to="/register" className="text-bold">Register</Link>
<Link to="/login" onClick={toggleMenu} className="text-bold">Login</Link>
<Link to="/register" onClick={toggleMenu} className="text-bold">Register</Link>
</>
)}
{isMobile && (
Expand Down

0 comments on commit c7cf019

Please sign in to comment.