diff --git a/src/components/forms/AdminForm.jsx b/src/components/forms/AdminForm.jsx index 93942ff..242381b 100644 --- a/src/components/forms/AdminForm.jsx +++ b/src/components/forms/AdminForm.jsx @@ -1,5 +1,6 @@ /* eslint-disable react/prop-types */ +import { useState } from "react"; import { Button } from "../ui/button"; import { Input } from "../ui/input"; import { Label } from "../ui/label"; @@ -44,7 +45,9 @@ export default function AdminForm({ required /> - + ); } diff --git a/src/components/forms/ExpenseForm.jsx b/src/components/forms/ExpenseForm.jsx index 371edbb..9232f55 100644 --- a/src/components/forms/ExpenseForm.jsx +++ b/src/components/forms/ExpenseForm.jsx @@ -1,6 +1,6 @@ -import { Label } from "@/components/ui/label" -import { Input } from "@/components/ui/input" -import { Textarea } from "@/components/ui/textarea" +import { Label } from "@/components/ui/label"; +import { Input } from "@/components/ui/input"; +import { Textarea } from "@/components/ui/textarea"; import { Select, SelectContent, @@ -8,29 +8,34 @@ import { SelectItem, SelectTrigger, SelectValue, -} from "@/components/ui/select" -import PropTypes from "prop-types" -import { Button } from "../ui/button" -import { EXPENSE_CATEGORIES_MOCK, PARTICIPANTS_MOCK_DATA } from "@/lib/mock-data" -import { useEffect, useState } from "react" -import { Popover, PopoverContent, PopoverTrigger } from "../ui/popover" -import { cn } from "@/lib/utils" -import { CalendarIcon, Percent } from "lucide-react" -import { format } from "date-fns" -import { Calendar } from "../ui/calendar" -import { CONTRIBUTION_WEIGHTS } from "@/lib/constants" +} from "@/components/ui/select"; +import PropTypes from "prop-types"; +import { Button } from "../ui/button"; +import { + EXPENSE_CATEGORIES_MOCK, + PARTICIPANTS_MOCK_DATA, +} from "@/lib/mock-data"; +import { useEffect, useState } from "react"; +import { Popover, PopoverContent, PopoverTrigger } from "../ui/popover"; +import { cn } from "@/lib/utils"; +import { CalendarIcon, Percent } from "lucide-react"; +import { format } from "date-fns"; +import { Calendar } from "../ui/calendar"; +import { CONTRIBUTION_WEIGHTS } from "@/lib/constants"; // TODO add default values prop (needed in case of edit export function ExpenseForm({ onSubmit, actions, className, date, setDate }) { - const [participants, setParticipants] = useState([]) + const [participants, setParticipants] = useState([]); useEffect(() => { - const participantsData = JSON.parse(localStorage.getItem("participantsData")) + const participantsData = JSON.parse( + localStorage.getItem("participantsData") + ); - if(participantsData){ - setParticipants(participantsData) + if (participantsData) { + setParticipants(participantsData); } - }) + }, []); return (
- + {actions ? ( @@ -132,7 +147,7 @@ export function ExpenseForm({ onSubmit, actions, className, date, setDate }) { )}
- ) + ); } ExpenseForm.propTypes = { @@ -142,4 +157,4 @@ ExpenseForm.propTypes = { setDate: PropTypes.func, // defaultValues: PropsTypes. className: PropTypes.string, -} +}; diff --git a/src/hooks/useLocalStorage.js b/src/hooks/useLocalStorage.js deleted file mode 100644 index ce73b38..0000000 --- a/src/hooks/useLocalStorage.js +++ /dev/null @@ -1,20 +0,0 @@ -import { useState } from "react"; - -export function useLocalStorage(key, defaultvalue) { - const [storedData, setStoredData] = useState(() => { - try { - const data = window.localStorage.getItem(key); - return data ? JSON.parse(data) : defaultvalue; - } catch (error) { - console.error("Error receiving data", error); - } - }); - - { - /*function setInformation(value) { - window.localStorage.setItem(key, JSON.stringify()); - }*/ - } - - return [storedData, setStoredData]; -} diff --git a/src/pages/Dashboard.jsx b/src/pages/Dashboard.jsx index 553e0d5..a30cdbb 100644 --- a/src/pages/Dashboard.jsx +++ b/src/pages/Dashboard.jsx @@ -1,33 +1,115 @@ -import React from 'react' -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "../components/ui/card"; -import { CircleDollarSign, Group, UsersRound } from 'lucide-react'; -import { cn, getInitials, totalExpenses } from "@/lib/utils" -import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar" -import { NavLink } from 'react-router-dom'; -import { ExpensesList } from '@/components/ExpensesList'; -import { Heading, BodyText } from '@/components/Typography'; -import { Button } from '@/components/ui/button'; +import { Card, CardHeader } from "../components/ui/card"; +import { CircleDollarSign, Group, UsersRound } from "lucide-react"; +import { totalExpenses } from "@/lib/utils"; +import { NavLink } from "react-router-dom"; +import { ExpensesList } from "@/components/ExpensesList"; +import { Heading, BodyText } from "@/components/Typography"; +import { Button } from "@/components/ui/button"; import GridCard from "@/components/GridCard"; import { PageGrid } from "@/components/PageGrid"; const MOCK_GROUP_INFO = [ - { name: "Bali Trip", avatar: "#", id: "random_id_1", budget: 500, expense: 300, members: 5 }, - { name: "Hawaii Trip", avatar: "#", id: "random_id_2", budget: 500, expense: 300, members: 5 }, - { name: "Mike's Birthday", avatar: "#", id: "random_id_3", budget: 500, expense: 300, members: 5 }, - { name: "John's Birthday", avatar: "#", id: "random_id_4", budget: 500, expense: 300, members: 5 }, - { name: "Escape Room", avatar: "#", id: "random_id_5", budget: 500, expense: 300, members: 5 }, -] + { + name: "Bali Trip", + avatar: "#", + id: "random_id_1", + budget: 500, + expense: 300, + members: 5, + }, + { + name: "Hawaii Trip", + avatar: "#", + id: "random_id_2", + budget: 500, + expense: 300, + members: 5, + }, + { + name: "Mike's Birthday", + avatar: "#", + id: "random_id_3", + budget: 500, + expense: 300, + members: 5, + }, + { + name: "John's Birthday", + avatar: "#", + id: "random_id_4", + budget: 500, + expense: 300, + members: 5, + }, + { + name: "Escape Room", + avatar: "#", + id: "random_id_5", + budget: 500, + expense: 300, + members: 5, + }, +]; const LAST_THREE_GROUPS = MOCK_GROUP_INFO.slice(-3); - const MOCK_EXPENSES = [ - { name: "Plane tickets to Hawaii", group: "Hawaii Trip", amount: 150, id: "expense_id_1", date: new Date('2024-01-02'), description: "", category: "", purchaser: "", contributionWeight: 10 }, - { name: "Hotel for Bali", group: "Bali Trip", amount: 150, id: "expense_id_2", date: new Date('2024-08-23'), description: "", category: "", purchaser: "", contributionWeight: 10 }, - { name: "Beer for John's Birthday", group: "John's Birthday", amount: 150, id: "expense_id_3", date: new Date('2024-05-18'), description: "", category: "", purchaser: "", contributionWeight: 10 }, - { name: "BBQ for Mike's Birthday", group: "Mike's Birthday", amount: 150, id: "expense_id_4", date: new Date('2024-06-30'), description: "", category: "", purchaser: "", contributionWeight: 10 }, - { name: "Escape Room Entry fee", group: "Escape Room", amount: 150, id: "expense_id_5", date: new Date('2024-02-24'), description: "", category: "", purchaser: "", contributionWeight: 10 }, -] + { + name: "Plane tickets to Hawaii", + group: "Hawaii Trip", + amount: 150, + id: "expense_id_1", + date: new Date("2024-01-02"), + description: "", + category: "", + purchaser: "", + contributionWeight: 10, + }, + { + name: "Hotel for Bali", + group: "Bali Trip", + amount: 150, + id: "expense_id_2", + date: new Date("2024-08-23"), + description: "", + category: "", + purchaser: "", + contributionWeight: 10, + }, + { + name: "Beer for John's Birthday", + group: "John's Birthday", + amount: 150, + id: "expense_id_3", + date: new Date("2024-05-18"), + description: "", + category: "", + purchaser: "", + contributionWeight: 10, + }, + { + name: "BBQ for Mike's Birthday", + group: "Mike's Birthday", + amount: 150, + id: "expense_id_4", + date: new Date("2024-06-30"), + description: "", + category: "", + purchaser: "", + contributionWeight: 10, + }, + { + name: "Escape Room Entry fee", + group: "Escape Room", + amount: 150, + id: "expense_id_5", + date: new Date("2024-02-24"), + description: "", + category: "", + purchaser: "", + contributionWeight: 10, + }, +]; //Sorting expenses by date const SORTED_MOCK_EXPENSES = MOCK_EXPENSES.sort((a, b) => b.date - a.date); @@ -35,84 +117,110 @@ const SORTED_MOCK_EXPENSES = MOCK_EXPENSES.sort((a, b) => b.date - a.date); //Last 3 expenses const LAST_THREE_EXPENSES = SORTED_MOCK_EXPENSES.slice(-3); - - - function Dashboard() { - - const groupList = LAST_THREE_GROUPS.map(group => { - return ( - - Alloted Budget: ${group.budget} - Expense Amount: ${group.expense} - Participants: {group.members} - - } - footer= { - <> - - - } - /> - ) - }) - - + const groupList = LAST_THREE_GROUPS.map((group) => { return ( -
- Dashboard -
- - - -
- Total Groups - {MOCK_GROUP_INFO.length} -
-
-
- - - -
- Total Friends - 2999 -
-
-
- - - -
- Total Expenses - {totalExpenses(SORTED_MOCK_EXPENSES)} -
-
-
-
-
- Group Expense Overview - - {groupList} - + + + Alloted Budget: ${group.budget} + + + Expense Amount: ${group.expense} + + + Participants: {group.members} + + + } + footer={ + <> + + + } + /> + ); + }); -
-
- Latest Expenses - { - - } -
-
- ) + return ( +
+ + Dashboard + +
+ + + +
+ + Total Groups + + + {MOCK_GROUP_INFO.length} + +
+
+
+ + + +
+ + Total Friends + + + 2999 + +
+
+
+ + + +
+ + Total Expenses + + + {totalExpenses(SORTED_MOCK_EXPENSES)} + +
+
+
+
+
+ + Group Expense Overview + + {groupList} +
+
+ + Latest Expenses + + {} +
+
+ ); } -export default Dashboard \ No newline at end of file +export default Dashboard; diff --git a/src/pages/ExpenseGroupPage.jsx b/src/pages/ExpenseGroupPage.jsx index 6ee9951..5a25afd 100644 --- a/src/pages/ExpenseGroupPage.jsx +++ b/src/pages/ExpenseGroupPage.jsx @@ -1,57 +1,67 @@ -import { GroupInfoWidget } from "@/components/GroupInfoWidget" -import { useParams } from "react-router-dom" -import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover" -import { Button } from "@/components/ui/button" -import { ChevronDown, Plus, Minus } from "lucide-react" -import { cn, formatCurrency } from "@/lib/utils" -import { useState } from "react" -import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs" -import { Card } from "@/components/ui/card" -import { Badge } from "@/components/ui/badge" -import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar" -import { BodyText } from "@/components/Typography" -import GridCard from "@/components/GridCard" -import { PageGrid } from "@/components/PageGrid" -import { CardAction } from "@/components/CardAction" -import PropTypes from "prop-types" -import { PARTICIPANTS_MOCK_DATA, ParticipantType } from "@/lib/mock-data" -import { ChartPie } from "@/components/ChartPie" -import { ChartBar } from "@/components/ChartBar" -import { ResponsiveDialog } from "@/components/ResponsiveDialog" -import { ParticipantForm } from "@/components/forms/ParticipantForm" -import { GroupDetailsForm } from "@/components/forms/GroupDetailsForm" -import { Alert } from "@/components/Alert" -import { ExpenseForm } from "@/components/forms/ExpenseForm" +import { GroupInfoWidget } from "@/components/GroupInfoWidget"; +import { useParams } from "react-router-dom"; +import { + Popover, + PopoverContent, + PopoverTrigger, +} from "@/components/ui/popover"; +import { Button } from "@/components/ui/button"; +import { ChevronDown, Plus, Minus } from "lucide-react"; +import { cn, formatCurrency } from "@/lib/utils"; +import { useState } from "react"; +import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; +import { Card } from "@/components/ui/card"; +import { Badge } from "@/components/ui/badge"; +import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; +import { BodyText, Heading } from "@/components/Typography"; +import GridCard from "@/components/GridCard"; +import { PageGrid } from "@/components/PageGrid"; +import { CardAction } from "@/components/CardAction"; +import PropTypes from "prop-types"; +import { + EXPENSES_MOCK_DATA, + PARTICIPANTS_MOCK_DATA, + ParticipantType, +} from "@/lib/mock-data"; + +import { ChartPie } from "@/components/ChartPie"; +import { ChartBar } from "@/components/ChartBar"; +import { ResponsiveDialog } from "@/components/ResponsiveDialog"; +import { ParticipantForm } from "@/components/forms/ParticipantForm"; +import { GroupDetailsForm } from "@/components/forms/GroupDetailsForm"; +import { Alert } from "@/components/Alert"; +import { ExpenseForm } from "@/components/forms/ExpenseForm"; +import { ExpensesList } from "@/components/ExpensesList"; export function ExpenseGroupPage() { // TODO remove the bottom disablers after the getting data functionality is done // eslint-disable-next-line no-unused-vars - const { groupId } = useParams() + const { groupId } = useParams(); // eslint-disable-next-line no-unused-vars const [groupInfo, setGroupInfo] = useState({ groupName: "Bali Trip", description: "Lorem ipsum dolor sit amet consectetur.", amount: 5000, - }) + }); // get expense group data by groupId const handleEditAction = () => { - console.log("Edit") - } + console.log("Edit"); + }; const deleteAction = () => { // after deleting the user to be redirected to the dashbord page - console.log("Delete") - } + console.log("Delete"); + }; const exportAction = () => { // export group data as a PDF or JSON - console.log("Export") - } + console.log("Export"); + }; + const handleExpenseSubmit = () => {}; return ( <>

