Skip to content

Commit

Permalink
finalizing the project
Browse files Browse the repository at this point in the history
  • Loading branch information
mtguerson committed May 22, 2024
1 parent e133ccc commit f23d01c
Show file tree
Hide file tree
Showing 20 changed files with 183 additions and 47 deletions.
3 changes: 3 additions & 0 deletions frontend/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:opsz,wght@9..40,400;9..40,500;9..40,600;9..40,700&display=swap" rel="stylesheet" />
<title>fincheck</title>
</head>
<body class="h-full bg-gray-50">
Expand Down
11 changes: 9 additions & 2 deletions frontend/src/app/contexts/AuthContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ import { useQuery, useQueryClient } from "@tanstack/react-query";
import { usersService } from "../services/usersSerice";
import { LaunchScreen } from "../../view/components/LaunchScreen";
import toast from "react-hot-toast";
import { User } from "../entities/User";

interface AuthContextValue {
signedIn: boolean;
user: User | undefined;
signin(accessToken: string): void;
signout(): void;
}
Expand All @@ -22,7 +24,7 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {

const queryClient = useQueryClient();

const { isError, isFetching, isSuccess } = useQuery({
const { isError, isFetching, isSuccess, data } = useQuery({
queryKey: ['users', 'me'],
queryFn: () => usersService.me(),
enabled: signedIn,
Expand Down Expand Up @@ -51,7 +53,12 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {

return (
<AuthContext.Provider
value={{ signedIn: isSuccess && signedIn, signin, signout }}
value={{
signedIn: isSuccess && signedIn,
user: data,
signin,
signout
}}
>
<LaunchScreen isLoading={isFetching} />

Expand Down
4 changes: 4 additions & 0 deletions frontend/src/app/entities/User.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export interface User {
name: string;
email: string;
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { useQuery } from "@tanstack/react-query";
import { bankAccountsService } from "../services/bankAccountsService";
import { bankAccountsService } from "../services/bankAccountsService/delete";

export function useBankAccounts() {
const { data, isFetching } = useQuery({
queryKey: ['bankAccounts'],
queryFn: bankAccountsService.getAll,
staleTime: Infinity,
});

return { accounts: data ?? [], isFetching };
Expand Down
24 changes: 10 additions & 14 deletions frontend/src/app/services/bankAccountsService/delete.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
import { httpClient } from '../httpClient'
import { create } from "./create";
import { remove } from "./remove";
import { getAll } from "./getAll";
import { update } from "./update";

export interface DeleteBankAccountParams {
id: string;
name: string;
initialBalance: number;
color: string;
type: 'CHECKING' | 'INVESTMENT' | 'CASH';
}

export async function remove(bankAccountId: string) {
const { data } = await httpClient.delete(`/bank-accounts/${bankAccountId}`);

return data;
}
export const bankAccountsService = {
create,
getAll,
update,
remove,
};
11 changes: 0 additions & 11 deletions frontend/src/app/services/bankAccountsService/index.ts

This file was deleted.

7 changes: 7 additions & 0 deletions frontend/src/app/services/bankAccountsService/remove.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { httpClient } from '../httpClient'

export async function remove(bankAccountId: string) {
const { data } = await httpClient.delete(`/bank-accounts/${bankAccountId}`);

return data;
}
7 changes: 7 additions & 0 deletions frontend/src/app/services/transactionsService/delete.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { httpClient } from '../httpClient'

export async function remove(transactionId: string) {
const { data } = await httpClient.delete(`/transactions/${transactionId}`);

return data;
}
4 changes: 4 additions & 0 deletions frontend/src/app/services/transactionsService/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import { create } from "./create";
import { remove } from "./delete";
import { getAll } from "./getAll";
import { update } from "./update";

export const transactionsService = {
create,
getAll,
update,
remove
};
20 changes: 20 additions & 0 deletions frontend/src/app/services/transactionsService/update.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { httpClient } from '../httpClient'

export interface UpdateTransactionParams {
id: string;
bankAccountId: string;
categoryId: string;
name: string;
value: number;
date: string;
type: "INCOME" | "EXPENSE";
}

export async function update({
id,
...params
}: UpdateTransactionParams) {
const { data } = await httpClient.put(`/transactions/${id}`, params);

return data;
}
8 changes: 3 additions & 5 deletions frontend/src/app/services/usersSerice/me.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import { User } from "../../entities/User";
import { httpClient } from "../httpClient";

interface meResonse {
name: string;
email: string;
}
type MeResponse = User;

export async function me() {
const { data } = await httpClient.get<meResonse>('/users/me');
const { data } = await httpClient.get<MeResponse>('/users/me');

return data;
}
4 changes: 2 additions & 2 deletions frontend/src/view/components/UserMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ import { DropdownMenu } from "./DropdownMenu";
import { useAuth } from "../../app/hooks/useAuth";

export function UserMenu() {
const { signout } = useAuth();
const { signout, user } = useAuth();
return (
<DropdownMenu.Root>
<DropdownMenu.Trigger>
<div className="bg-teal-50 rounded-full w-12 h-12 flex items-center justify-center border border-teal-100">
<span className="text-sm tracking-[-0.5px] text-teal-900 font-medium">
MG
{user?.name.slice(0, 2).toUpperCase()}
</span>
</div>
</DropdownMenu.Trigger>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useMemo, useState } from "react";
import { useWindowWidth } from "../../../../../app/hooks/useWindowWidth";
import { useDashboard } from "../DashboardContext/useDashboard";
import { useBankAccounts } from "../../../../../app/hooks/useBankAccount";
import { useBankAccounts } from "../../../../../app/hooks/useBankAccounts";

export function UseAccountsController() {
const windowWidth = useWindowWidth();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useState } from "react";
import { useBankAccounts } from "../../../../../../app/hooks/useBankAccount";
import { useBankAccounts } from "../../../../../../app/hooks/useBankAccounts";

export function useFiltersModalController() {
const [selectedBankAccountId, setSelectedBankAccountId] = useState<undefined | string>(undefined);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useDashboard } from "../../components/DashboardContext/useDashboard";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { bankAccountsService } from "../../../../../app/services/bankAccountsService";
import { bankAccountsService } from "../../../../../app/services/bankAccountsService/delete";
import { currencyStringToNumber } from "../../../../../app/utils/currencyStringToNumber";
import toast from "react-hot-toast";
import { useState } from "react";
Expand Down Expand Up @@ -56,7 +56,6 @@ export function useEditAccountModalController() {
mutateAsync: removeAccount,
} = useMutation(bankAccountsService.remove);


const handleSubmit = hookFormSubmit(async (data) => {
try {
await updateAccount({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import { Modal } from "../../../../components/Modal";
import { Select } from "../../../../components/Select";
import { useEditTransactionModalController } from "./useEditTransactionModalController";
import { Transaction } from "../../../../../app/entities/Transaction";
import { ConfirmDeleteModal } from "../../../../components/icons/ConfirmDeleteModal";
import { TrashIcon } from "../../../../components/icons/TrashIcon";

interface EditTransactionModalProps {
transaction: Transaction | null;
Expand All @@ -23,15 +25,36 @@ export function EditTransactionModal({ transaction, open, onClose }: EditTransac
accounts,
categories,
isLoading,
} = useEditTransactionModalController(transaction);
isDeleteModalOpen,
isLoadingDelete,
handleDeleteTransaction,
handleCloseDeleteModal,
handleOpenDeleteModal
} = useEditTransactionModalController(transaction, onClose);

const isExpense = transaction?.type === 'EXPENSE';

if (isDeleteModalOpen) {
return (
<ConfirmDeleteModal
isLoading={isLoadingDelete}
onConfirm={handleDeleteTransaction}
onClose={handleCloseDeleteModal}
title={`Tem certeza que deseja excluir esta ${isExpense ? "despesa" : "receita" }`}
/>
);
}

return (
<Modal
title={isExpense ? 'Editar despesa' : 'Editar Receita'}
open={open}
onClose={onClose}
rightAction={(
<button onClick={handleOpenDeleteModal}>
<TrashIcon className="w-6 h-6 text-red-900" />
</button>
)}
>
<form onSubmit={handleSubmit}>
<div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import { z } from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import { useForm } from "react-hook-form";
import { useBankAccounts } from "../../../../../app/hooks/useBankAccount";
import { useBankAccounts } from "../../../../../app/hooks/useBankAccounts";
import { useCategories } from "../../../../../app/hooks/useCategories";
import { useMemo } from "react";
import { useMemo, useState } from "react";
import { Transaction } from "../../../../../app/entities/Transaction";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { transactionsService } from "../../../../../app/services/transactionsService";
import { currencyStringToNumber } from "../../../../../app/utils/currencyStringToNumber";
import toast from "react-hot-toast";

const schema = z.object({
value: z.union([
Expand All @@ -21,6 +25,7 @@ type FormData = z.infer<typeof schema>;

export function useEditTransactionModalController(
transaction: Transaction | null,
onClose: () => void,
) {

const {
Expand All @@ -41,22 +46,91 @@ export function useEditTransactionModalController(

const { accounts } = useBankAccounts();
const { categories: categoriesList } = useCategories();
const queryClient = useQueryClient();
const {
isLoading,
mutateAsync: updateTransaction
} = useMutation(transactionsService.update);
const {
isLoading: isLoadingDelete,
mutateAsync: removeTransaction,
} = useMutation(transactionsService.remove);

const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);

const handleSubmit = hookFormSubmit(async data => {
console.log(data);
try {
await updateTransaction({
...data,
id: transaction!.id,
type: transaction!.type,
value: currencyStringToNumber(data.value),
date: data.date.toISOString(),
});

queryClient.invalidateQueries({ queryKey: ['transactions'] })
queryClient.invalidateQueries({ queryKey: ['bankAccounts'] })
toast.success(
transaction?.type === "EXPENSE"
? "Despesa editada com sucesso!"
: "Receita editada com sucesso!"
);
onClose();
} catch {
toast.error(
transaction?.type === "EXPENSE"
? "Erro ao salvar a despesa!"
: "Erro ao salvar a receita!"
);
}
});

const categories = useMemo(() => {
return categoriesList.filter(category => category.type === transaction?.type);
}, [categoriesList, transaction]);

async function handleDeleteTransaction() {
try {
await removeTransaction(transaction!.id);

queryClient.invalidateQueries({ queryKey: ['transactions'] });
queryClient.invalidateQueries({ queryKey: ['bankAccounts'] });
toast.success(
transaction?.type === "EXPENSE"
? "A despesa foi deletade com sucesso!"
: "A receita foi deletade com sucesso!"
);
onClose();
} catch {
toast.error(
transaction?.type === "EXPENSE"
? "Erro ao deletar a despesa!"
: "Erro ao deletar a receita!"
);
}
}

function handleOpenDeleteModal() {
setIsDeleteModalOpen(true);
}

function handleCloseDeleteModal() {
setIsDeleteModalOpen(false);
}


return {
register,
control,
errors,
handleSubmit,
accounts,
categories,
isLoading: false,
isLoading,
isDeleteModalOpen,
isLoadingDelete,
handleDeleteTransaction,
handleCloseDeleteModal,
handleOpenDeleteModal
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useDashboard } from '../../components/DashboardContext/useDashboard'
import { useForm } from 'react-hook-form'
import { zodResolver } from '@hookform/resolvers/zod'
import { useMutation, useQueryClient } from '@tanstack/react-query'
import { bankAccountsService } from '../../../../../app/services/bankAccountsService'
import { bankAccountsService } from '../../../../../app/services/bankAccountsService/delete'
import toast from 'react-hot-toast'
import { currencyStringToNumber } from '../../../../../app/utils/currencyStringToNumber'

Expand Down
Loading

0 comments on commit f23d01c

Please sign in to comment.