chore: remover seções vazias de mudanças de código
Este commit remove seções vazias de mudanças de código do arquivo de mudanças. Isso ajuda a manter o histórico de mudanças mais limpo e organizado, facilitando a leitura e a compreensão das alterações realizadas no projeto.
This commit is contained in:
@@ -1,9 +1,8 @@
|
||||
"use client";
|
||||
|
||||
import { cn } from "@/lib/utils/ui";
|
||||
|
||||
import type { CalendarEvent } from "@/components/calendario/types";
|
||||
import { EVENT_TYPE_STYLES } from "@/components/calendario/day-cell";
|
||||
import type { CalendarEvent } from "@/components/calendario/types";
|
||||
import { cn } from "@/lib/utils/ui";
|
||||
|
||||
const LEGEND_ITEMS: Array<{
|
||||
type: CalendarEvent["type"];
|
||||
@@ -16,17 +15,12 @@ const LEGEND_ITEMS: Array<{
|
||||
|
||||
export function CalendarLegend() {
|
||||
return (
|
||||
<div className="flex flex-wrap gap-3 rounded-lg border border-border/60 bg-muted/20 px-3 py-2 text-[11px] font-medium text-muted-foreground">
|
||||
<div className="flex flex-wrap gap-3 rounded-sm border border-border/60 bg-muted/20 p-2 text-xs font-medium text-muted-foreground">
|
||||
{LEGEND_ITEMS.map((item) => {
|
||||
const style = EVENT_TYPE_STYLES[item.type];
|
||||
return (
|
||||
<span key={item.type} className="flex items-center gap-2">
|
||||
<span
|
||||
className={cn(
|
||||
"size-2.5 rounded-full border border-black/10 dark:border-white/20",
|
||||
style.dot
|
||||
)}
|
||||
/>
|
||||
<span className={cn("size-3 rounded-full", style.dot)} />
|
||||
{item.label}
|
||||
</span>
|
||||
);
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
"use client";
|
||||
|
||||
import type { CalendarDay, CalendarEvent } from "@/components/calendario/types";
|
||||
import { currencyFormatter } from "@/lib/lancamentos/formatting-helpers";
|
||||
import { cn } from "@/lib/utils/ui";
|
||||
import { RiAddLine } from "@remixicon/react";
|
||||
import type { KeyboardEvent, MouseEvent } from "react";
|
||||
import type { CalendarDay, CalendarEvent } from "@/components/calendario/types";
|
||||
import { currencyFormatter } from "@/lib/lancamentos/formatting-helpers";
|
||||
|
||||
type DayCellProps = {
|
||||
day: CalendarDay;
|
||||
@@ -17,17 +17,18 @@ export const EVENT_TYPE_STYLES: Record<
|
||||
{ wrapper: string; dot: string; accent?: string }
|
||||
> = {
|
||||
lancamento: {
|
||||
wrapper: "bg-cyan-600 text-cyan-50 dark:bg-cyan-500/30 dark:text-cyan-200",
|
||||
dot: "bg-cyan-600",
|
||||
wrapper:
|
||||
"bg-orange-100 text-orange-600 dark:bg-orange-800 dark:text-orange-50",
|
||||
dot: "bg-orange-600",
|
||||
},
|
||||
boleto: {
|
||||
wrapper: "bg-red-600 text-red-50 dark:bg-red-500/30 dark:text-red-200",
|
||||
dot: "bg-red-600",
|
||||
wrapper:
|
||||
"bg-emerald-100 text-emerald-600 dark:bg-emerald-800 dark:text-emerald-50",
|
||||
dot: "bg-emerald-600",
|
||||
},
|
||||
cartao: {
|
||||
wrapper:
|
||||
"bg-violet-600 text-violet-50 dark:bg-violet-500/30 dark:text-violet-200",
|
||||
dot: "bg-violet-600",
|
||||
wrapper: "bg-blue-100 text-blue-600 dark:bg-blue-800 dark:text-blue-50",
|
||||
dot: "bg-blue-600",
|
||||
},
|
||||
};
|
||||
|
||||
@@ -82,11 +83,12 @@ const DayEventPreview = ({ event }: { event: CalendarEvent }) => {
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
"flex w-full items-center justify-between gap-2 rounded p-1 text-xs leading-tight",
|
||||
"flex w-full items-center justify-between gap-2 rounded p-1 text-xs",
|
||||
style.wrapper
|
||||
)}
|
||||
>
|
||||
<div className="flex min-w-0">
|
||||
<div className="flex min-w-0 items-center gap-1">
|
||||
<span className={cn("size-1.5 rounded-full", style.dot)} />
|
||||
<span className="truncate">{label}</span>
|
||||
</div>
|
||||
{complement ? (
|
||||
|
||||
@@ -87,7 +87,7 @@ export function CategoryDetailHeader({
|
||||
<Card className="px-4">
|
||||
<div className="flex flex-col gap-6 lg:flex-row lg:items-center lg:justify-between">
|
||||
<div className="flex items-start gap-3">
|
||||
<span className="flex size-12 items-center justify-center rounded-xl bg-muted border text-primary">
|
||||
<span className="flex size-12 items-center justify-center rounded-xl bg-muted">
|
||||
{IconComponent ? (
|
||||
<IconComponent className="size-6" aria-hidden />
|
||||
) : (
|
||||
|
||||
@@ -19,6 +19,7 @@ import type { ChangelogEntry } from "@/lib/changelog/data";
|
||||
import {
|
||||
getCategoryLabel,
|
||||
groupEntriesByCategory,
|
||||
parseSafariCompatibleDate,
|
||||
} from "@/lib/changelog/utils";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { RiMegaphoneLine } from "@remixicon/react";
|
||||
@@ -115,7 +116,7 @@ export function ChangelogNotification({
|
||||
{entry.title}
|
||||
</p>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
{formatDistanceToNow(new Date(entry.date), {
|
||||
{formatDistanceToNow(parseSafariCompatibleDate(entry.date), {
|
||||
addSuffix: true,
|
||||
locale: ptBR,
|
||||
})}
|
||||
|
||||
@@ -205,7 +205,7 @@ export function CategoryHistoryWidget({ data }: CategoryHistoryWidgetProps) {
|
||||
<CardContent className="space-y-2.5">
|
||||
<div className="space-y-2">
|
||||
{selectedCategoryDetails.length > 0 && (
|
||||
<div className="flex items-start justify-between gap-4">
|
||||
<div className="flex items-start justify-between gap-4 mb-4">
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{selectedCategoryDetails.map((category) => {
|
||||
if (!category) return null;
|
||||
|
||||
@@ -130,7 +130,7 @@ export function InstallmentAnalysisPage({
|
||||
return (
|
||||
<div className="flex flex-col gap-4">
|
||||
{/* Card de resumo principal */}
|
||||
<Card className="border-primary/20 bg-primary/5">
|
||||
<Card className="border-none bg-primary/15">
|
||||
<CardContent className="flex flex-col items-start justify-center gap-2 py-2">
|
||||
<p className="text-sm font-medium text-muted-foreground">
|
||||
Se você pagar tudo que está selecionado:
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
CardTitle,
|
||||
} from "@/components/ui/card";
|
||||
import type { DashboardCardMetrics } from "@/lib/dashboard/metrics";
|
||||
import { title_font } from "@/public/fonts/font_index";
|
||||
import {
|
||||
RiArrowDownLine,
|
||||
RiArrowUpLine,
|
||||
@@ -15,7 +16,6 @@ import {
|
||||
RiSubtractLine,
|
||||
} from "@remixicon/react";
|
||||
import MoneyValues from "../money-values";
|
||||
import { title_font } from "@/public/fonts/font_index";
|
||||
|
||||
type SectionCardsProps = {
|
||||
metrics: DashboardCardMetrics;
|
||||
@@ -73,7 +73,7 @@ export function SectionCards({ metrics }: SectionCardsProps) {
|
||||
<Card key={label} className="@container/card gap-2">
|
||||
<CardHeader>
|
||||
<CardTitle className="flex items-center gap-1">
|
||||
<Icon className="size-4" />
|
||||
<Icon className="size-4 text-primary" />
|
||||
{label}
|
||||
</CardTitle>
|
||||
<MoneyValues className="text-2xl" amount={metric.current} />
|
||||
@@ -84,9 +84,9 @@ export function SectionCards({ metrics }: SectionCardsProps) {
|
||||
</Badge>
|
||||
</CardAction>
|
||||
</CardHeader>
|
||||
<CardFooter className="flex-col items-start gap-1.5 text-sm">
|
||||
<div className="line-clamp-1 flex gap-2 text-sm">
|
||||
Mês anterior:
|
||||
<CardFooter className="flex-col items-start gap-2 text-sm">
|
||||
<div className="line-clamp-1 flex gap-2 text-xs">
|
||||
Mês anterior
|
||||
</div>
|
||||
<div className="text-muted-foreground">
|
||||
<MoneyValues amount={metric.previous} />
|
||||
|
||||
@@ -1,25 +1,30 @@
|
||||
"use client";
|
||||
|
||||
import {
|
||||
deleteSavedInsightsAction,
|
||||
generateInsightsAction,
|
||||
loadSavedInsightsAction,
|
||||
saveInsightsAction,
|
||||
deleteSavedInsightsAction,
|
||||
} from "@/app/(dashboard)/insights/actions";
|
||||
import { DEFAULT_MODEL } from "@/app/(dashboard)/insights/data";
|
||||
import { Alert, AlertDescription } from "@/components/ui/alert";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Card, CardContent, CardHeader } from "@/components/ui/card";
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
import { Alert, AlertDescription } from "@/components/ui/alert";
|
||||
import type { InsightsResponse } from "@/lib/schemas/insights";
|
||||
import { RiDeleteBinLine, RiSaveLine, RiSparklingLine, RiAlertLine } from "@remixicon/react";
|
||||
import {
|
||||
RiAlertLine,
|
||||
RiDeleteBinLine,
|
||||
RiSaveLine,
|
||||
RiSparklingLine,
|
||||
} from "@remixicon/react";
|
||||
import { format } from "date-fns";
|
||||
import { ptBR } from "date-fns/locale";
|
||||
import { useEffect, useState, useTransition } from "react";
|
||||
import { toast } from "sonner";
|
||||
import { EmptyState } from "../empty-state";
|
||||
import { InsightsGrid } from "./insights-grid";
|
||||
import { ModelSelector } from "./model-selector";
|
||||
import { format } from "date-fns";
|
||||
import { ptBR } from "date-fns/locale";
|
||||
|
||||
interface InsightsPageProps {
|
||||
period: string;
|
||||
@@ -129,11 +134,14 @@ export function InsightsPage({ period, onAnalyze }: InsightsPageProps) {
|
||||
return (
|
||||
<div className="flex flex-col gap-6">
|
||||
{/* Privacy Warning */}
|
||||
<Alert>
|
||||
<Alert className="border-none">
|
||||
<RiAlertLine className="size-4" />
|
||||
<AlertDescription className="text-sm">
|
||||
<strong>Aviso de privacidade:</strong> Ao gerar insights, seus dados financeiros serão enviados para o provedor de IA selecionado
|
||||
(Anthropic, OpenAI, Google ou OpenRouter) para processamento. Certifique-se de que você confia no provedor escolhido antes de prosseguir.
|
||||
<strong>Aviso de privacidade:</strong> Ao gerar insights, seus dados
|
||||
financeiros serão enviados para o provedor de IA selecionado
|
||||
(Anthropic, OpenAI, Google ou OpenRouter) para processamento.
|
||||
Certifique-se de que você confia no provedor escolhido antes de
|
||||
prosseguir.
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
|
||||
|
||||
@@ -30,7 +30,6 @@ import { createMonthOptions } from "@/lib/utils/period";
|
||||
import { RiAddLine, RiDeleteBinLine } from "@remixicon/react";
|
||||
import { useMemo, useState } from "react";
|
||||
import { toast } from "sonner";
|
||||
import { EstabelecimentoInput } from "../shared/estabelecimento-input";
|
||||
import type { SelectOption } from "../../types";
|
||||
import {
|
||||
CategoriaSelectContent,
|
||||
@@ -40,6 +39,7 @@ import {
|
||||
PaymentMethodSelectContent,
|
||||
TransactionTypeSelectContent,
|
||||
} from "../select-items";
|
||||
import { EstabelecimentoInput } from "../shared/estabelecimento-input";
|
||||
|
||||
interface MassAddDialogProps {
|
||||
open: boolean;
|
||||
@@ -57,7 +57,6 @@ interface MassAddDialogProps {
|
||||
export interface MassAddFormData {
|
||||
fixedFields: {
|
||||
transactionType?: string;
|
||||
pagadorId?: string;
|
||||
paymentMethod?: string;
|
||||
condition?: string;
|
||||
period?: string;
|
||||
@@ -69,6 +68,7 @@ export interface MassAddFormData {
|
||||
name: string;
|
||||
amount: string;
|
||||
categoriaId?: string;
|
||||
pagadorId?: string;
|
||||
}>;
|
||||
}
|
||||
|
||||
@@ -78,6 +78,7 @@ interface TransactionRow {
|
||||
name: string;
|
||||
amount: string;
|
||||
categoriaId: string | undefined;
|
||||
pagadorId: string | undefined;
|
||||
}
|
||||
|
||||
export function MassAddDialog({
|
||||
@@ -96,9 +97,6 @@ export function MassAddDialog({
|
||||
|
||||
// Fixed fields state (sempre ativos, sem checkboxes)
|
||||
const [transactionType, setTransactionType] = useState<string>("Despesa");
|
||||
const [pagadorId, setPagadorId] = useState<string | undefined>(
|
||||
defaultPagadorId ?? undefined
|
||||
);
|
||||
const [paymentMethod, setPaymentMethod] = useState<string>(
|
||||
LANCAMENTO_PAYMENT_METHODS[0]
|
||||
);
|
||||
@@ -115,6 +113,7 @@ export function MassAddDialog({
|
||||
name: "",
|
||||
amount: "",
|
||||
categoriaId: undefined,
|
||||
pagadorId: defaultPagadorId ?? undefined,
|
||||
},
|
||||
]);
|
||||
|
||||
@@ -141,6 +140,7 @@ export function MassAddDialog({
|
||||
name: "",
|
||||
amount: "",
|
||||
categoriaId: undefined,
|
||||
pagadorId: defaultPagadorId ?? undefined,
|
||||
},
|
||||
]);
|
||||
};
|
||||
@@ -191,7 +191,6 @@ export function MassAddDialog({
|
||||
const formData: MassAddFormData = {
|
||||
fixedFields: {
|
||||
transactionType,
|
||||
pagadorId,
|
||||
paymentMethod,
|
||||
condition,
|
||||
period,
|
||||
@@ -203,6 +202,7 @@ export function MassAddDialog({
|
||||
name: t.name.trim(),
|
||||
amount: t.amount.trim(),
|
||||
categoriaId: t.categoriaId,
|
||||
pagadorId: t.pagadorId,
|
||||
})),
|
||||
};
|
||||
|
||||
@@ -212,7 +212,6 @@ export function MassAddDialog({
|
||||
onOpenChange(false);
|
||||
// Reset form
|
||||
setTransactionType("Despesa");
|
||||
setPagadorId(defaultPagadorId ?? undefined);
|
||||
setPaymentMethod(LANCAMENTO_PAYMENT_METHODS[0]);
|
||||
setCondition("À vista");
|
||||
setPeriod(selectedPeriod);
|
||||
@@ -225,6 +224,7 @@ export function MassAddDialog({
|
||||
name: "",
|
||||
amount: "",
|
||||
categoriaId: undefined,
|
||||
pagadorId: defaultPagadorId ?? undefined,
|
||||
},
|
||||
]);
|
||||
} catch (_error) {
|
||||
@@ -236,7 +236,7 @@ export function MassAddDialog({
|
||||
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||
<DialogContent className="sm:max-w-2xl max-h-[90vh] overflow-y-auto p-6 sm:px-8">
|
||||
<DialogContent className="sm:max-w-3xl max-h-[90vh] overflow-y-auto p-6 sm:px-8">
|
||||
<DialogHeader>
|
||||
<DialogTitle>Adicionar múltiplos lançamentos</DialogTitle>
|
||||
<DialogDescription>
|
||||
@@ -248,7 +248,7 @@ export function MassAddDialog({
|
||||
{/* Fixed Fields Section */}
|
||||
<div className="space-y-4">
|
||||
<h3 className="text-sm font-semibold">Valores Padrão</h3>
|
||||
<div className="grid gap-3 sm:grid-cols-2 lg:grid-cols-3">
|
||||
<div className="grid gap-3 sm:grid-cols-2 lg:grid-cols-5">
|
||||
{/* Transaction Type */}
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="transaction-type">Tipo de Transação</Label>
|
||||
@@ -274,39 +274,6 @@ export function MassAddDialog({
|
||||
</Select>
|
||||
</div>
|
||||
|
||||
{/* Pagador */}
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="pagador">Pagador</Label>
|
||||
<Select value={pagadorId} onValueChange={setPagadorId}>
|
||||
<SelectTrigger id="pagador" className="w-full">
|
||||
<SelectValue placeholder="Selecione o pagador">
|
||||
{pagadorId &&
|
||||
(() => {
|
||||
const selectedOption = pagadorOptions.find(
|
||||
(opt) => opt.value === pagadorId
|
||||
);
|
||||
return selectedOption ? (
|
||||
<PagadorSelectContent
|
||||
label={selectedOption.label}
|
||||
avatarUrl={selectedOption.avatarUrl}
|
||||
/>
|
||||
) : null;
|
||||
})()}
|
||||
</SelectValue>
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{pagadorOptions.map((option) => (
|
||||
<SelectItem key={option.value} value={option.value}>
|
||||
<PagadorSelectContent
|
||||
label={option.label}
|
||||
avatarUrl={option.avatarUrl}
|
||||
/>
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
|
||||
{/* Payment Method */}
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="payment-method">Forma de Pagamento</Label>
|
||||
@@ -489,6 +456,7 @@ export function MassAddDialog({
|
||||
)
|
||||
}
|
||||
placeholder="Data"
|
||||
className="w-32 truncate"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
@@ -528,6 +496,52 @@ export function MassAddDialog({
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="w-full">
|
||||
<Label
|
||||
htmlFor={`pagador-${transaction.id}`}
|
||||
className="sr-only"
|
||||
>
|
||||
Pagador {index + 1}
|
||||
</Label>
|
||||
<Select
|
||||
value={transaction.pagadorId}
|
||||
onValueChange={(value) =>
|
||||
updateTransaction(transaction.id, "pagadorId", value)
|
||||
}
|
||||
>
|
||||
<SelectTrigger
|
||||
id={`pagador-${transaction.id}`}
|
||||
className="w-32 truncate"
|
||||
>
|
||||
<SelectValue placeholder="Pagador">
|
||||
{transaction.pagadorId &&
|
||||
(() => {
|
||||
const selectedOption = pagadorOptions.find(
|
||||
(opt) => opt.value === transaction.pagadorId
|
||||
);
|
||||
return selectedOption ? (
|
||||
<PagadorSelectContent
|
||||
label={selectedOption.label}
|
||||
avatarUrl={selectedOption.avatarUrl}
|
||||
/>
|
||||
) : null;
|
||||
})()}
|
||||
</SelectValue>
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{pagadorOptions.map((option) => (
|
||||
<SelectItem key={option.value} value={option.value}>
|
||||
<PagadorSelectContent
|
||||
label={option.label}
|
||||
avatarUrl={option.avatarUrl}
|
||||
/>
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
|
||||
<div className="w-full">
|
||||
<Label
|
||||
htmlFor={`categoria-${transaction.id}`}
|
||||
@@ -547,7 +561,7 @@ export function MassAddDialog({
|
||||
>
|
||||
<SelectTrigger
|
||||
id={`categoria-${transaction.id}`}
|
||||
className="w-42 truncate"
|
||||
className="w-32 truncate"
|
||||
>
|
||||
<SelectValue placeholder="Categoria" />
|
||||
</SelectTrigger>
|
||||
|
||||
@@ -712,17 +712,24 @@ export function LancamentosTable({
|
||||
</Button>
|
||||
) : null}
|
||||
{onMassAdd ? (
|
||||
<Button
|
||||
onClick={onMassAdd}
|
||||
variant="outline"
|
||||
size="icon"
|
||||
className="shrink-0"
|
||||
>
|
||||
<RiAddCircleFill className="size-4" />
|
||||
<span className="sr-only">
|
||||
Adicionar múltiplos lançamentos
|
||||
</span>
|
||||
</Button>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
onClick={onMassAdd}
|
||||
variant="outline"
|
||||
size="icon"
|
||||
className="shrink-0"
|
||||
>
|
||||
<RiAddCircleFill className="size-4" />
|
||||
<span className="sr-only">
|
||||
Adicionar múltiplos lançamentos
|
||||
</span>
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
<p>Adicionar múltiplos lançamentos</p>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
) : null}
|
||||
</div>
|
||||
) : (
|
||||
|
||||
@@ -21,7 +21,7 @@ export function Logo({ variant = "full", className }: LogoProps) {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={cn("flex items-center", className)}>
|
||||
<div className={cn("flex items-center py-4", className)}>
|
||||
<Image
|
||||
src="/logo_small.png"
|
||||
alt="Opensheets"
|
||||
|
||||
@@ -22,7 +22,7 @@ function MoneyValues({ amount, className }: Props) {
|
||||
<span
|
||||
className={cn(
|
||||
money_font.className,
|
||||
"inline-flex items-baseline font-medium transition-all duration-200",
|
||||
"inline-flex items-baseline transition-all duration-200 tracking-tighter",
|
||||
privacyMode &&
|
||||
"blur-[6px] select-none hover:blur-none focus-within:blur-none",
|
||||
className
|
||||
|
||||
@@ -89,7 +89,7 @@ export default function MonthPicker() {
|
||||
|
||||
<div className="flex items-center">
|
||||
<div
|
||||
className="mx-1 space-x-1 capitalize font-medium"
|
||||
className="mx-1 space-x-1 capitalize font-bold"
|
||||
aria-current={!isDifferentFromCurrent ? "date" : undefined}
|
||||
aria-label={`Período selecionado: ${currentMonthLabel} de ${currentYear}`}
|
||||
>
|
||||
|
||||
@@ -51,7 +51,7 @@ export function AppSidebar({
|
||||
<SidebarMenuItem>
|
||||
<SidebarMenuButton
|
||||
asChild
|
||||
className="data-[slot=sidebar-menu-button]:px-1.5! hover:bg-transparent"
|
||||
className="data-[slot=sidebar-menu-button]:px-1.5! hover:bg-transparent active:bg-transparent pt-4 justify-center hover:scale-105 transition-all duration-200"
|
||||
>
|
||||
<a href="/dashboard">
|
||||
<LogoContent />
|
||||
|
||||
@@ -48,6 +48,14 @@ type NavSection = {
|
||||
items: NavItem[];
|
||||
};
|
||||
|
||||
const MONTH_PERIOD_PARAM = "periodo";
|
||||
|
||||
const PERIOD_AWARE_PATHS = new Set([
|
||||
"/dashboard",
|
||||
"/lancamentos",
|
||||
"/orcamentos",
|
||||
]);
|
||||
|
||||
export function NavMain({ sections }: { sections: NavSection[] }) {
|
||||
const pathname = usePathname();
|
||||
const searchParams = useSearchParams();
|
||||
@@ -167,7 +175,7 @@ export function NavMain({ sections }: { sections: NavSection[] }) {
|
||||
src={avatarSrc}
|
||||
alt={`Avatar de ${subItem.title}`}
|
||||
/>
|
||||
<AvatarFallback className="text-[10px] font-medium uppercase">
|
||||
<AvatarFallback className="text-xs font-medium uppercase">
|
||||
{initial}
|
||||
</AvatarFallback>
|
||||
</Avatar>
|
||||
@@ -196,11 +204,3 @@ export function NavMain({ sections }: { sections: NavSection[] }) {
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
const MONTH_PERIOD_PARAM = "periodo";
|
||||
|
||||
const PERIOD_AWARE_PATHS = new Set([
|
||||
"/dashboard",
|
||||
"/lancamentos",
|
||||
"/orcamentos",
|
||||
]);
|
||||
|
||||
@@ -12,10 +12,10 @@ import {
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
} from "@/components/ui/dialog";
|
||||
import { title_font } from "@/public/fonts/font_index";
|
||||
import { RiExpandDiagonalLine } from "@remixicon/react";
|
||||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import { Button } from "./ui/button";
|
||||
import { title_font } from "@/public/fonts/font_index";
|
||||
|
||||
const OVERFLOW_THRESHOLD_PX = 16;
|
||||
const OVERFLOW_CHECK_DEBOUNCE_MS = 100;
|
||||
@@ -82,7 +82,7 @@ export default function WidgetCard({
|
||||
<CardTitle
|
||||
className={`${title_font.className} flex items-center gap-1`}
|
||||
>
|
||||
{icon}
|
||||
<span className="text-primary">{icon}</span>
|
||||
{title}
|
||||
</CardTitle>
|
||||
<CardDescription className="text-muted-foreground text-sm capitalize mt-1">
|
||||
|
||||
Reference in New Issue
Block a user