-
-
- {expense?.title}
-
-
- {formatBRL(expense?.partialValue)}
-
-
+ {isLoading ? (
+
Carregando despesas...
+ ) : expenses?.length === 0 ? (
+
Nenhuma despesa encontrada.
+ ) : (
+ <>
+
+
+
+ ))}
+
+
+ {/* 🔄 Controle de Paginação */}
+
+ >
+ )}
);
}
diff --git a/frontend/src/components/forms/ExpenseForm/FormFieldsExpenses/index.jsx b/frontend/src/components/forms/ExpenseForm/FormFieldsExpenses/index.jsx
index 2002618..bb71e76 100644
--- a/frontend/src/components/forms/ExpenseForm/FormFieldsExpenses/index.jsx
+++ b/frontend/src/components/forms/ExpenseForm/FormFieldsExpenses/index.jsx
@@ -1,12 +1,13 @@
-import categories from '../../../../mockData/categories';
import { getCurrentDate } from '../../../../utils/helpers';
import InputUI from '../../../ui/Input';
import SelectUI from '../../../ui/Select';
import TextareaUI from '../../../ui/Textarea';
import CurrencyInputUI from '../../../ui/CurrencyInput';
import { useFormExpense } from '../useForm';
+import { useAllGroupExpenseCategoriesQuery } from '../../../../hooks/ReactQuery/useAllGroupExpenseCategoriesQuery';
-export default function FormFieldsExpenses({ data: members }) {
+export default function FormFieldsExpenses() {
+ const { data: allCategories } = useAllGroupExpenseCategoriesQuery();
const { setAmount } = useFormExpense();
const handleAmountChange = ({ float: numericValue }) => {
@@ -111,7 +112,7 @@ export default function FormFieldsExpenses({ data: members }) {
className="w-full p-2 border border-neutral rounded-md text-text placeholder-muted
focus:outline-none focus:ring-2 focus:ring-primary focus:border-primary transition cursor-pointer"
>
- {categories?.map(({ id, name }) => (
+ {allCategories?.map(({ id, name }) => (
diff --git a/frontend/src/hooks/ReactQuery/useAllGroupExpenseCategoriesQuery.js b/frontend/src/hooks/ReactQuery/useAllGroupExpenseCategoriesQuery.js
new file mode 100644
index 0000000..130ed2e
--- /dev/null
+++ b/frontend/src/hooks/ReactQuery/useAllGroupExpenseCategoriesQuery.js
@@ -0,0 +1,12 @@
+import { useQuery } from '@tanstack/react-query';
+import { REACTQUERY_KEYS } from '../../libs/ReactQuery/keys';
+import { getAllGroupsExpenseCategories } from '../../services/groups';
+
+export function useAllGroupExpenseCategoriesQuery() {
+ return useQuery({
+ queryKey: [REACTQUERY_KEYS.EXPENSES.CATEGORIES],
+ queryFn: getAllGroupsExpenseCategories,
+ staleTime: Infinity,
+ placeholderData: [],
+ });
+}
diff --git a/frontend/src/hooks/ReactQuery/useGroupsQuery.js b/frontend/src/hooks/ReactQuery/useGroupsQuery.js
index adcecc5..a758b09 100644
--- a/frontend/src/hooks/ReactQuery/useGroupsQuery.js
+++ b/frontend/src/hooks/ReactQuery/useGroupsQuery.js
@@ -2,12 +2,16 @@ import { useQuery } from '@tanstack/react-query';
import { REACTQUERY_KEYS } from '../../libs/ReactQuery/keys';
import { getGroupById, getGroups } from '../../services/groups';
-export function useGroupsQuery(page, size) {
+export function useGroupsQuery(page) {
return useQuery({
- queryKey: [REACTQUERY_KEYS.GROUPS.ALL, { page, size }],
- queryFn: async () => await getGroups(page, size),
+ queryKey: [REACTQUERY_KEYS.GROUPS.ALL, { page }],
+ queryFn: async () => await getGroups(page),
staleTime: Infinity,
- placeholderData: { content: [] },
+ placeholderData: {
+ groups: [],
+ totalPages: 0,
+ groupsLength: 0,
+ },
});
}
export function useGroupByIdQuery(id) {
diff --git a/frontend/src/hooks/ReactQuery/useMeExpensesQuery.js b/frontend/src/hooks/ReactQuery/useMeExpensesQuery.js
index b9d9e6f..429d347 100644
--- a/frontend/src/hooks/ReactQuery/useMeExpensesQuery.js
+++ b/frontend/src/hooks/ReactQuery/useMeExpensesQuery.js
@@ -3,12 +3,13 @@ import { REACTQUERY_KEYS } from '../../libs/ReactQuery/keys';
import { getMeExpenses } from '../../services/me';
import useMeQuery from './useMeQuery';
-export default function useMeExpensesQuery() {
+export default function useMeExpensesQuery(page) {
const { data: user } = useMeQuery();
const userId = user?.id;
return useQuery({
- queryKey: [REACTQUERY_KEYS.USER.EXPENSES, userId],
- queryFn: getMeExpenses,
+ queryKey: [REACTQUERY_KEYS.USER.EXPENSES, { userId, page }],
+ queryFn: async () => await getMeExpenses(page),
enabled: !!userId,
+ placeholderData: { expenses: [], totalPages: 0, expensesLength: 0 },
});
}
diff --git a/frontend/src/libs/ReactQuery/keys.js b/frontend/src/libs/ReactQuery/keys.js
index 507340c..e60cfdb 100644
--- a/frontend/src/libs/ReactQuery/keys.js
+++ b/frontend/src/libs/ReactQuery/keys.js
@@ -10,6 +10,9 @@ export const REACTQUERY_KEYS = {
DETAILS: 'groupDetails',
EXPENSES: 'groupExpenses',
},
+ EXPENSES: {
+ CATEGORIES: 'allCategories',
+ },
MEMBERS: {
ALL: 'allMembers',
},
diff --git a/frontend/src/pages/Groups/GroupDetails/ExpensesList.jsx b/frontend/src/pages/Groups/GroupDetails/ExpensesList.jsx
index 496e946..292a985 100644
--- a/frontend/src/pages/Groups/GroupDetails/ExpensesList.jsx
+++ b/frontend/src/pages/Groups/GroupDetails/ExpensesList.jsx
@@ -1,43 +1,179 @@
+import { useState, useMemo } from 'react';
+import { FiSearch } from 'react-icons/fi';
import { formatBRL } from '../../../utils/formatters';
+import InputUI from '../../../components/ui/Input';
+import SelectUI from '../../../components/ui/Select';
+import CheckboxUI from '../../../components/ui/Checkbox';
+import { Link } from 'react-router';
+
+export const expenses = [
+ {
+ id: 1,
+ description: 'Pizza da sexta-feira',
+ amount: 128.5,
+ status: 'PENDING',
+ payerName: 'LunaStar',
+ createdAt: '2025-10-29T20:15:00Z',
+ },
+ {
+ id: 2,
+ description: 'Supermercado do mês',
+ amount: 450.0,
+ status: 'PAID',
+ payerName: 'Clark Kent',
+ createdAt: '2025-10-25T14:45:00Z',
+ },
+ {
+ id: 3,
+ description: 'Assinatura Netflix',
+ amount: 55.9,
+ status: 'PAID',
+ payerName: 'LunaStar',
+ createdAt: '2025-10-20T12:00:00Z',
+ },
+ {
+ id: 4,
+ description: 'Taxi para o evento',
+ amount: 79.75,
+ status: 'PENDING',
+ payerName: 'Clark Kent',
+ createdAt: '2025-10-30T08:30:00Z',
+ },
+ {
+ id: 5,
+ description: 'Jantar no restaurante',
+ amount: 230.0,
+ status: 'PENDING',
+ payerName: 'LunaStar',
+ createdAt: '2025-10-31T22:10:00Z',
+ },
+ {
+ id: 6,
+ description: 'Conta de energia',
+ amount: 189.9,
+ status: 'PAID',
+ payerName: 'Clark Kent',
+ createdAt: '2025-10-28T10:45:00Z',
+ },
+];
export default function ExpensesList({ group }) {
+ const [search, setSearch] = useState('');
+ const [status, setStatus] = useState('ALL');
+ const [allMembers, setAllMembers] = useState(false);
+ const isLoading = false;
+
+ // 💡 Filtro local (mock sem API)
+ const filteredExpenses = useMemo(() => {
+ return expenses.filter(expense => {
+ const matchSearch = expense.description
+ .toLowerCase()
+ .includes(search.toLowerCase());
+ const matchStatus = status === 'ALL' ? true : expense.status === status;
+ const matchMember = allMembers ? true : expense.payerName === 'LunaStar';
+ return matchSearch && matchStatus && matchMember;
+ });
+ }, [search, status, allMembers]);
+
return (
-
- Últimas despesas
-
-
-
- );
-}
-
-function ListExpensesItens({ group }) {
- return (
- <>
- {group.recentExpenses.map(expense => (
-
+
-
- {expense.description}
-
-
- - {formatBRL(expense.amount)}
-
-
- ))}
- {group.recentExpenses.length === 0 && (
-
Nenhuma despesa recente.
+ Despesas do grupo
+
+
+
+ {/* 🔍 Filtros */}
+ Carregando despesas...
+ ) : filteredExpenses.length > 0 ? (
+