diff --git a/txclient/src/app/components/FinancialWidget/FinancialWidget.tsx b/txclient/src/app/components/FinancialWidget/FinancialWidget.tsx index f5f310d..43a9a29 100644 --- a/txclient/src/app/components/FinancialWidget/FinancialWidget.tsx +++ b/txclient/src/app/components/FinancialWidget/FinancialWidget.tsx @@ -1,13 +1,17 @@ "use client"; import React, { useEffect, useState } from "react"; import { LineChart } from "@mui/x-charts/LineChart"; -import { MyOranizationsView } from "@core/Models/Company.model"; -import { DashboardFinancialsResult, getDashboardFinancials } from "../../landing/dashboard/Dashboard.Service"; +import { + DashboardFinancialsResult, + getDashboardFinancials, +} from "../../landing/dashboard/Dashboard.Service"; import { loadCollaboratorsByCompanyId } from "../../admin/(organization-profile)/org/profile/[id]/collaborators/Collaborators.Service"; import { CompanyEmployeesView } from "@models/Collaborators.model"; import UnpaidIncomeCard from "../UnpaidIncomeCard/UnpaidIncomeCard"; import styles from "./FinancialWidget.module.css"; import dayjs from "dayjs"; +import OpenInNewOutlinedIcon from "@mui/icons-material/OpenInNewOutlined"; +import { useNavigation } from "@core/app/hooks/goto"; export interface FinancialWidgetProps { sessionUser: string; @@ -15,11 +19,16 @@ export interface FinancialWidgetProps { organizationName?: string; } -export default function FinancialWidget({ sessionUser, selectedOrgId, organizationName }: FinancialWidgetProps) { +export default function FinancialWidget({ + sessionUser, + selectedOrgId, + organizationName, +}: FinancialWidgetProps) { + const { goTo } = useNavigation(); const [selectedTimeframe, setSelectedTimeframe] = useState<"week" | "month" | "year">("month"); const [selectedEmployeeId, setSelectedEmployeeId] = useState(""); const [collaborators, setCollaborators] = useState([]); - + const [financials, setFinancials] = useState(null); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); @@ -27,10 +36,12 @@ export default function FinancialWidget({ sessionUser, selectedOrgId, organizati useEffect(() => { if (selectedOrgId) { - loadCollaboratorsByCompanyId({ companyId: selectedOrgId }).then((res) => { - setCollaborators(res); - setSelectedEmployeeId(""); // reset employee filter when org changes - }).catch(console.error); + loadCollaboratorsByCompanyId({ companyId: selectedOrgId }) + .then((res) => { + setCollaborators(res); + setSelectedEmployeeId(""); // reset employee filter when org changes + }) + .catch(console.error); } }, [selectedOrgId, sessionUser]); @@ -43,14 +54,17 @@ export default function FinancialWidget({ sessionUser, selectedOrgId, organizati sessionUser, companyId: selectedOrgId, timeframe: selectedTimeframe, - employeeId: selectedEmployeeId || undefined - }).then((res) => { - setFinancials(res); - }).catch((err) => { - const errMsg = err.format ? err.format() : err.message; - console.warn("Acceso denegado a métricas financieras: ", errMsg); - setError("No tienes permisos de administrador para esta organización."); - }).finally(() => setLoading(false)); + employeeId: selectedEmployeeId || undefined, + }) + .then((res) => { + setFinancials(res); + }) + .catch((err) => { + const errMsg = err.format ? err.format() : err.message; + console.warn("Acceso denegado a métricas financieras: ", errMsg); + setError("No tienes permisos de administrador para esta organización."); + }) + .finally(() => setLoading(false)); } }, [selectedOrgId, selectedTimeframe, selectedEmployeeId, sessionUser]); @@ -62,17 +76,24 @@ export default function FinancialWidget({ sessionUser, selectedOrgId, organizati if (!financials) return null; const current = financials.currentPeriodTotal; const previous = financials.previousPeriodTotal; - + if (previous === 0) { - if (current > 0) return +100% vs periodo anterior; + if (current > 0) + return +100% vs periodo anterior; return Sin datos previos; } const diff = current - previous; const percent = (diff / previous) * 100; - - if (percent > 0) return +{percent.toFixed(1)}% vs periodo anterior; - if (percent < 0) return {percent.toFixed(1)}% vs periodo anterior; + + if (percent > 0) + return ( + +{percent.toFixed(1)}% vs periodo anterior + ); + if (percent < 0) + return ( + {percent.toFixed(1)}% vs periodo anterior + ); return 0% vs periodo anterior; }; @@ -81,15 +102,46 @@ export default function FinancialWidget({ sessionUser, selectedOrgId, organizati if (error) { return (
- + {isOpen ? "−" : "+"} +
{isOpen && ( -
-

Acceso Restringido

+
+

+ Acceso Restringido +

{error}

)} @@ -98,67 +150,108 @@ export default function FinancialWidget({ sessionUser, selectedOrgId, organizati } const chartData = financials?.currentPeriodData || []; - const xAxisData = chartData.map(d => { + const xAxisData = chartData.map((d) => { // format label nicer depending on timeframe if (selectedTimeframe === "year") return dayjs(d.date).format("MMM YYYY"); return dayjs(d.date).format("DD/MM"); }); - const seriesData = chartData.map(d => d.amount); - const hasChartData = chartData.some(d => d.amount > 0); + const seriesData = chartData.map((d) => d.amount); + const hasChartData = chartData.some((d) => d.amount > 0); return (
- + {isOpen ? "−" : "+"} +
{isOpen && ( <>
- + - +
-
- Ingresos del Periodo - - {loading ? "..." : formatCurrency(financials?.currentPeriodTotal || 0)} - -
- {!loading && renderComparison()} -
-
- - {financials && ( - - )} +
+ Ingresos del Periodo + + {loading + ? "..." + : formatCurrency(financials?.currentPeriodTotal || 0)} + +
+ {!loading && renderComparison()} +
+
+ + {financials && }
{loading && (
-
+
Cargando datos...
@@ -168,57 +261,68 @@ export default function FinancialWidget({ sessionUser, selectedOrgId, organizati
val ? formatCurrency(val) : "0", + curve: "monotoneX", + valueFormatter: (val: number | null) => + val ? formatCurrency(val) : "0", }, ]} grid={{ horizontal: true }} margin={{ top: 20, bottom: 40, left: 70, right: 20 }} sx={{ - '.MuiLineElement-root': { + ".MuiLineElement-root": { strokeWidth: 3, }, - '.MuiAreaElement-root': { - fill: 'url(#gradient)', + ".MuiAreaElement-root": { + fill: "url(#gradient)", }, - '.MuiChartsGrid-line': { - strokeDasharray: '5 5', - stroke: '#e5e7eb', + ".MuiChartsGrid-line": { + strokeDasharray: "5 5", + stroke: "#e5e7eb", }, - '.MuiChartsAxis-line': { - stroke: 'transparent', + ".MuiChartsAxis-line": { + stroke: "transparent", }, - '.MuiChartsAxis-tick': { - stroke: 'transparent', + ".MuiChartsAxis-tick": { + stroke: "transparent", }, - '.MuiChartsAxis-tickLabel': { - fill: '#9ca3af', - fontFamily: 'inherit', - fontSize: '12px', + ".MuiChartsAxis-tickLabel": { + fill: "#9ca3af", + fontFamily: "inherit", + fontSize: "12px", fontWeight: 500, }, - '.MuiMarkElement-root': { - stroke: 'rgb(36, 169, 53)', + ".MuiMarkElement-root": { + stroke: "rgb(36, 169, 53)", strokeWidth: 2, - fill: '#ffffff', - scale: '1.2', - } + fill: "#ffffff", + scale: "1.2", + }, }} > - - + +