From 72915aa6c44627fff6ee2051c5beb78fbebd9562 Mon Sep 17 00:00:00 2001 From: Cosmo Date: Sun, 1 Mar 2026 05:02:23 +0000 Subject: [PATCH] feat: add month switcher to Finance page - fix transactions not showing --- Dockerfile.dev | 13 ++++++ docker-compose.dev.yml | 4 +- src/components/finance/FinanceAnalytics.jsx | 12 ++--- src/components/finance/FinanceDashboard.jsx | 12 ++--- src/components/finance/TransactionList.jsx | 13 +++--- src/pages/Finance.jsx | 50 +++++++++++++++++++-- 6 files changed, 76 insertions(+), 28 deletions(-) create mode 100644 Dockerfile.dev diff --git a/Dockerfile.dev b/Dockerfile.dev new file mode 100644 index 0000000..d5f1ebf --- /dev/null +++ b/Dockerfile.dev @@ -0,0 +1,13 @@ +FROM node:20-alpine AS builder +WORKDIR /app +COPY package*.json ./ +RUN npm install +COPY . . +ENV VITE_API_URL=http://192.168.31.60:8081 +RUN npm run build + +FROM nginx:alpine +COPY --from=builder /app/dist /usr/share/nginx/html +COPY nginx.conf /etc/nginx/conf.d/default.conf +EXPOSE 80 +CMD ["nginx", "-g", "daemon off;"] diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index 2a49885..d2a83ed 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -5,7 +5,9 @@ networks: services: web-dev: - build: . + build: + context: . + dockerfile: Dockerfile.dev container_name: pulse-web-dev restart: always ports: diff --git a/src/components/finance/FinanceAnalytics.jsx b/src/components/finance/FinanceAnalytics.jsx index 8f4c14c..1dc597d 100644 --- a/src/components/finance/FinanceAnalytics.jsx +++ b/src/components/finance/FinanceAnalytics.jsx @@ -18,16 +18,16 @@ const MONTH_NAMES = [ "Июл", "Авг", "Сен", "Окт", "Ноя", "Дек", ] -export default function FinanceAnalytics() { +export default function FinanceAnalytics({ month, year }) { const [analytics, setAnalytics] = useState(null) const [summary, setSummary] = useState(null) const [loading, setLoading] = useState(true) useEffect(() => { - const now = new Date() + setLoading(true) Promise.all([ financeApi.getAnalytics({ months: 6 }), - financeApi.getSummary({ month: now.getMonth() + 1, year: now.getFullYear() }), + financeApi.getSummary({ month, year }), ]) .then(([a, s]) => { setAnalytics(a) @@ -35,7 +35,7 @@ export default function FinanceAnalytics() { }) .catch(console.error) .finally(() => setLoading(false)) - }, []) + }, [month, year]) if (loading) { return ( @@ -72,7 +72,6 @@ export default function FinanceAnalytics() { return (
- {/* Summary cards */}

