Commit d9c2a997 authored by Samuel Tuka's avatar Samuel Tuka
Browse files

added ading new expense

parent a2452dbe
Loading
Loading
Loading
Loading
+10 −8
Original line number Diff line number Diff line
import { useReportPage } from "@/hooks";
import InputSearchField from "../Input/InputSearchField";
import { ExpensesDataType } from "@/models/ExpensesDataType";

type ExpanseHistoryProps = {
  expensesData: ExpensesDataType[];
  filter: string;
  setFilter: (value: string) => void;
};

export const ExpanseHistory = ({ expensesData }: ExpanseHistoryProps) => {
  const { filter, setFilter, filteredExpenses } = useReportPage({
export const ExpanseHistory: React.FC<ExpanseHistoryProps> = ({
  expensesData,
  });
  filter,
  setFilter,
}) => {
  return (
    <>
      <h3 className="font-bold text-xl text-center lg:text-left mb-5">
      <h3 className="font-bold text-xl text-center lg:text-left my-10">
        História výdavkov
      </h3>
      <InputSearchField
@@ -21,8 +23,8 @@ export const ExpanseHistory = ({ expensesData }: ExpanseHistoryProps) => {
        placeholder="Vyhľadať výdavky..."
      />
      <div className="mt-5 sm:grid grid-cols-2">
        {filteredExpenses.length > 0 ? (
          filteredExpenses.map((expense, index) => (
        {expensesData.length > 0 ? (
          expensesData.map((expense, index) => (
            <div key={index} className="p-3 border-b">
              <p className="text-sm">
                {expense.date} - {expense.category}
+18 −17
Original line number Diff line number Diff line
@@ -3,32 +3,33 @@ import Modal from "@/components/Modal/Modal";
import CustomButton from "@/components/Button/CustomButton";
import InputField from "@/components/Input/InputField";
import { Form } from "@/components/ui/form";
import { useHouseholdPage } from "@/hooks";
import { ExpensesDataType } from "@/models/ExpensesDataType";
import { Plus } from "lucide-react";
import { useAddExpense } from "@/hooks/useAddExpense";

type AddExpenseProps = {
  buttomClassName: string;
  onAddExpense: (expense: ExpensesDataType) => void;
  buttonClassName?: string;
};

const AddExpense: React.FC<AddExpenseProps> = ({ buttomClassName }) => {
  const {
    onAddExpenseSubmit,
    expenseForm,
    createModalOpen,
    setCreateModalOpen,
  } = useHouseholdPage();

const AddExpense: React.FC<AddExpenseProps> = ({
  onAddExpense,
  buttonClassName,
}) => {
  const { modalOpen, setModalOpen, expenseForm, onSubmit } = useAddExpense({
    onAddExpense,
  });
  return (
    <Modal
      dialogDescription="Pridať nový výdavok"
      open={createModalOpen}
      onOpenChange={setCreateModalOpen}
      open={modalOpen}
      onOpenChange={setModalOpen}
      trigger={
        <CustomButton
          onClick={() => setCreateModalOpen(true)}
          className={buttomClassName}
          onClick={() => setModalOpen(true)}
          className={buttonClassName}
          tooltip="Pridať výdavok"
          leftIcon={<Plus className="w-4 h-4 mr-2 sm:w-6 sm:h-6" />}
          leftIcon={<Plus className="w-4 h-4 sm:w-6 sm:h-6 mr-2" />}
        >
          Pridať výdavok
        </CustomButton>
@@ -36,7 +37,7 @@ const AddExpense: React.FC<AddExpenseProps> = ({ buttomClassName }) => {
    >
      <Form {...expenseForm}>
        <form
          onSubmit={expenseForm.handleSubmit(onAddExpenseSubmit)}
          onSubmit={expenseForm.handleSubmit(onSubmit)}
          className="flex flex-col gap-5 mt-5"
        >
          <InputField
@@ -64,7 +65,7 @@ const AddExpense: React.FC<AddExpenseProps> = ({ buttomClassName }) => {
            label="Popis"
            placeholder="Zara nohavice"
          />
          <CustomButton>Pridať výdavok</CustomButton>
          <CustomButton>Potvrdiť pridanie výdavku</CustomButton>
        </form>
      </Form>
    </Modal>
+33 −0
Original line number Diff line number Diff line
import { ExpensesDataType } from "@/models/ExpensesDataType";
import { AddExpenseSchema } from "@/validationSchemas";
import { zodResolver } from "@hookform/resolvers/zod";
import { useState } from "react";
import { useForm } from "react-hook-form";
import { z } from "zod";

type AddExpenseProps = {
  onAddExpense: (expense: ExpensesDataType) => void;
};

export const useAddExpense = ({ onAddExpense }: AddExpenseProps) => {
  const [modalOpen, setModalOpen] = useState(false);
  type AddExpenseFormData = z.infer<typeof AddExpenseSchema>;

  const expenseForm = useForm<ExpensesDataType>({
    resolver: zodResolver(AddExpenseSchema),
    defaultValues: {
      date: "",
      category: "",
      amount: 0,
      description: "",
    },
  });

  const onSubmit = (data: AddExpenseFormData) => {
    onAddExpense(data);
    setModalOpen(false);
    expenseForm.reset();
  };

  return { modalOpen, setModalOpen, expenseForm, onSubmit };
};
+20 −8
Original line number Diff line number Diff line
import { monthlySpendingData } from "@/mockData/reportData";
import { useState, useEffect } from "react";
import { ExpensesDataType } from "@/models/ExpensesDataType";
import { useEffect, useState } from "react";

type ReportPageProps = {
  expensesData: ExpensesDataType[];
  initialExpensesData: ExpensesDataType[];
};

export const useReportPage = ({ expensesData }: ReportPageProps) => {
export const useReportPage = ({ initialExpensesData }: ReportPageProps) => {
  const [filter, setFilter] = useState("");
  const [expensesData, setExpensesData] = useState(initialExpensesData);
  const [filteredExpenses, setFilteredExpenses] = useState(expensesData);

  const currentMonth =
    monthlySpendingData.find((data) => data.month === "August")?.amount || 0;
  const currentMonth = expensesData.reduce(
    (total, expense) => total + expense.amount,
    0
  );

  useEffect(() => {
    const handler = setTimeout(() => {
@@ -24,7 +26,17 @@ export const useReportPage = ({ expensesData }: ReportPageProps) => {
    return () => {
      clearTimeout(handler);
    };
  }, [filter]);
  }, [filter, expensesData]);

  const addExpense = (newExpense: ExpensesDataType) => {
    setExpensesData((prevExpenses) => [newExpense, ...prevExpenses]);
  };

  return { filter, setFilter, filteredExpenses, currentMonth };
  return {
    filter,
    setFilter,
    filteredExpenses,
    currentMonth,
    addExpense,
  };
};
+12 −5
Original line number Diff line number Diff line
import React from "react";
import { ExpanseBar } from "@/components/ExpanseBar/ExpanseBar";
import { ExpanseHistory } from "@/components/ExpanseHistory/ExpanseHistory";
import MainContainer from "@/components/Layout/MainContainer";
@@ -7,7 +8,7 @@ import {
  weeklyTotalHousehold,
  yearlyTotalHouseHold,
} from "@/mockData/expenseBarHouseholdData";
import { expensesData } from "@/mockData/reportData";
import { expensesData as initialExpensesData } from "@/mockData/reportData";
import {
  Accordion,
  AccordionContent,
@@ -17,7 +18,9 @@ import {
import AddExpense from "@/components/HouseholdPage/AddExpense";

const HouseholdPage: React.FC = () => {
  const { currentMonth } = useReportPage({ expensesData });
  const { currentMonth, filteredExpenses, addExpense, filter, setFilter } =
    useReportPage({ initialExpensesData });

  return (
    <MainContainer>
      <ExpanseBar
@@ -26,12 +29,12 @@ const HouseholdPage: React.FC = () => {
        yearlyTotal={yearlyTotalHouseHold}
        currentMonth={currentMonth}
      />
      <div className="flex items-center justify-between">
      <div className="flex items-center justify-between mb-5">
        <h3 className="text-lg my-10">
          Domácnosť: <span className="text-2xl font-bold">Schodová 5</span>
        </h3>

        <AddExpense buttomClassName="p-6 sm:p-10" />
        <AddExpense onAddExpense={addExpense} buttonClassName="p-6 sm:p-10" />
      </div>
      <Accordion type="single" collapsible className="mb-15">
        <AccordionItem value="household-members">
@@ -43,7 +46,11 @@ const HouseholdPage: React.FC = () => {
          </AccordionContent>
        </AccordionItem>
      </Accordion>
      <ExpanseHistory expensesData={expensesData} />
      <ExpanseHistory
        expensesData={filteredExpenses}
        filter={filter}
        setFilter={setFilter}
      />
    </MainContainer>
  );
};
Loading