refactor(core): centraliza hooks, providers e base compartilhada

This commit is contained in:
Felipe Coutinho
2026-03-09 17:11:55 +00:00
parent 2de5101058
commit 3e06a1d056
76 changed files with 3271 additions and 709 deletions

View File

@@ -1,9 +1,9 @@
"use client";
import { useRouter } from "next/navigation";
import { useEffect, useMemo, useTransition } from "react";
import { Card } from "@/components/ui/card";
import { useEffect, useTransition } from "react";
import { getNextPeriod, getPreviousPeriod } from "@/lib/utils/period";
import { Card } from "../ui/card";
import LoadingSpinner from "./loading-spinner";
import NavigationButton from "./nav-button";
import ReturnButton from "./return-button";
@@ -16,23 +16,10 @@ export default function MonthNavigation() {
const router = useRouter();
const [isPending, startTransition] = useTransition();
const currentMonthLabel = useMemo(
() =>
`${currentMonth.charAt(0).toUpperCase()}${currentMonth.slice(1)} ${currentYear}`,
[currentMonth, currentYear],
);
const prevTarget = useMemo(
() => buildHref(getPreviousPeriod(period)),
[buildHref, period],
);
const nextTarget = useMemo(
() => buildHref(getNextPeriod(period)),
[buildHref, period],
);
const returnTarget = useMemo(
() => buildHref(defaultPeriod),
[buildHref, defaultPeriod],
);
const currentMonthLabel = `${currentMonth.charAt(0).toUpperCase()}${currentMonth.slice(1)} ${currentYear}`;
const prevTarget = buildHref(getPreviousPeriod(period));
const nextTarget = buildHref(getNextPeriod(period));
const returnTarget = buildHref(defaultPeriod);
const isDifferentFromCurrent = period !== defaultPeriod;
// Prefetch otimizado: apenas meses adjacentes (M-1, M+1) e mês atual
@@ -55,7 +42,7 @@ export default function MonthNavigation() {
};
return (
<Card className="flex w-full flex-row bg-card text-card-foreground p-4 sticky top-16 z-10">
<Card className="flex w-full flex-row p-4 sticky top-16 z-10 backdrop-blur-sm bg-card/30">
<div className="flex items-center gap-1">
<NavigationButton
direction="left"

View File

@@ -1,13 +1,11 @@
"use client";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import { useCallback, useMemo } from "react";
import { usePathname, useSearchParams } from "next/navigation";
import { useRef } from "react";
import {
formatPeriod,
formatPeriodForUrl,
formatPeriodParam,
MONTH_NAMES,
parsePeriodParam,
} from "@/lib/utils/period";
@@ -16,74 +14,30 @@ const PERIOD_PARAM = "periodo";
export function useMonthPeriod() {
const searchParams = useSearchParams();
const pathname = usePathname();
const router = useRouter();
const periodFromParams = searchParams.get(PERIOD_PARAM);
const referenceDate = useMemo(() => new Date(), []);
const defaultPeriod = useMemo(
() =>
formatPeriod(referenceDate.getFullYear(), referenceDate.getMonth() + 1),
[referenceDate],
const referenceDate = useRef(new Date()).current;
const defaultPeriod = formatPeriod(
referenceDate.getFullYear(),
referenceDate.getMonth() + 1,
);
const { period, monthName, year } = useMemo(
() => parsePeriodParam(periodFromParams, referenceDate),
[periodFromParams, referenceDate],
);
const defaultMonth = useMemo(
() => MONTH_NAMES[referenceDate.getMonth()] ?? "",
[referenceDate],
);
const defaultYear = useMemo(
() => referenceDate.getFullYear().toString(),
[referenceDate],
const { period, monthName, year } = parsePeriodParam(
periodFromParams,
referenceDate,
);
const buildHref = useCallback(
(targetPeriod: string) => {
const params = new URLSearchParams(searchParams.toString());
params.set(PERIOD_PARAM, formatPeriodForUrl(targetPeriod));
const buildHref = (targetPeriod: string) => {
const params = new URLSearchParams(searchParams.toString());
params.set(PERIOD_PARAM, formatPeriodForUrl(targetPeriod));
return `${pathname}?${params.toString()}`;
},
[pathname, searchParams],
);
const buildHrefFromMonth = useCallback(
(month: string, nextYear: string | number) => {
const parsedYear = Number.parseInt(String(nextYear).trim(), 10);
if (Number.isNaN(parsedYear)) {
return buildHref(defaultPeriod);
}
const param = formatPeriodParam(month, parsedYear);
const parsed = parsePeriodParam(param, referenceDate);
return buildHref(parsed.period);
},
[buildHref, defaultPeriod, referenceDate],
);
const replacePeriod = useCallback(
(targetPeriod: string) => {
if (!targetPeriod) {
return;
}
router.replace(buildHref(targetPeriod), { scroll: false });
},
[buildHref, router],
);
return `${pathname}?${params.toString()}`;
};
return {
pathname,
period,
currentMonth: monthName,
currentYear: year.toString(),
defaultPeriod,
defaultMonth,
defaultYear,
buildHref,
buildHrefFromMonth,
replacePeriod,
};
}