@@ -97,7 +96,6 @@ export default function FinanceAnalytics() {

- {/* Bar chart */} {barData.length > 0 && (

@@ -131,7 +129,6 @@ export default function FinanceAnalytics() {

)} - {/* Donut chart */} {pieData.length > 0 && (

@@ -179,7 +176,6 @@ export default function FinanceAnalytics() {

)} - {/* Monthly trend */} {monthlyData.length > 0 && (

diff --git a/src/components/finance/FinanceDashboard.jsx b/src/components/finance/FinanceDashboard.jsx index 8b711be..cae0c32 100644 --- a/src/components/finance/FinanceDashboard.jsx +++ b/src/components/finance/FinanceDashboard.jsx @@ -12,18 +12,18 @@ const COLORS = [ const fmt = (n) => Number(n).toLocaleString("ru-RU") + " ₽" -export default function FinanceDashboard() { +export default function FinanceDashboard({ month, year }) { const [summary, setSummary] = useState(null) const [loading, setLoading] = useState(true) useEffect(() => { - const now = new Date() + setLoading(true) financeApi - .getSummary({ month: now.getMonth() + 1, year: now.getFullYear() }) + .getSummary({ month, year }) .then(setSummary) .catch(console.error) .finally(() => setLoading(false)) - }, []) + }, [month, year]) if (loading) { return ( @@ -63,7 +63,6 @@ export default function FinanceDashboard() { return (
- {/* Balance Card */}

Баланс за месяц

{fmt(summary.balance)}

@@ -83,7 +82,6 @@ export default function FinanceDashboard() {
- {/* Top Categories */} {expenseCategories.length > 0 && (

@@ -120,7 +118,6 @@ export default function FinanceDashboard() {

)} - {/* Donut Chart */} {pieData.length > 0 && (

@@ -168,7 +165,6 @@ export default function FinanceDashboard() {

)} - {/* Daily Line Chart */} {dailyData.length > 0 && (

diff --git a/src/components/finance/TransactionList.jsx b/src/components/finance/TransactionList.jsx index b2f90be..a276ce7 100644 --- a/src/components/finance/TransactionList.jsx +++ b/src/components/finance/TransactionList.jsx @@ -8,7 +8,7 @@ const formatDate = (d) => { return dt.toLocaleDateString("ru-RU", { day: "numeric", month: "long" }) } -export default function TransactionList({ onAdd }) { +export default function TransactionList({ onAdd, month, year }) { const [transactions, setTransactions] = useState([]) const [categories, setCategories] = useState([]) const [loading, setLoading] = useState(true) @@ -17,11 +17,12 @@ export default function TransactionList({ onAdd }) { const [search, setSearch] = useState("") useEffect(() => { + setLoading(true) Promise.all([ financeApi.listCategories(), financeApi.listTransactions({ - month: new Date().getMonth() + 1, - year: new Date().getFullYear(), + month, + year, limit: 100, }), ]) @@ -31,7 +32,7 @@ export default function TransactionList({ onAdd }) { }) .catch(console.error) .finally(() => setLoading(false)) - }, []) + }, [month, year]) const filtered = transactions.filter((t) => { if (filter !== "all" && t.type !== filter) return false @@ -67,7 +68,6 @@ export default function TransactionList({ onAdd }) { return (
- {/* Search */} setSearch(e.target.value)} /> - {/* Type filter */}
{[ ["all", "Все"], @@ -96,7 +95,6 @@ export default function TransactionList({ onAdd }) { ))}
- {/* Category filter */}
- {/* Transaction groups */} {Object.keys(grouped).length === 0 ? (
🔍 diff --git a/src/pages/Finance.jsx b/src/pages/Finance.jsx index e27dd04..6c6aa77 100644 --- a/src/pages/Finance.jsx +++ b/src/pages/Finance.jsx @@ -13,13 +13,32 @@ const tabs = [ { key: "categories", label: "Категории", icon: "🏷️" }, ] +const MONTH_NAMES = [ + "Январь", "Февраль", "Март", "Апрель", "Май", "Июнь", + "Июль", "Август", "Сентябрь", "Октябрь", "Ноябрь", "Декабрь", +] + export default function Finance() { + const now = new Date() const [activeTab, setActiveTab] = useState("dashboard") const [showAdd, setShowAdd] = useState(false) const [refreshKey, setRefreshKey] = useState(0) + const [month, setMonth] = useState(now.getMonth() + 1) + const [year, setYear] = useState(now.getFullYear()) const refresh = () => setRefreshKey((k) => k + 1) + const prevMonth = () => { + if (month === 1) { setMonth(12); setYear(y => y - 1) } + else setMonth(m => m - 1) + } + const nextMonth = () => { + if (month === 12) { setMonth(1); setYear(y => y + 1) } + else setMonth(m => m + 1) + } + + const isCurrentMonth = month === now.getMonth() + 1 && year === now.getFullYear() + return (
@@ -36,6 +55,31 @@ export default function Finance() { +
+ + {/* Month Switcher */} +
+
+ + + +
+
+
{tabs.map((t) => (