{groupInfo.groupName} Management

- Edit} + trigger={ + Edit + } > - + } /> - - + Balances @@ -118,8 +132,20 @@ export function ExpenseGroupPage() { {/* Temporaly removed, because this tab has a low priority */} {/* Receipts content */} + <> +
+ Expenses + Add Expense} + > + + +
+ + - ) + ); } // TABS CONTENT @@ -134,15 +160,18 @@ const Balances = () => { ))} - ) -} + ); +}; const BalanceCard = ({ participant, className }) => { return (
- + {participant.firstName}
@@ -158,14 +187,16 @@ const BalanceCard = ({ participant, className }) => {
  • - {formatCurrency(Math.abs(300))} to Parker + {formatCurrency(Math.abs(300))}{" "} + to Parker
  • {formatCurrency(Math.abs(403))} from Rosendo
  • - {formatCurrency(Math.abs(1000))} from Emily + {formatCurrency(Math.abs(1000))}{" "} + from Emily
@@ -179,18 +210,18 @@ const BalanceCard = ({ participant, className }) => { - ) -} + ); +}; BalanceCard.propTypes = { participant: ParticipantType, className: PropTypes.string, -} +}; const BalanceBadge = ({ amount }) => { - const isBalancePositive = amount > 0 - const isBalanceNegative = amount < 0 - const isBalanceZero = amount === 0 + const isBalancePositive = amount > 0; + const isBalanceNegative = amount < 0; + const isBalanceZero = amount === 0; return ( {   {isBalanceZero ? amount : formatCurrency(Math.abs(amount))} - ) -} + ); +}; BalanceBadge.propTypes = { amount: PropTypes.number.isRequired, -} +}; const Participants = () => { const handleAddParticipant = (event) => { - event.preventDefault() - console.log("handleAddParticipant: Submit from Participants Tab") - } + event.preventDefault(); + console.log("handleAddParticipant: Submit from Participants Tab"); + }; const handleAddParticipantExpense = (event) => { - event.preventDefault() - console.log("handleAddParticipantExpense: Submit from Participants Tab") - } + event.preventDefault(); + console.log("handleAddParticipantExpense: Submit from Participants Tab"); + }; return (
@@ -234,21 +265,31 @@ const Participants = () => { dialogTitle="Add Participant" trigger={} > - + {PARTICIPANTS_MOCK_DATA.map((participant) => (
  • Add Expense} + trigger={ + + Add Expense + + } > @@ -291,7 +332,9 @@ const Participants = () => { Gets -
    {formatCurrency(500)}
    +
    + {formatCurrency(500)} +
    Owes @@ -307,8 +350,8 @@ const Participants = () => { ))}
  • - ) -} + ); +}; const Statistics = () => { return ( @@ -316,5 +359,5 @@ const Statistics = () => {
    - ) -} + ); +};