From 6a45a5110da9e4a47e5b496da8de422d2ac096a3 Mon Sep 17 00:00:00 2001 From: Felipe Coutinho Date: Sun, 11 Jan 2026 22:44:20 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20implementar=20melhorias=20em=20importa?= =?UTF-8?q?=C3=A7=C3=A3o,=20compartilhamento=20e=20contas=20inativas?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Corrigir cálculo de valor na importação de lançamentos parcelados - Exibir valor total (parcela × quantidade) ao invés do valor da parcela individual - Permite recriar parcelamentos importados com valor correto - Permitir que usuários compartilhados se descompartilhem de pagadores - Adicionar componente PagadorLeaveShareCard na aba Perfil - Usuário filho pode sair do compartilhamento sem precisar do usuário pai - Manter autorização bidirecionada na action de remoção de share - Implementar submenu "Inativos" para contas bancárias - Criar página /contas/inativos seguindo padrão de cartões - Filtrar contas ativas e inativas em páginas separadas - Adicionar ícone e navegação no sidebar --- app/(dashboard)/cartoes/data.ts | 88 +++- app/(dashboard)/cartoes/inativos/page.tsx | 19 + app/(dashboard)/cartoes/layout.tsx | 4 +- app/(dashboard)/contas/data.ts | 79 +++- app/(dashboard)/contas/inativos/page.tsx | 14 + app/(dashboard)/insights/data.ts | 43 +- app/(dashboard)/pagadores/[pagadorId]/data.ts | 59 ++- .../pagadores/[pagadorId]/page.tsx | 24 +- app/(landing-page)/page.tsx | 45 +- components/cartoes/cards-page.tsx | 52 ++- components/contas/accounts-page.tsx | 7 +- .../dashboard/payment-methods-widget.tsx | 4 +- .../lancamentos/table/lancamentos-filters.tsx | 56 ++- .../lancamentos/table/lancamentos-table.tsx | 12 +- .../details/pagador-card-usage-card.tsx | 4 +- .../details/pagador-leave-share-card.tsx | 114 +++++ components/relatorios/category-cell.tsx | 64 +-- .../relatorios/category-report-table.tsx | 18 +- components/sidebar/nav-link.tsx | 22 +- components/sidebar/nav-main.tsx | 4 +- lib/categorias/icons.ts | 2 +- lib/lancamentos/form-helpers.ts | 18 +- lib/lancamentos/page-helpers.ts | 10 +- lib/utils/icons.tsx | 10 +- package.json | 14 +- pnpm-lock.yaml | 431 ++++++++---------- 26 files changed, 812 insertions(+), 405 deletions(-) create mode 100644 app/(dashboard)/cartoes/inativos/page.tsx create mode 100644 app/(dashboard)/contas/inativos/page.tsx create mode 100644 components/pagadores/details/pagador-leave-share-card.tsx diff --git a/app/(dashboard)/cartoes/data.ts b/app/(dashboard)/cartoes/data.ts index 5cc4ce4..9b10a19 100644 --- a/app/(dashboard)/cartoes/data.ts +++ b/app/(dashboard)/cartoes/data.ts @@ -1,7 +1,7 @@ import { cartoes, contas, lancamentos } from "@/db/schema"; import { db } from "@/lib/db"; import { loadLogoOptions } from "@/lib/logo/options"; -import { and, eq, isNull, or, sql } from "drizzle-orm"; +import { and, eq, ilike, isNull, not, or, sql } from "drizzle-orm"; export type CardData = { id: string; @@ -33,7 +33,91 @@ export async function fetchCardsForUser(userId: string): Promise<{ const [cardRows, accountRows, logoOptions, usageRows] = await Promise.all([ db.query.cartoes.findMany({ orderBy: (card: typeof cartoes.$inferSelect, { desc }: { desc: (field: unknown) => unknown }) => [desc(card.name)], - where: eq(cartoes.userId, userId), + where: and(eq(cartoes.userId, userId), not(ilike(cartoes.status, "inativo"))), + with: { + conta: { + columns: { + id: true, + name: true, + }, + }, + }, + }), + db.query.contas.findMany({ + orderBy: (account: typeof contas.$inferSelect, { desc }: { desc: (field: unknown) => unknown }) => [desc(account.name)], + where: eq(contas.userId, userId), + columns: { + id: true, + name: true, + logo: true, + }, + }), + loadLogoOptions(), + db + .select({ + cartaoId: lancamentos.cartaoId, + total: sql`coalesce(sum(${lancamentos.amount}), 0)`, + }) + .from(lancamentos) + .where( + and( + eq(lancamentos.userId, userId), + or(isNull(lancamentos.isSettled), eq(lancamentos.isSettled, false)) + ) + ) + .groupBy(lancamentos.cartaoId), + ]); + + const usageMap = new Map(); + usageRows.forEach((row: { cartaoId: string | null; total: number | null }) => { + if (!row.cartaoId) return; + usageMap.set(row.cartaoId, Number(row.total ?? 0)); + }); + + const cards = cardRows.map((card) => ({ + id: card.id, + name: card.name, + brand: card.brand, + status: card.status, + closingDay: card.closingDay, + dueDay: card.dueDay, + note: card.note, + logo: card.logo, + limit: card.limit ? Number(card.limit) : null, + limitInUse: (() => { + const total = usageMap.get(card.id) ?? 0; + return total < 0 ? Math.abs(total) : 0; + })(), + limitAvailable: (() => { + if (!card.limit) { + return null; + } + const total = usageMap.get(card.id) ?? 0; + const inUse = total < 0 ? Math.abs(total) : 0; + return Math.max(Number(card.limit) - inUse, 0); + })(), + contaId: card.contaId, + contaName: card.conta?.name ?? "Conta não encontrada", + })); + + const accounts = accountRows.map((account) => ({ + id: account.id, + name: account.name, + logo: account.logo, + })); + + return { cards, accounts, logoOptions }; +} + +export async function fetchInativosForUser(userId: string): Promise<{ + cards: CardData[]; + accounts: AccountSimple[]; + logoOptions: LogoOption[]; +}> { + const [cardRows, accountRows, logoOptions, usageRows] = await Promise.all([ + db.query.cartoes.findMany({ + orderBy: (card: typeof cartoes.$inferSelect, { desc }: { desc: (field: unknown) => unknown }) => [desc(card.name)], + where: and(eq(cartoes.userId, userId), ilike(cartoes.status, "inativo")), with: { conta: { columns: { diff --git a/app/(dashboard)/cartoes/inativos/page.tsx b/app/(dashboard)/cartoes/inativos/page.tsx new file mode 100644 index 0000000..da4d4e6 --- /dev/null +++ b/app/(dashboard)/cartoes/inativos/page.tsx @@ -0,0 +1,19 @@ +import { CardsPage } from "@/components/cartoes/cards-page"; +import { getUserId } from "@/lib/auth/server"; +import { fetchInativosForUser } from "../data"; + +export default async function InativosPage() { + const userId = await getUserId(); + const { cards, accounts, logoOptions } = await fetchInativosForUser(userId); + + return ( +
+ +
+ ); +} diff --git a/app/(dashboard)/cartoes/layout.tsx b/app/(dashboard)/cartoes/layout.tsx index 471044c..ef746d4 100644 --- a/app/(dashboard)/cartoes/layout.tsx +++ b/app/(dashboard)/cartoes/layout.tsx @@ -1,5 +1,5 @@ import PageDescription from "@/components/page-description"; -import { RiBankCardLine } from "@remixicon/react"; +import { RiBankCard2Line } from "@remixicon/react"; export const metadata = { title: "Cartões | Opensheets", @@ -13,7 +13,7 @@ export default function RootLayout({ return (
} + icon={} title="Cartões" subtitle="Acompanhe todas os cartões do mês selecionado incluindo faturas, limites e transações previstas. Use o seletor abaixo para navegar pelos meses e diff --git a/app/(dashboard)/contas/data.ts b/app/(dashboard)/contas/data.ts index dae8477..47a2df4 100644 --- a/app/(dashboard)/contas/data.ts +++ b/app/(dashboard)/contas/data.ts @@ -3,7 +3,7 @@ import { INITIAL_BALANCE_NOTE } from "@/lib/accounts/constants"; import { db } from "@/lib/db"; import { loadLogoOptions } from "@/lib/logo/options"; import { PAGADOR_ROLE_ADMIN } from "@/lib/pagadores/constants"; -import { and, eq, sql } from "drizzle-orm"; +import { and, eq, ilike, not, sql } from "drizzle-orm"; export type AccountData = { id: string; @@ -58,6 +58,83 @@ export async function fetchAccountsForUser( .where( and( eq(contas.userId, userId), + not(ilike(contas.status, "inativa")), + sql`(${lancamentos.id} IS NULL OR ${pagadores.role} = ${PAGADOR_ROLE_ADMIN})` + ) + ) + .groupBy( + contas.id, + contas.name, + contas.accountType, + contas.status, + contas.note, + contas.logo, + contas.initialBalance, + contas.excludeFromBalance, + contas.excludeInitialBalanceFromIncome + ), + loadLogoOptions(), + ]); + + const accounts = accountRows.map((account) => ({ + id: account.id, + name: account.name, + accountType: account.accountType, + status: account.status, + note: account.note, + logo: account.logo, + initialBalance: Number(account.initialBalance ?? 0), + balance: + Number(account.initialBalance ?? 0) + + Number(account.balanceMovements ?? 0), + excludeFromBalance: account.excludeFromBalance, + excludeInitialBalanceFromIncome: account.excludeInitialBalanceFromIncome, + })); + + return { accounts, logoOptions }; +} + +export async function fetchInativosForUser( + userId: string +): Promise<{ accounts: AccountData[]; logoOptions: LogoOption[] }> { + const [accountRows, logoOptions] = await Promise.all([ + db + .select({ + id: contas.id, + name: contas.name, + accountType: contas.accountType, + status: contas.status, + note: contas.note, + logo: contas.logo, + initialBalance: contas.initialBalance, + excludeFromBalance: contas.excludeFromBalance, + excludeInitialBalanceFromIncome: contas.excludeInitialBalanceFromIncome, + balanceMovements: sql` + coalesce( + sum( + case + when ${lancamentos.note} = ${INITIAL_BALANCE_NOTE} then 0 + else ${lancamentos.amount} + end + ), + 0 + ) + `, + }) + .from(contas) + .leftJoin( + lancamentos, + and( + eq(lancamentos.contaId, contas.id), + eq(lancamentos.userId, userId), + eq(lancamentos.isSettled, true) + ) + ) + .leftJoin(pagadores, eq(lancamentos.pagadorId, pagadores.id)) + .where( + and( + eq(contas.userId, userId), + ilike(contas.status, "inativa"), sql`(${lancamentos.id} IS NULL OR ${pagadores.role} = ${PAGADOR_ROLE_ADMIN})` ) ) diff --git a/app/(dashboard)/contas/inativos/page.tsx b/app/(dashboard)/contas/inativos/page.tsx new file mode 100644 index 0000000..5419f7e --- /dev/null +++ b/app/(dashboard)/contas/inativos/page.tsx @@ -0,0 +1,14 @@ +import { AccountsPage } from "@/components/contas/accounts-page"; +import { getUserId } from "@/lib/auth/server"; +import { fetchInativosForUser } from "../data"; + +export default async function InativosPage() { + const userId = await getUserId(); + const { accounts, logoOptions } = await fetchInativosForUser(userId); + + return ( +
+ +
+ ); +} diff --git a/app/(dashboard)/insights/data.ts b/app/(dashboard)/insights/data.ts index 2fb6f65..aca0972 100644 --- a/app/(dashboard)/insights/data.ts +++ b/app/(dashboard)/insights/data.ts @@ -33,14 +33,24 @@ export const PROVIDERS = { * Lista de modelos de IA disponíveis para análise de insights */ export const AVAILABLE_MODELS = [ - // OpenAI Models (5) - { id: "gpt-5.1", name: "GPT-5.1 ", provider: "openai" as const }, - { id: "gpt-5.1-chat", name: "GPT-5.1 Chat", provider: "openai" as const }, - { id: "gpt-5", name: "GPT-5", provider: "openai" as const }, - { id: "gpt-5-mini", name: "GPT-5 Mini", provider: "openai" as const }, - { id: "gpt-5-nano", name: "GPT-5 Nano", provider: "openai" as const }, + // OpenAI Models - GPT-5.2 Family (Latest) + { id: "gpt-5.2", name: "GPT-5.2", provider: "openai" as const }, + { + id: "gpt-5.2-instant", + name: "GPT-5.2 Instant", + provider: "openai" as const, + }, + { + id: "gpt-5.2-thinking", + name: "GPT-5.2 Thinking", + provider: "openai" as const, + }, - // Anthropic Models (5) + // OpenAI Models - GPT-5 Family + { id: "gpt-5", name: "GPT-5", provider: "openai" as const }, + { id: "gpt-5-instant", name: "GPT-5 Instant", provider: "openai" as const }, + + // Anthropic Models - Claude 4.5 { id: "claude-4.5-haiku", name: "Claude 4.5 Haiku", @@ -57,20 +67,27 @@ export const AVAILABLE_MODELS = [ provider: "anthropic" as const, }, - // Google Models (5) + // Google Models - Gemini 3 (Latest) { - id: "gemini-2.5-pro", - name: "Gemini 2.5 Pro", + id: "gemini-3-flash-preview", + name: "Gemini 3 Flash", provider: "google" as const, }, { - id: "gemini-2.5-flash", - name: "Gemini 2.5 Flash", + id: "gemini-3-pro-preview", + name: "Gemini 3 Pro", + provider: "google" as const, + }, + + // Google Models - Gemini 2.0 + { + id: "gemini-2.0-flash", + name: "Gemini 2.0 Flash", provider: "google" as const, }, ] as const; -export const DEFAULT_MODEL = "gpt-5.1"; +export const DEFAULT_MODEL = "gpt-5.2"; export const DEFAULT_PROVIDER = "openai"; /** diff --git a/app/(dashboard)/pagadores/[pagadorId]/data.ts b/app/(dashboard)/pagadores/[pagadorId]/data.ts index 44ad5ac..accbbbf 100644 --- a/app/(dashboard)/pagadores/[pagadorId]/data.ts +++ b/app/(dashboard)/pagadores/[pagadorId]/data.ts @@ -1,4 +1,4 @@ -import { lancamentos, pagadorShares, user as usersTable } from "@/db/schema"; +import { lancamentos, pagadorShares, user as usersTable, contas, cartoes, categorias, pagadores } from "@/db/schema"; import { db } from "@/lib/db"; import { and, desc, eq, type SQL } from "drizzle-orm"; @@ -37,17 +37,54 @@ export async function fetchPagadorShares( })); } -export async function fetchPagadorLancamentos(filters: SQL[]) { - const lancamentoRows = await db.query.lancamentos.findMany({ - where: and(...filters), - with: { - pagador: true, - conta: true, - cartao: true, - categoria: true, +export async function fetchCurrentUserShare( + pagadorId: string, + userId: string +): Promise<{ id: string; createdAt: string } | null> { + const shareRow = await db.query.pagadorShares.findFirst({ + columns: { + id: true, + createdAt: true, }, - orderBy: desc(lancamentos.purchaseDate), + where: and( + eq(pagadorShares.pagadorId, pagadorId), + eq(pagadorShares.sharedWithUserId, userId) + ), }); - return lancamentoRows; + if (!shareRow) { + return null; + } + + return { + id: shareRow.id, + createdAt: shareRow.createdAt?.toISOString() ?? new Date().toISOString(), + }; +} + +export async function fetchPagadorLancamentos(filters: SQL[]) { + const lancamentoRows = await db + .select({ + lancamento: lancamentos, + pagador: pagadores, + conta: contas, + cartao: cartoes, + categoria: categorias, + }) + .from(lancamentos) + .leftJoin(pagadores, eq(lancamentos.pagadorId, pagadores.id)) + .leftJoin(contas, eq(lancamentos.contaId, contas.id)) + .leftJoin(cartoes, eq(lancamentos.cartaoId, cartoes.id)) + .leftJoin(categorias, eq(lancamentos.categoriaId, categorias.id)) + .where(and(...filters)) + .orderBy(desc(lancamentos.purchaseDate), desc(lancamentos.createdAt)); + + // Transformar resultado para o formato esperado + return lancamentoRows.map((row: any) => ({ + ...row.lancamento, + pagador: row.pagador, + conta: row.conta, + cartao: row.cartao, + categoria: row.categoria, + })); } diff --git a/app/(dashboard)/pagadores/[pagadorId]/page.tsx b/app/(dashboard)/pagadores/[pagadorId]/page.tsx index e7e2a34..2d587ce 100644 --- a/app/(dashboard)/pagadores/[pagadorId]/page.tsx +++ b/app/(dashboard)/pagadores/[pagadorId]/page.tsx @@ -5,6 +5,7 @@ import { PagadorInfoCard } from "@/components/pagadores/details/pagador-info-car import { PagadorMonthlySummaryCard } from "@/components/pagadores/details/pagador-monthly-summary-card"; import { PagadorBoletoCard } from "@/components/pagadores/details/pagador-payment-method-cards"; import { PagadorSharingCard } from "@/components/pagadores/details/pagador-sharing-card"; +import { PagadorLeaveShareCard } from "@/components/pagadores/details/pagador-leave-share-card"; import { LancamentosPage as LancamentosSection } from "@/components/lancamentos/page/lancamentos-page"; import type { ContaCartaoFilterOption, @@ -39,7 +40,7 @@ import { fetchPagadorMonthlyBreakdown, } from "@/lib/pagadores/details"; import { notFound } from "next/navigation"; -import { fetchPagadorLancamentos, fetchPagadorShares } from "./data"; +import { fetchPagadorLancamentos, fetchPagadorShares, fetchCurrentUserShare } from "./data"; type PageSearchParams = Promise; @@ -92,9 +93,13 @@ export default async function Page({ params, searchParams }: PageProps) { } = parsePeriodParam(periodoParamRaw); const periodLabel = `${capitalize(monthName)} de ${year}`; + const allSearchFilters = extractLancamentoSearchFilters(resolvedSearchParams); const searchFilters = canEdit - ? extractLancamentoSearchFilters(resolvedSearchParams) - : EMPTY_FILTERS; + ? allSearchFilters + : { + ...EMPTY_FILTERS, + searchFilter: allSearchFilters.searchFilter, // Permitir busca mesmo em modo read-only + }; let filterSources: Awaited< ReturnType @@ -133,6 +138,10 @@ export default async function Page({ params, searchParams }: PageProps) { ? fetchPagadorShares(pagador.id) : Promise.resolve([]); + const currentUserSharePromise = !canEdit + ? fetchCurrentUserShare(pagador.id, userId) + : Promise.resolve(null); + const [ lancamentoRows, monthlyBreakdown, @@ -140,6 +149,7 @@ export default async function Page({ params, searchParams }: PageProps) { cardUsage, boletoStats, shareRows, + currentUserShare, estabelecimentos, ] = await Promise.all([ fetchPagadorLancamentos(filters), @@ -164,6 +174,7 @@ export default async function Page({ params, searchParams }: PageProps) { period: selectedPeriod, }), sharesPromise, + currentUserSharePromise, getRecentEstablishmentsAction(), ]); @@ -281,6 +292,13 @@ export default async function Page({ params, searchParams }: PageProps) { shares={pagadorSharesData} /> ) : null} + {!canEdit && currentUserShare ? ( + + ) : null} diff --git a/app/(landing-page)/page.tsx b/app/(landing-page)/page.tsx index 819b4c8..9e1e7d3 100644 --- a/app/(landing-page)/page.tsx +++ b/app/(landing-page)/page.tsx @@ -6,7 +6,7 @@ import { Card, CardContent } from "@/components/ui/card"; import { getOptionalUserSession } from "@/lib/auth/server"; import { RiArrowRightSLine, - RiBankCardLine, + RiBankCard2Line, RiBarChartBoxLine, RiCalendarLine, RiCodeSSlashLine, @@ -15,7 +15,6 @@ import { RiGithubFill, RiLineChartLine, RiLockLine, - RiMoneyDollarCircleLine, RiPieChartLine, RiShieldCheckLine, RiTimeLine, @@ -234,9 +233,9 @@ export default async function Page() { Parcelamentos avançados

- Controle completo de compras parceladas. Antecipe parcelas - com cálculo automático de desconto. Veja análise - consolidada de todas as parcelas em aberto. + Controle completo de compras parceladas. Antecipe + parcelas com cálculo automático de desconto. Veja + análise consolidada de todas as parcelas em aberto.

@@ -254,9 +253,9 @@ export default async function Page() { Insights com IA

- Análises financeiras geradas por IA (Claude, GPT, Gemini). - Insights personalizados sobre seus padrões de gastos e - recomendações inteligentes. + Análises financeiras geradas por IA (Claude, GPT, + Gemini). Insights personalizados sobre seus padrões de + gastos e recomendações inteligentes.

@@ -287,16 +286,16 @@ export default async function Page() {
- +

Faturas de cartão

- Cadastre seus cartões e acompanhe as faturas por período. - Veja o que ainda não foi fechado. Controle limites, - vencimentos e fechamentos. + Cadastre seus cartões e acompanhe as faturas por + período. Veja o que ainda não foi fechado. Controle + limites, vencimentos e fechamentos.

@@ -315,8 +314,8 @@ export default async function Page() {

Compartilhe pagadores com permissões granulares (admin/ - viewer). Notificações automáticas por e-mail. Colabore em - lançamentos compartilhados. + viewer). Notificações automáticas por e-mail. Colabore + em lançamentos compartilhados.

@@ -334,9 +333,9 @@ export default async function Page() { Categorias e orçamentos

- Crie categorias personalizadas. Defina orçamentos mensais - e acompanhe o quanto gastou vs. planejado com indicadores - visuais. + Crie categorias personalizadas. Defina orçamentos + mensais e acompanhe o quanto gastou vs. planejado com + indicadores visuais.

@@ -394,9 +393,9 @@ export default async function Page() { Importação em massa

- Cole múltiplos lançamentos de uma vez. Economize tempo ao - registrar várias transações. Formatação inteligente para - facilitar a entrada de dados. + Cole múltiplos lançamentos de uma vez. Economize tempo + ao registrar várias transações. Formatação inteligente + para facilitar a entrada de dados.

@@ -434,9 +433,9 @@ export default async function Page() { Performance otimizada

- Dashboard carrega em ~200-500ms com 18+ queries paralelas. - Índices otimizados. Type-safe em toda codebase. Isolamento - completo de dados por usuário. + Dashboard carrega em ~200-500ms com 18+ queries + paralelas. Índices otimizados. Type-safe em toda + codebase. Isolamento completo de dados por usuário.

diff --git a/components/cartoes/cards-page.tsx b/components/cartoes/cards-page.tsx index c565242..293e057 100644 --- a/components/cartoes/cards-page.tsx +++ b/components/cartoes/cards-page.tsx @@ -5,7 +5,7 @@ import { ConfirmActionDialog } from "@/components/confirm-action-dialog"; import { EmptyState } from "@/components/empty-state"; import { Button } from "@/components/ui/button"; import { Card } from "@/components/ui/card"; -import { RiAddCircleLine, RiBankCardLine } from "@remixicon/react"; +import { RiAddCircleLine, RiBankCard2Line } from "@remixicon/react"; import { useRouter } from "next/navigation"; import { useCallback, useMemo, useState } from "react"; import { toast } from "sonner"; @@ -21,9 +21,15 @@ interface CardsPageProps { cards: Card[]; accounts: AccountOption[]; logoOptions: string[]; + isInativos?: boolean; } -export function CardsPage({ cards, accounts, logoOptions }: CardsPageProps) { +export function CardsPage({ + cards, + accounts, + logoOptions, + isInativos = false, +}: CardsPageProps) { const router = useRouter(); const [editOpen, setEditOpen] = useState(false); const [selectedCard, setSelectedCard] = useState(null); @@ -102,19 +108,21 @@ export function CardsPage({ cards, accounts, logoOptions }: CardsPageProps) { return ( <>
-
- - - Novo cartão - - } - /> -
+ {!isInativos && ( +
+ + + Novo cartão + + } + /> +
+ )} {hasCards ? (
@@ -141,9 +149,17 @@ export function CardsPage({ cards, accounts, logoOptions }: CardsPageProps) { ) : ( } - title="Nenhum cartão cadastrado" - description="Adicione seu primeiro cartão para acompanhar limites e faturas com mais controle." + media={} + title={ + isInativos + ? "Nenhum cartão inativo" + : "Nenhum cartão cadastrado" + } + description={ + isInativos + ? "Os cartões inativos aparecerão aqui." + : "Adicione seu primeiro cartão para acompanhar limites e faturas com mais controle." + } /> )} diff --git a/components/contas/accounts-page.tsx b/components/contas/accounts-page.tsx index a6dd9b4..718cf50 100644 --- a/components/contas/accounts-page.tsx +++ b/components/contas/accounts-page.tsx @@ -19,6 +19,7 @@ import type { Account } from "./types"; interface AccountsPageProps { accounts: Account[]; logoOptions: string[]; + isInativos?: boolean; } const resolveLogoSrc = (logo: string | null) => { @@ -30,7 +31,7 @@ const resolveLogoSrc = (logo: string | null) => { return `/logos/${fileName}`; }; -export function AccountsPage({ accounts, logoOptions }: AccountsPageProps) { +export function AccountsPage({ accounts, logoOptions, isInativos = false }: AccountsPageProps) { const router = useRouter(); const [editOpen, setEditOpen] = useState(false); const [selectedAccount, setSelectedAccount] = useState(null); @@ -169,8 +170,8 @@ export function AccountsPage({ accounts, logoOptions }: AccountsPageProps) { } - title="Nenhuma conta cadastrada" - description="Cadastre sua primeira conta para começar a organizar os lançamentos." + title={isInativos ? "Nenhuma conta inativa" : "Nenhuma conta cadastrada"} + description={isInativos ? "Não há contas inativas no momento." : "Cadastre sua primeira conta para começar a organizar os lançamentos."} /> )} diff --git a/components/dashboard/payment-methods-widget.tsx b/components/dashboard/payment-methods-widget.tsx index 954dccd..c6c853a 100644 --- a/components/dashboard/payment-methods-widget.tsx +++ b/components/dashboard/payment-methods-widget.tsx @@ -1,7 +1,7 @@ import MoneyValues from "@/components/money-values"; import type { PaymentMethodsData } from "@/lib/dashboard/payments/payment-methods"; import { getPaymentMethodIcon } from "@/lib/utils/icons"; -import { RiBankCardLine, RiMoneyDollarCircleLine } from "@remixicon/react"; +import { RiBankCard2Line, RiMoneyDollarCircleLine } from "@remixicon/react"; import { Progress } from "../ui/progress"; import { WidgetEmptyState } from "../widget-empty-state"; @@ -28,7 +28,7 @@ const resolveIcon = (paymentMethod: string | null | undefined) => { return icon; } - return ; + return ; }; export function PaymentMethodsWidget({ data }: PaymentMethodsWidgetProps) { diff --git a/components/lancamentos/table/lancamentos-filters.tsx b/components/lancamentos/table/lancamentos-filters.tsx index 3a11527..86b262e 100644 --- a/components/lancamentos/table/lancamentos-filters.tsx +++ b/components/lancamentos/table/lancamentos-filters.tsx @@ -130,6 +130,7 @@ interface LancamentosFiltersProps { contaCartaoOptions: ContaCartaoFilterOption[]; className?: string; exportButton?: ReactNode; + hideAdvancedFilters?: boolean; } export function LancamentosFilters({ @@ -138,6 +139,7 @@ export function LancamentosFilters({ contaCartaoOptions, className, exportButton, + hideAdvancedFilters = false, }: LancamentosFiltersProps) { const router = useRouter(); const pathname = usePathname(); @@ -277,22 +279,31 @@ export function LancamentosFilters({ return (
+ setSearchValue(event.target.value)} + placeholder="Buscar" + aria-label="Buscar lançamentos" + className="w-[250px] text-sm border-dashed" + /> + {exportButton} - - - - + {!hideAdvancedFilters && ( + + + + Filtros @@ -319,7 +330,9 @@ export function LancamentosFilters({
- +
- + - - - setSearchValue(event.target.value)} - placeholder="Buscar" - aria-label="Buscar lançamentos" - className="w-[250px] text-sm border-dashed" - /> + + )}
); } diff --git a/components/lancamentos/table/lancamentos-table.tsx b/components/lancamentos/table/lancamentos-table.tsx index 7c02786..a63e436 100644 --- a/components/lancamentos/table/lancamentos-table.tsx +++ b/components/lancamentos/table/lancamentos-table.tsx @@ -734,9 +734,8 @@ export function LancamentosTable({ 0 ); - // Check if all data belongs to current user to determine if filters should be shown - const isOwnData = data.every((item) => item.userId === currentUserId); - const shouldShowFilters = showFilters && isOwnData; + // Check if there's any data from other users + const hasOtherUserData = data.some((item) => item.userId !== currentUserId); const handleBulkDelete = () => { if (onBulkDelete && selectedCount > 0) { @@ -755,7 +754,7 @@ export function LancamentosTable({ }; const showTopControls = - Boolean(onCreate) || Boolean(onMassAdd) || shouldShowFilters; + Boolean(onCreate) || Boolean(onMassAdd) || showFilters; return ( @@ -791,15 +790,16 @@ export function LancamentosTable({ ) : null}
) : ( - + )} - {shouldShowFilters ? ( + {showFilters ? ( { @@ -36,7 +36,7 @@ export function PagadorCardUsageCard({ items }: PagadorCardUsageCardProps) { {items.length === 0 ? ( } + icon={} title="Nenhum lançamento com cartão de crédito" description="Quando houver despesas registradas com cartão, elas aparecerão aqui." /> diff --git a/components/pagadores/details/pagador-leave-share-card.tsx b/components/pagadores/details/pagador-leave-share-card.tsx new file mode 100644 index 0000000..e0c3dc7 --- /dev/null +++ b/components/pagadores/details/pagador-leave-share-card.tsx @@ -0,0 +1,114 @@ +"use client"; + +import { deletePagadorShareAction } from "@/app/(dashboard)/pagadores/actions"; +import { Button } from "@/components/ui/button"; +import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; +import { RiLogoutBoxLine } from "@remixicon/react"; +import { useRouter } from "next/navigation"; +import { useState, useTransition } from "react"; +import { toast } from "sonner"; + +interface PagadorLeaveShareCardProps { + shareId: string; + pagadorName: string; + createdAt: string; +} + +export function PagadorLeaveShareCard({ + shareId, + pagadorName, + createdAt, +}: PagadorLeaveShareCardProps) { + const router = useRouter(); + const [isPending, startTransition] = useTransition(); + const [showConfirm, setShowConfirm] = useState(false); + + const handleLeave = () => { + startTransition(async () => { + const result = await deletePagadorShareAction({ shareId }); + + if (!result.success) { + toast.error(result.error); + return; + } + + toast.success("Você saiu do compartilhamento."); + router.push("/pagadores"); + }); + }; + + const formattedDate = new Date(createdAt).toLocaleDateString("pt-BR", { + day: "2-digit", + month: "long", + year: "numeric", + }); + + return ( + + + + Acesso Compartilhado + +

+ Você tem acesso somente leitura aos dados de{" "} + {pagadorName}. +

+
+ +
+ + Informações do compartilhamento + +
+

+ Acesso desde:{" "} + {formattedDate} +

+

+ Você pode visualizar os lançamentos, mas não pode criar ou editar. +

+
+
+ + {!showConfirm ? ( + + ) : ( +
+

+ Tem certeza que deseja sair? Você perderá o acesso aos dados de{" "} + {pagadorName}. +

+
+ + +
+
+ )} +
+
+ ); +} diff --git a/components/relatorios/category-cell.tsx b/components/relatorios/category-cell.tsx index 957e850..3f53954 100644 --- a/components/relatorios/category-cell.tsx +++ b/components/relatorios/category-cell.tsx @@ -1,46 +1,46 @@ "use client"; import { formatCurrency, formatPercentageChange } from "@/lib/relatorios/utils"; -import { RiArrowDownLine, RiArrowUpLine } from "@remixicon/react"; import { cn } from "@/lib/utils/ui"; +import { RiArrowDownLine, RiArrowUpLine } from "@remixicon/react"; interface CategoryCellProps { - value: number; - previousValue: number; - categoryType: "despesa" | "receita"; - isFirstMonth: boolean; + value: number; + previousValue: number; + categoryType: "despesa" | "receita"; + isFirstMonth: boolean; } export function CategoryCell({ - value, - previousValue, - categoryType, - isFirstMonth, + value, + previousValue, + categoryType, + isFirstMonth, }: CategoryCellProps) { - const percentageChange = - !isFirstMonth && previousValue !== 0 - ? ((value - previousValue) / previousValue) * 100 - : null; + const percentageChange = + !isFirstMonth && previousValue !== 0 + ? ((value - previousValue) / previousValue) * 100 + : null; - const isIncrease = percentageChange !== null && percentageChange > 0; - const isDecrease = percentageChange !== null && percentageChange < 0; + const isIncrease = percentageChange !== null && percentageChange > 0; + const isDecrease = percentageChange !== null && percentageChange < 0; - return ( -
- {formatCurrency(value)} - {!isFirstMonth && percentageChange !== null && ( -
- {isIncrease && } - {isDecrease && } - {formatPercentageChange(percentageChange)} -
- )} + return ( +
+ {formatCurrency(value)} + {!isFirstMonth && percentageChange !== null && ( +
+ {isIncrease && } + {isDecrease && } + {formatPercentageChange(percentageChange)}
- ); + )} +
+ ); } diff --git a/components/relatorios/category-report-table.tsx b/components/relatorios/category-report-table.tsx index 0a9ee21..f704717 100644 --- a/components/relatorios/category-report-table.tsx +++ b/components/relatorios/category-report-table.tsx @@ -9,13 +9,12 @@ import { TableHeader, TableRow, } from "@/components/ui/table"; -import { getIconComponent } from "@/lib/utils/icons"; -import { formatPeriodLabel } from "@/lib/relatorios/utils"; import type { CategoryReportData } from "@/lib/relatorios/types"; -import { CategoryCell } from "./category-cell"; -import { formatCurrency } from "@/lib/relatorios/utils"; -import { Card } from "../ui/card"; +import { formatCurrency, formatPeriodLabel } from "@/lib/relatorios/utils"; +import { getIconComponent } from "@/lib/utils/icons"; import DotIcon from "../dot-icon"; +import { Card } from "../ui/card"; +import { CategoryCell } from "./category-cell"; interface CategoryReportTableProps { data: CategoryReportData; @@ -88,16 +87,19 @@ export function CategoryReportTable({ data }: CategoryReportTableProps) { - Total Geral + Total Geral {periods.map((period) => { const periodTotal = totals.get(period) ?? 0; return ( - + {formatCurrency(periodTotal)} ); })} - + {formatCurrency(grandTotal)} diff --git a/components/sidebar/nav-link.tsx b/components/sidebar/nav-link.tsx index daba35b..01ef6bb 100644 --- a/components/sidebar/nav-link.tsx +++ b/components/sidebar/nav-link.tsx @@ -1,17 +1,19 @@ import { RiArchiveLine, RiArrowLeftRightLine, - RiBankCardLine, + RiBankCard2Line, RiBankLine, RiCalendarEventLine, RiDashboardLine, RiFileChartLine, RiFundsLine, RiGroupLine, + RiNoCreditCardLine, RiPriceTag3Line, RiSettingsLine, RiSparklingLine, RiTodoLine, + RiEyeOffLine, type RemixiconComponentType, } from "@remixicon/react"; @@ -98,12 +100,28 @@ export function createSidebarNavData(pagadores: PagadorLike[]): SidebarNavData { { title: "Cartões", url: "/cartoes", - icon: RiBankCardLine, + icon: RiBankCard2Line, + items: [ + { + title: "Inativos", + url: "/cartoes/inativos", + key: "cartoes-inativos", + icon: RiNoCreditCardLine, + }, + ], }, { title: "Contas", url: "/contas", icon: RiBankLine, + items: [ + { + title: "Inativas", + url: "/contas/inativos", + key: "contas-inativos", + icon: RiEyeOffLine, + }, + ], }, { title: "Orçamentos", diff --git a/components/sidebar/nav-main.tsx b/components/sidebar/nav-main.tsx index 7ac2f5b..7e26e25 100644 --- a/components/sidebar/nav-main.tsx +++ b/components/sidebar/nav-main.tsx @@ -21,7 +21,7 @@ import { import { getAvatarSrc } from "@/lib/pagadores/utils"; import { RiArrowRightSLine, - RiStackshareLine, + RiUserSharedLine, type RemixiconComponentType, } from "@remixicon/react"; import Link from "next/link"; @@ -182,7 +182,7 @@ export function NavMain({ sections }: { sections: NavSection[] }) { ) : null} {subItem.title} {subItem.isShared ? ( - + ) : null} diff --git a/lib/categorias/icons.ts b/lib/categorias/icons.ts index 64eda2c..50a93c3 100644 --- a/lib/categorias/icons.ts +++ b/lib/categorias/icons.ts @@ -15,7 +15,7 @@ export const CATEGORY_ICON_OPTIONS: CategoryIconOption[] = [ { label: "Dinheiro", value: "RiMoneyDollarCircleLine" }, { label: "Carteira", value: "RiWallet3Line" }, { label: "Carteira 2", value: "RiWalletLine" }, - { label: "Cartão", value: "RiBankCardLine" }, + { label: "Cartão", value: "RiBankCard2Line" }, { label: "Banco", value: "RiBankLine" }, { label: "Moedas", value: "RiHandCoinLine" }, { label: "Gráfico", value: "RiLineChartLine" }, diff --git a/lib/lancamentos/form-helpers.ts b/lib/lancamentos/form-helpers.ts index 190f36b..75e60b6 100644 --- a/lib/lancamentos/form-helpers.ts +++ b/lib/lancamentos/form-helpers.ts @@ -78,6 +78,19 @@ export function buildLancamentoInitialState( ? getTodayDateString() : ""); + // Calcular o valor correto para importação de parcelados + let amountValue = ""; + if (typeof lancamento?.amount === "number") { + let baseAmount = Math.abs(lancamento.amount); + + // Se está importando e é parcelado, usar o valor total (parcela * quantidade) + if (isImporting && lancamento.condition === "Parcelado" && lancamento.installmentCount) { + baseAmount = baseAmount * lancamento.installmentCount; + } + + amountValue = (Math.round(baseAmount * 100) / 100).toFixed(2); + } + return { purchaseDate, period: @@ -87,10 +100,7 @@ export function buildLancamentoInitialState( name: lancamento?.name ?? "", transactionType: lancamento?.transactionType ?? LANCAMENTO_TRANSACTION_TYPES[0], - amount: - typeof lancamento?.amount === "number" - ? (Math.round(Math.abs(lancamento.amount) * 100) / 100).toFixed(2) - : "", + amount: amountValue, condition: lancamento?.condition ?? LANCAMENTO_CONDITIONS[0], paymentMethod, pagadorId: fallbackPagadorId ?? undefined, diff --git a/lib/lancamentos/page-helpers.ts b/lib/lancamentos/page-helpers.ts index 5072c5c..ede8d45 100644 --- a/lib/lancamentos/page-helpers.ts +++ b/lib/lancamentos/page-helpers.ts @@ -15,7 +15,7 @@ import { } from "@/lib/lancamentos/constants"; import { PAGADOR_ROLE_ADMIN, PAGADOR_ROLE_TERCEIRO } from "@/lib/pagadores/constants"; import type { SQL } from "drizzle-orm"; -import { eq, ilike, or } from "drizzle-orm"; +import { and, eq, ilike, isNotNull, or } from "drizzle-orm"; type PagadorRow = typeof pagadores.$inferSelect; type ContaRow = typeof contas.$inferSelect; @@ -370,8 +370,12 @@ export const buildLancamentoWhere = ({ where.push( or( ilike(lancamentos.name, searchPattern), - ilike(lancamentos.note, searchPattern) - ) + ilike(lancamentos.note, searchPattern), + ilike(lancamentos.paymentMethod, searchPattern), + ilike(lancamentos.condition, searchPattern), + and(isNotNull(contas.name), ilike(contas.name, searchPattern)), + and(isNotNull(cartoes.name), ilike(cartoes.name, searchPattern)) + )! ); } diff --git a/lib/utils/icons.tsx b/lib/utils/icons.tsx index 7d25c4c..67405c1 100644 --- a/lib/utils/icons.tsx +++ b/lib/utils/icons.tsx @@ -49,14 +49,16 @@ export const getPaymentMethodIcon = (paymentMethod: string): ReactNode => { ), cartaodecredito: ( - + ), cartaodedebito: ( - + ), - debito: , + debito: , prepagovrva: , - transferenciabancaria: , + transferenciabancaria: ( + + ), }; return registry[key] ?? null; diff --git a/package.json b/package.json index 6ac6e8b..8637330 100644 --- a/package.json +++ b/package.json @@ -27,9 +27,9 @@ "docker:rebuild": "docker compose up --build --force-recreate" }, "dependencies": { - "@ai-sdk/anthropic": "^3.0.2", - "@ai-sdk/google": "^3.0.2", - "@ai-sdk/openai": "^3.0.2", + "@ai-sdk/anthropic": "^3.0.9", + "@ai-sdk/google": "^3.0.6", + "@ai-sdk/openai": "^3.0.7", "@openrouter/ai-sdk-provider": "^1.5.4", "@radix-ui/react-accordion": "^1.2.12", "@radix-ui/react-alert-dialog": "1.1.15", @@ -56,7 +56,7 @@ "@tanstack/react-table": "8.21.3", "@vercel/analytics": "^1.6.1", "@vercel/speed-insights": "^1.3.1", - "ai": "^6.0.7", + "ai": "^6.0.27", "babel-plugin-react-compiler": "^1.0.0", "better-auth": "1.4.10", "class-variance-authority": "0.7.1", @@ -66,7 +66,7 @@ "drizzle-orm": "0.45.1", "jspdf": "^4.0.0", "jspdf-autotable": "^5.0.7", - "motion": "^12.23.27", + "motion": "^12.25.0", "next": "16.1.1", "next-themes": "0.4.6", "pg": "8.16.3", @@ -74,7 +74,7 @@ "react-day-picker": "^9.13.0", "react-dom": "19.2.3", "recharts": "3.6.0", - "resend": "^6.6.0", + "resend": "^6.7.0", "sonner": "2.0.7", "tailwind-merge": "3.4.0", "vaul": "1.1.2", @@ -88,7 +88,7 @@ "@types/pg": "^8.16.0", "@types/react": "19.2.7", "@types/react-dom": "19.2.3", - "baseline-browser-mapping": "^2.9.11", + "baseline-browser-mapping": "^2.9.14", "depcheck": "^1.4.7", "dotenv": "^17.2.3", "drizzle-kit": "0.31.8", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 137df88..d84d1dc 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,17 +9,17 @@ importers: .: dependencies: '@ai-sdk/anthropic': - specifier: ^3.0.2 - version: 3.0.2(zod@4.3.5) + specifier: ^3.0.9 + version: 3.0.9(zod@4.3.5) '@ai-sdk/google': - specifier: ^3.0.2 - version: 3.0.2(zod@4.3.5) + specifier: ^3.0.6 + version: 3.0.6(zod@4.3.5) '@ai-sdk/openai': - specifier: ^3.0.2 - version: 3.0.2(zod@4.3.5) + specifier: ^3.0.7 + version: 3.0.7(zod@4.3.5) '@openrouter/ai-sdk-provider': specifier: ^1.5.4 - version: 1.5.4(ai@6.0.7(zod@4.3.5))(zod@4.3.5) + version: 1.5.4(ai@6.0.27(zod@4.3.5))(zod@4.3.5) '@radix-ui/react-accordion': specifier: ^1.2.12 version: 1.2.12(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) @@ -96,8 +96,8 @@ importers: specifier: ^1.3.1 version: 1.3.1(next@16.1.1(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react@19.2.3) ai: - specifier: ^6.0.7 - version: 6.0.7(zod@4.3.5) + specifier: ^6.0.27 + version: 6.0.27(zod@4.3.5) babel-plugin-react-compiler: specifier: ^1.0.0 version: 1.0.0 @@ -126,8 +126,8 @@ importers: specifier: ^5.0.7 version: 5.0.7(jspdf@4.0.0) motion: - specifier: ^12.23.27 - version: 12.23.27(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^12.25.0 + version: 12.25.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) next: specifier: 16.1.1 version: 16.1.1(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) @@ -150,8 +150,8 @@ importers: specifier: 3.6.0 version: 3.6.0(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react-is@16.13.1)(react@19.2.3)(redux@5.0.1) resend: - specifier: ^6.6.0 - version: 6.6.0 + specifier: ^6.7.0 + version: 6.7.0 sonner: specifier: 2.0.7 version: 2.0.7(react-dom@19.2.3(react@19.2.3))(react@19.2.3) @@ -187,8 +187,8 @@ importers: specifier: 19.2.3 version: 19.2.3(@types/react@19.2.7) baseline-browser-mapping: - specifier: ^2.9.11 - version: 2.9.11 + specifier: ^2.9.14 + version: 2.9.14 depcheck: specifier: ^1.4.7 version: 1.4.7 @@ -203,7 +203,7 @@ importers: version: 9.39.2(jiti@2.6.1) eslint-config-next: specifier: 16.1.1 - version: 16.1.1(@typescript-eslint/parser@8.50.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + version: 16.1.1(@typescript-eslint/parser@8.52.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) tailwindcss: specifier: 4.1.18 version: 4.1.18 @@ -216,38 +216,38 @@ importers: packages: - '@ai-sdk/anthropic@3.0.2': - resolution: {integrity: sha512-D6iSsrOYryBSPsFtOiEDv54jnjVCU/flIuXdjuRY7LdikB0KGjpazN8Dt4ONXzL+ux69ds2nzFNKke/w/fgLAA==} + '@ai-sdk/anthropic@3.0.9': + resolution: {integrity: sha512-QBD4qDnwIHd+N5PpjxXOaWJig1aRB43J0PM5ZUe6Yyl9Qq2bUmraQjvNznkuFKy+hMFDgj0AvgGogTiO5TC+qA==} engines: {node: '>=18'} peerDependencies: zod: ^3.25.76 || ^4.1.8 - '@ai-sdk/gateway@3.0.6': - resolution: {integrity: sha512-oEpwjM0PIaSUErtZI8Ag+gQ+ZelysRWA96N5ahvOc5e9d7QkKJWF0POWx0nI1qBxvmUSw7ca0sLTVw+J5yn7Tg==} + '@ai-sdk/gateway@3.0.11': + resolution: {integrity: sha512-gLrgNXA95wdo/zAlA0miX/SJEYKSYCHg+e0Y/uQeABLScZAMjPw3jWaeANta/Db1T4xfi8cBvY3nnV8Pa27z+w==} engines: {node: '>=18'} peerDependencies: zod: ^3.25.76 || ^4.1.8 - '@ai-sdk/google@3.0.2': - resolution: {integrity: sha512-KyV4AR8fBKVCABfav3zGn/PY7cMDMt9m7yYhH+FJ7jLfBrEVdjT4sM0ojPFRHYUelXHl42oOAgpy3GWkeG6vtw==} + '@ai-sdk/google@3.0.6': + resolution: {integrity: sha512-Nr7E+ouWd/bKO9SFlgLnJJ1+fiGHC07KAeFr08faT+lvkECWlxVox3aL0dec8uCgBDUghYbq7f4S5teUrCc+QQ==} engines: {node: '>=18'} peerDependencies: zod: ^3.25.76 || ^4.1.8 - '@ai-sdk/openai@3.0.2': - resolution: {integrity: sha512-GONwavgSWtcWO+t9+GpGK8l7nIYh+zNtCL/NYDSeHxHiw6ksQS9XMRWrZyE5NpJ0EXNxSAWCHIDmb1WvTqhq9Q==} + '@ai-sdk/openai@3.0.7': + resolution: {integrity: sha512-CBoYn1U59Lop8yBL9KuVjHCKc/B06q9Qo0SasRwHoyMEq+X4I8LQZu3a8Ck1jwwcZTTxfyiExB70LtIRSynBDA==} engines: {node: '>=18'} peerDependencies: zod: ^3.25.76 || ^4.1.8 - '@ai-sdk/provider-utils@4.0.2': - resolution: {integrity: sha512-KaykkuRBdF/ffpI5bwpL4aSCmO/99p8/ci+VeHwJO8tmvXtiVAb99QeyvvvXmL61e9Zrvv4GBGoajW19xdjkVQ==} + '@ai-sdk/provider-utils@4.0.4': + resolution: {integrity: sha512-VxhX0B/dWGbpNHxrKCWUAJKXIXV015J4e7qYjdIU9lLWeptk0KMLGcqkB4wFxff5Njqur8dt8wRi1MN9lZtDqg==} engines: {node: '>=18'} peerDependencies: zod: ^3.25.76 || ^4.1.8 - '@ai-sdk/provider@3.0.1': - resolution: {integrity: sha512-2lR4w7mr9XrydzxBSjir4N6YMGdXD+Np1Sh0RXABh7tWdNFFwIeRI1Q+SaYZMbfL8Pg8RRLcrxQm51yxTLhokg==} + '@ai-sdk/provider@3.0.2': + resolution: {integrity: sha512-HrEmNt/BH/hkQ7zpi2o6N3k1ZR1QTb7z85WYhYygiTxOQuaml4CMtHCWRbric5WPU+RNsYI7r1EpyVQMKO1pYw==} engines: {node: '>=18'} '@alloc/quick-lru@5.2.0': @@ -352,11 +352,11 @@ packages: '@drizzle-team/brocli@0.10.2': resolution: {integrity: sha512-z33Il7l5dKjUgGULTqBsQBQwckHh5AbIuxhdsIxDDiZAzBOrZO6q9ogcWC65kU382AfynTfgNumVcNIjuIua6w==} - '@emnapi/core@1.7.1': - resolution: {integrity: sha512-o1uhUASyo921r2XtHYOHy7gdkGLge8ghBEQHMWmyJFoXlpU58kIrhhN3w26lpQb6dspetweapMn2CSNwQ8I4wg==} + '@emnapi/core@1.8.1': + resolution: {integrity: sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg==} - '@emnapi/runtime@1.7.1': - resolution: {integrity: sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA==} + '@emnapi/runtime@1.8.1': + resolution: {integrity: sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==} '@emnapi/wasi-threads@1.1.0': resolution: {integrity: sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==} @@ -813,8 +813,8 @@ packages: cpu: [x64] os: [win32] - '@eslint-community/eslint-utils@4.9.0': - resolution: {integrity: sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==} + '@eslint-community/eslint-utils@4.9.1': + resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 @@ -1880,9 +1880,6 @@ packages: '@types/minimatch@3.0.5': resolution: {integrity: sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==} - '@types/node@22.19.3': - resolution: {integrity: sha512-1N9SBnWYOJTrNZCdh/yJE+t910Y128BoyY+zBLWhL3r0TYzlTmFdXrPwHL9DyFZmlEXNQQolTZh3KHV31QDhyA==} - '@types/node@25.0.3': resolution: {integrity: sha512-W609buLVRVmeW693xKfzHeIV6nJGGz98uCPfeXI1ELMLXVeKYZ9m15fAMSaUPBHYLGFsVRcMmSCksQOrZV9BYA==} @@ -1912,63 +1909,63 @@ packages: '@types/use-sync-external-store@0.0.6': resolution: {integrity: sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==} - '@typescript-eslint/eslint-plugin@8.50.1': - resolution: {integrity: sha512-PKhLGDq3JAg0Jk/aK890knnqduuI/Qj+udH7wCf0217IGi4gt+acgCyPVe79qoT+qKUvHMDQkwJeKW9fwl8Cyw==} + '@typescript-eslint/eslint-plugin@8.52.0': + resolution: {integrity: sha512-okqtOgqu2qmZJ5iN4TWlgfF171dZmx2FzdOv2K/ixL2LZWDStL8+JgQerI2sa8eAEfoydG9+0V96m7V+P8yE1Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.50.1 + '@typescript-eslint/parser': ^8.52.0 eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/parser@8.50.1': - resolution: {integrity: sha512-hM5faZwg7aVNa819m/5r7D0h0c9yC4DUlWAOvHAtISdFTc8xB86VmX5Xqabrama3wIPJ/q9RbGS1worb6JfnMg==} + '@typescript-eslint/parser@8.52.0': + resolution: {integrity: sha512-iIACsx8pxRnguSYhHiMn2PvhvfpopO9FXHyn1mG5txZIsAaB6F0KwbFnUQN3KCiG3Jcuad/Cao2FAs1Wp7vAyg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/project-service@8.50.1': - resolution: {integrity: sha512-E1ur1MCVf+YiP89+o4Les/oBAVzmSbeRB0MQLfSlYtbWU17HPxZ6Bhs5iYmKZRALvEuBoXIZMOIRRc/P++Ortg==} + '@typescript-eslint/project-service@8.52.0': + resolution: {integrity: sha512-xD0MfdSdEmeFa3OmVqonHi+Cciab96ls1UhIF/qX/O/gPu5KXD0bY9lu33jj04fjzrXHcuvjBcBC+D3SNSadaw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/scope-manager@8.50.1': - resolution: {integrity: sha512-mfRx06Myt3T4vuoHaKi8ZWNTPdzKPNBhiblze5N50//TSHOAQQevl/aolqA/BcqqbJ88GUnLqjjcBc8EWdBcVw==} + '@typescript-eslint/scope-manager@8.52.0': + resolution: {integrity: sha512-ixxqmmCcc1Nf8S0mS0TkJ/3LKcC8mruYJPOU6Ia2F/zUUR4pApW7LzrpU3JmtePbRUTes9bEqRc1Gg4iyRnDzA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.50.1': - resolution: {integrity: sha512-ooHmotT/lCWLXi55G4mvaUF60aJa012QzvLK0Y+Mp4WdSt17QhMhWOaBWeGTFVkb2gDgBe19Cxy1elPXylslDw==} + '@typescript-eslint/tsconfig-utils@8.52.0': + resolution: {integrity: sha512-jl+8fzr/SdzdxWJznq5nvoI7qn2tNYV/ZBAEcaFMVXf+K6jmXvAFrgo/+5rxgnL152f//pDEAYAhhBAZGrVfwg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/type-utils@8.50.1': - resolution: {integrity: sha512-7J3bf022QZE42tYMO6SL+6lTPKFk/WphhRPe9Tw/el+cEwzLz1Jjz2PX3GtGQVxooLDKeMVmMt7fWpYRdG5Etg==} + '@typescript-eslint/type-utils@8.52.0': + resolution: {integrity: sha512-JD3wKBRWglYRQkAtsyGz1AewDu3mTc7NtRjR/ceTyGoPqmdS5oCdx/oZMWD5Zuqmo6/MpsYs0wp6axNt88/2EQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/types@8.50.1': - resolution: {integrity: sha512-v5lFIS2feTkNyMhd7AucE/9j/4V9v5iIbpVRncjk/K0sQ6Sb+Np9fgYS/63n6nwqahHQvbmujeBL7mp07Q9mlA==} + '@typescript-eslint/types@8.52.0': + resolution: {integrity: sha512-LWQV1V4q9V4cT4H5JCIx3481iIFxH1UkVk+ZkGGAV1ZGcjGI9IoFOfg3O6ywz8QqCDEp7Inlg6kovMofsNRaGg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.50.1': - resolution: {integrity: sha512-woHPdW+0gj53aM+cxchymJCrh0cyS7BTIdcDxWUNsclr9VDkOSbqC13juHzxOmQ22dDkMZEpZB+3X1WpUvzgVQ==} + '@typescript-eslint/typescript-estree@8.52.0': + resolution: {integrity: sha512-XP3LClsCc0FsTK5/frGjolyADTh3QmsLp6nKd476xNI9CsSsLnmn4f0jrzNoAulmxlmNIpeXuHYeEQv61Q6qeQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/utils@8.50.1': - resolution: {integrity: sha512-lCLp8H1T9T7gPbEuJSnHwnSuO9mDf8mfK/Nion5mZmiEaQD9sWf9W4dfeFqRyqRjF06/kBuTmAqcs9sewM2NbQ==} + '@typescript-eslint/utils@8.52.0': + resolution: {integrity: sha512-wYndVMWkweqHpEpwPhwqE2lnD2DxC6WVLupU/DOt/0/v+/+iQbbzO3jOHjmBMnhu0DgLULvOaU4h4pwHYi2oRQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/visitor-keys@8.50.1': - resolution: {integrity: sha512-IrDKrw7pCRUR94zeuCSUWQ+w8JEf5ZX5jl/e6AHGSLi1/zIr0lgutfn/7JpfCey+urpgQEdrZVYzCaVVKiTwhQ==} + '@typescript-eslint/visitor-keys@8.52.0': + resolution: {integrity: sha512-ink3/Zofus34nmBsPjow63FP5M7IGff0RKAgqR6+CFpdk22M7aLwC9gOcLGYqr7MczLPzZVERW9hRog3O4n1sQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@unrs/resolver-binding-android-arm-eabi@1.11.1': @@ -2092,8 +2089,8 @@ packages: vue-router: optional: true - '@vercel/oidc@3.0.5': - resolution: {integrity: sha512-fnYhv671l+eTTp48gB4zEsTW/YtRgRPnkI2nT7x6qw5rkI1Lq2hTmQIpHPgyThI0znLK+vX2n9XxKdXZ7BUbbw==} + '@vercel/oidc@3.1.0': + resolution: {integrity: sha512-Fw28YZpRnA3cAHHDlkt7xQHiJ0fcL+NRcIqsocZQUSmbzeIKRpwttJjik5ZGanXP+vlA4SbTg+AbA3bP363l+w==} engines: {node: '>= 20'} '@vercel/speed-insights@1.3.1': @@ -2148,8 +2145,8 @@ packages: resolution: {integrity: sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A==} engines: {node: '>=0.8'} - ai@6.0.7: - resolution: {integrity: sha512-kLzSXHdW6cAcb2mFSIfkbfzxYqqjrUnyhrB1sg855qlC+6XkLI8hmwFE8f/4SnjmtcTDOnkIaVjWoO5i5Ir0bw==} + ai@6.0.27: + resolution: {integrity: sha512-a4ToMt5+4xOzHuYdoTy2GQXuNa2/Tpuhxfs5QESHtEV/Vf2HAzSwmTwikrIs8CDKPuMWV1I9YqAvaN5xexMCiQ==} engines: {node: '>=18'} peerDependencies: zod: ^3.25.76 || ^4.1.8 @@ -2234,8 +2231,8 @@ packages: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} - axe-core@4.11.0: - resolution: {integrity: sha512-ilYanEU8vxxBexpJd8cWM4ElSQq4QctCLKih0TSfjIfCQTeyH/6zVrmIJfLPrKTKJRbiG+cfnZbQIjAlJmF1jQ==} + axe-core@4.11.1: + resolution: {integrity: sha512-BASOg+YwO2C+346x3LZOeoovTIoTrRqEsqMa6fmfAV0P+U9mFr9NsyOEpiYvFjbc64NMrSswhV50WdXzdb/Z5A==} engines: {node: '>=4'} axobject-query@4.1.0: @@ -2252,8 +2249,8 @@ packages: resolution: {integrity: sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==} engines: {node: '>= 0.6.0'} - baseline-browser-mapping@2.9.11: - resolution: {integrity: sha512-Sg0xJUNDU1sJNGdfGWhVHX0kkZ+HWcvmVymJbj6NSgZZmW/8S9Y2HQ5euytnIgakgxN6papOAWiwDo1ctFDcoQ==} + baseline-browser-mapping@2.9.14: + resolution: {integrity: sha512-B0xUquLkiGLgHhpPBqvl7GWegWBUNuujQ6kXd/r1U38ElPT6Ok8KZ8e+FpUGEc2ZoRQUzq/aUnaKFc/svWUGSg==} hasBin: true better-auth@1.4.10: @@ -2364,8 +2361,8 @@ packages: resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} engines: {node: '>=10'} - caniuse-lite@1.0.30001761: - resolution: {integrity: sha512-JF9ptu1vP2coz98+5051jZ4PwQgd2ni8A+gYSN7EA7dPKIMf0pDlSUxhdmVOaV3/fYK5uWBkgSXJaRLr4+3A6g==} + caniuse-lite@1.0.30001763: + resolution: {integrity: sha512-mh/dGtq56uN98LlNX9qdbKnzINhX0QzhiWBFEkFfsFO4QyCvL8YegrJAazCwXIeqkIob8BlZPGM3xdnY+sgmvQ==} canvg@3.0.11: resolution: {integrity: sha512-5ON+q7jCTgMp9cjpu4Jo6XbvfYwSB2Ow3kzHKfIyJfaCAOHLbdKPQqGKgfED/R5B+3TFFfe8pegYA+b423SRyA==} @@ -2721,9 +2718,6 @@ packages: es-toolkit@1.43.0: resolution: {integrity: sha512-SKCT8AsWvYzBBuUqMk4NPwFlSdqLpJwmy6AP322ERn8W2YLIB6JBXnwMI2Qsh2gfphT3q7EKAxKb23cvFHFwKA==} - es6-promise@4.2.8: - resolution: {integrity: sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==} - esbuild-register@3.6.0: resolution: {integrity: sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg==} peerDependencies: @@ -2857,8 +2851,8 @@ packages: engines: {node: '>=4'} hasBin: true - esquery@1.6.0: - resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} + esquery@1.7.0: + resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} engines: {node: '>=0.10'} esrecurse@4.3.0: @@ -2952,8 +2946,8 @@ packages: resolution: {integrity: sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA==} engines: {node: '>=0.8'} - framer-motion@12.23.27: - resolution: {integrity: sha512-EAcX8FS8jzZ4tSKpj+1GhwbVY+r1gfamPFwXZAsioPqu/ffRwU2otkKg6GEDCR41FVJv3RoBN7Aqep6drL9Itg==} + framer-motion@12.25.0: + resolution: {integrity: sha512-mlWqd0rApIjeyhTCSNCqPYsUAEhkcUukZxH3ke6KbstBRPcxhEpuIjmiUQvB+1E9xkEm5SpNHBgHCapH/QHTWg==} peerDependencies: '@emotion/is-prop-valid': '*' react: ^18.0.0 || ^19.0.0 @@ -3099,8 +3093,8 @@ packages: immer@10.2.0: resolution: {integrity: sha512-d/+XTN3zfODyjr89gM3mPq1WNX2B8pYsu7eORitdwyA2sBubnTl3laYlBk4sXY5FUa5qTZGBDPJICVbvqzjlbw==} - immer@11.1.0: - resolution: {integrity: sha512-dlzb07f5LDY+tzs+iLCSXV2yuhaYfezqyZQc+n6baLECWkOMEWxkECAOnXL0ba7lsA25fM9b2jtzpu/uxo1a7g==} + immer@11.1.3: + resolution: {integrity: sha512-6jQTc5z0KJFtr1UgFpIL3N9XSC3saRaI9PwWtzM2pSqkNGtiNkYY2OSwkOGDK2XcTRcLb1pi/aNkKZz0nxVH4Q==} import-fresh@3.3.1: resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} @@ -3444,14 +3438,14 @@ packages: minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - motion-dom@12.23.23: - resolution: {integrity: sha512-n5yolOs0TQQBRUFImrRfs/+6X4p3Q4n1dUEqt/H58Vx7OW6RF+foWEgmTVDhIWJIMXOuNNL0apKH2S16en9eiA==} + motion-dom@12.24.11: + resolution: {integrity: sha512-DlWOmsXMJrV8lzZyd+LKjG2CXULUs++bkq8GZ2Sr0R0RRhs30K2wtY+LKiTjhmJU3W61HK+rB0GLz6XmPvTA1A==} - motion-utils@12.23.6: - resolution: {integrity: sha512-eAWoPgr4eFEOFfg2WjIsMoqJTW6Z8MTUCgn/GZ3VRpClWBdnbjryiA3ZSNLyxCTmCQx4RmYX6jX1iWHbenUPNQ==} + motion-utils@12.24.10: + resolution: {integrity: sha512-x5TFgkCIP4pPsRLpKoI86jv/q8t8FQOiM/0E8QKBzfMozWHfkKap2gA1hOki+B5g3IsBNpxbUnfOum1+dgvYww==} - motion@12.23.27: - resolution: {integrity: sha512-EDb0hAE6jNX8BHpmQK1GBf9Eizx9bg/Tz2KEAJBOGEnIJp8W77QweRpVb05U8R0L0/LXndHmS1Xv3fwXJh/kcQ==} + motion@12.25.0: + resolution: {integrity: sha512-jBFohEYklpZ+TL64zv03sHdqr1Tsc8/yDy7u68hVzi7hTJYtv53AduchqCiY3aWi4vY1hweS8DWtgCuckusYdQ==} peerDependencies: '@emotion/is-prop-valid': '*' react: ^18.0.0 || ^19.0.0 @@ -3686,9 +3680,6 @@ packages: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} - querystringify@2.2.0: - resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} - queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} @@ -3793,14 +3784,11 @@ packages: require-package-name@2.0.1: resolution: {integrity: sha512-uuoJ1hU/k6M0779t3VMVIYpb2VMJk05cehCaABFhXaibcbvfgR8wKiozLjVFSzJPmQMRqIcO0HMyTFqfV09V6Q==} - requires-port@1.0.0: - resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} - reselect@5.1.1: resolution: {integrity: sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==} - resend@6.6.0: - resolution: {integrity: sha512-d1WoOqSxj5x76JtQMrieNAG1kZkh4NU4f+Je1yq4++JsDpLddhEwnJlNfvkCzvUuZy9ZquWmMMAm2mENd2JvRw==} + resend@6.7.0: + resolution: {integrity: sha512-2ZV0NDZsh4Gh+Nd1hvluZIitmGJ59O4+OxMufymG6Y8uz1Jgt2uS1seSENnkIUlmwg7/dwmfIJC9rAufByz7wA==} engines: {node: '>=20'} peerDependencies: '@react-email/render': '*' @@ -3951,6 +3939,9 @@ packages: resolution: {integrity: sha512-yf7OENo23AGJhBriGx0QivY5JP6Y1HbrrDI6WLt6C5auYZXlQrheoY8hD4ibekFKz1HOfE48Ww8kMWMnJD/zcQ==} engines: {node: '>=0.1.14'} + standardwebhooks@1.0.0: + resolution: {integrity: sha512-BbHGOQK9olHPMvQNHWul6MYlrRTAOKn03rOe4A8O3CLWhNf4YHBqq2HJKKC+sfqpxiBY52pNeesD6jIiLDz8jg==} + stop-iteration-iterator@1.1.0: resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} engines: {node: '>= 0.4'} @@ -4019,8 +4010,8 @@ packages: resolution: {integrity: sha512-qsjeeq5YjBZ5eMdFuUa4ZosMLxgr5RZ+F+Y1OrDhuOCEInRMA3x74XdBtggJcj9kOeInz0WE+LgCPDkZFlBYJw==} engines: {node: '>=12.0.0'} - svix@1.76.1: - resolution: {integrity: sha512-CRuDWBTgYfDnBLRaZdKp9VuoPcNUq9An14c/k+4YJ15Qc5Grvf66vp0jvTltd4t7OIRj+8lM1DAgvSgvf7hdLw==} + svix@1.84.1: + resolution: {integrity: sha512-K8DPPSZaW/XqXiz1kEyzSHYgmGLnhB43nQCMeKjWGCUpLIpAMMM8kx3rVVOSm6Bo6EHyK1RQLPT4R06skM/MlQ==} tailwind-merge@3.4.0: resolution: {integrity: sha512-uSaO4gnW+b3Y2aWoWfFpX62vn2sR3skfhbjsEnaBI81WD1wBLlHZe5sWf0AqjksNdYTbGBEd0UasQMT3SNV15g==} @@ -4046,8 +4037,8 @@ packages: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} - ts-api-utils@2.1.0: - resolution: {integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==} + ts-api-utils@2.4.0: + resolution: {integrity: sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==} engines: {node: '>=18.12'} peerDependencies: typescript: '>=4.8.4' @@ -4083,8 +4074,8 @@ packages: resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} engines: {node: '>= 0.4'} - typescript-eslint@8.50.1: - resolution: {integrity: sha512-ytTHO+SoYSbhAH9CrYnMhiLx8To6PSSvqnvXyPUgPETCvB6eBKmTI9w6XMPS3HsBRGkwTVBX+urA8dYQx6bHfQ==} + typescript-eslint@8.52.0: + resolution: {integrity: sha512-atlQQJ2YkO4pfTVQmQ+wvYQwexPDOIgo+RaVcD7gHgzy/IQA+XTyuxNM9M9TVXvttkF7koBHmcwisKdOAf2EcA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -4099,9 +4090,6 @@ packages: resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} engines: {node: '>= 0.4'} - undici-types@6.21.0: - resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} - undici-types@7.16.0: resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} @@ -4117,9 +4105,6 @@ packages: uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} - url-parse@1.5.10: - resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} - use-callback-ref@1.3.3: resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==} engines: {node: '>=10'} @@ -4245,39 +4230,39 @@ packages: snapshots: - '@ai-sdk/anthropic@3.0.2(zod@4.3.5)': + '@ai-sdk/anthropic@3.0.9(zod@4.3.5)': dependencies: - '@ai-sdk/provider': 3.0.1 - '@ai-sdk/provider-utils': 4.0.2(zod@4.3.5) + '@ai-sdk/provider': 3.0.2 + '@ai-sdk/provider-utils': 4.0.4(zod@4.3.5) zod: 4.3.5 - '@ai-sdk/gateway@3.0.6(zod@4.3.5)': + '@ai-sdk/gateway@3.0.11(zod@4.3.5)': dependencies: - '@ai-sdk/provider': 3.0.1 - '@ai-sdk/provider-utils': 4.0.2(zod@4.3.5) - '@vercel/oidc': 3.0.5 + '@ai-sdk/provider': 3.0.2 + '@ai-sdk/provider-utils': 4.0.4(zod@4.3.5) + '@vercel/oidc': 3.1.0 zod: 4.3.5 - '@ai-sdk/google@3.0.2(zod@4.3.5)': + '@ai-sdk/google@3.0.6(zod@4.3.5)': dependencies: - '@ai-sdk/provider': 3.0.1 - '@ai-sdk/provider-utils': 4.0.2(zod@4.3.5) + '@ai-sdk/provider': 3.0.2 + '@ai-sdk/provider-utils': 4.0.4(zod@4.3.5) zod: 4.3.5 - '@ai-sdk/openai@3.0.2(zod@4.3.5)': + '@ai-sdk/openai@3.0.7(zod@4.3.5)': dependencies: - '@ai-sdk/provider': 3.0.1 - '@ai-sdk/provider-utils': 4.0.2(zod@4.3.5) + '@ai-sdk/provider': 3.0.2 + '@ai-sdk/provider-utils': 4.0.4(zod@4.3.5) zod: 4.3.5 - '@ai-sdk/provider-utils@4.0.2(zod@4.3.5)': + '@ai-sdk/provider-utils@4.0.4(zod@4.3.5)': dependencies: - '@ai-sdk/provider': 3.0.1 + '@ai-sdk/provider': 3.0.2 '@standard-schema/spec': 1.1.0 eventsource-parser: 3.0.6 zod: 4.3.5 - '@ai-sdk/provider@3.0.1': + '@ai-sdk/provider@3.0.2': dependencies: json-schema: 0.4.0 @@ -4410,13 +4395,13 @@ snapshots: '@drizzle-team/brocli@0.10.2': {} - '@emnapi/core@1.7.1': + '@emnapi/core@1.8.1': dependencies: '@emnapi/wasi-threads': 1.1.0 tslib: 2.8.1 optional: true - '@emnapi/runtime@1.7.1': + '@emnapi/runtime@1.8.1': dependencies: tslib: 2.8.1 optional: true @@ -4658,7 +4643,7 @@ snapshots: '@esbuild/win32-x64@0.27.2': optional: true - '@eslint-community/eslint-utils@4.9.0(eslint@9.39.2(jiti@2.6.1))': + '@eslint-community/eslint-utils@4.9.1(eslint@9.39.2(jiti@2.6.1))': dependencies: eslint: 9.39.2(jiti@2.6.1) eslint-visitor-keys: 3.4.3 @@ -4817,7 +4802,7 @@ snapshots: '@img/sharp-wasm32@0.34.5': dependencies: - '@emnapi/runtime': 1.7.1 + '@emnapi/runtime': 1.8.1 optional: true '@img/sharp-win32-arm64@0.34.5': @@ -4850,8 +4835,8 @@ snapshots: '@napi-rs/wasm-runtime@0.2.12': dependencies: - '@emnapi/core': 1.7.1 - '@emnapi/runtime': 1.7.1 + '@emnapi/core': 1.8.1 + '@emnapi/runtime': 1.8.1 '@tybys/wasm-util': 0.10.1 optional: true @@ -4903,10 +4888,10 @@ snapshots: '@nolyfill/is-core-module@1.0.39': {} - '@openrouter/ai-sdk-provider@1.5.4(ai@6.0.7(zod@4.3.5))(zod@4.3.5)': + '@openrouter/ai-sdk-provider@1.5.4(ai@6.0.27(zod@4.3.5))(zod@4.3.5)': dependencies: '@openrouter/sdk': 0.1.27 - ai: 6.0.7(zod@4.3.5) + ai: 6.0.27(zod@4.3.5) zod: 4.3.5 '@openrouter/sdk@0.1.27': @@ -5512,7 +5497,7 @@ snapshots: dependencies: '@standard-schema/spec': 1.1.0 '@standard-schema/utils': 0.3.0 - immer: 11.1.0 + immer: 11.1.3 redux: 5.0.1 redux-thunk: 3.1.0(redux@5.0.1) reselect: 5.1.1 @@ -5650,10 +5635,6 @@ snapshots: '@types/minimatch@3.0.5': {} - '@types/node@22.19.3': - dependencies: - undici-types: 6.21.0 - '@types/node@25.0.3': dependencies: undici-types: 7.16.0 @@ -5684,95 +5665,95 @@ snapshots: '@types/use-sync-external-store@0.0.6': {} - '@typescript-eslint/eslint-plugin@8.50.1(@typescript-eslint/parser@8.50.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/eslint-plugin@8.52.0(@typescript-eslint/parser@8.52.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.50.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.50.1 - '@typescript-eslint/type-utils': 8.50.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/utils': 8.50.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.50.1 + '@typescript-eslint/parser': 8.52.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.52.0 + '@typescript-eslint/type-utils': 8.52.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/utils': 8.52.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.52.0 eslint: 9.39.2(jiti@2.6.1) ignore: 7.0.5 natural-compare: 1.4.0 - ts-api-utils: 2.1.0(typescript@5.9.3) + ts-api-utils: 2.4.0(typescript@5.9.3) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.50.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/parser@8.52.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@typescript-eslint/scope-manager': 8.50.1 - '@typescript-eslint/types': 8.50.1 - '@typescript-eslint/typescript-estree': 8.50.1(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.50.1 + '@typescript-eslint/scope-manager': 8.52.0 + '@typescript-eslint/types': 8.52.0 + '@typescript-eslint/typescript-estree': 8.52.0(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.52.0 debug: 4.4.3 eslint: 9.39.2(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.50.1(typescript@5.9.3)': + '@typescript-eslint/project-service@8.52.0(typescript@5.9.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.50.1(typescript@5.9.3) - '@typescript-eslint/types': 8.50.1 + '@typescript-eslint/tsconfig-utils': 8.52.0(typescript@5.9.3) + '@typescript-eslint/types': 8.52.0 debug: 4.4.3 typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.50.1': + '@typescript-eslint/scope-manager@8.52.0': dependencies: - '@typescript-eslint/types': 8.50.1 - '@typescript-eslint/visitor-keys': 8.50.1 + '@typescript-eslint/types': 8.52.0 + '@typescript-eslint/visitor-keys': 8.52.0 - '@typescript-eslint/tsconfig-utils@8.50.1(typescript@5.9.3)': + '@typescript-eslint/tsconfig-utils@8.52.0(typescript@5.9.3)': dependencies: typescript: 5.9.3 - '@typescript-eslint/type-utils@8.50.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/type-utils@8.52.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@typescript-eslint/types': 8.50.1 - '@typescript-eslint/typescript-estree': 8.50.1(typescript@5.9.3) - '@typescript-eslint/utils': 8.50.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/types': 8.52.0 + '@typescript-eslint/typescript-estree': 8.52.0(typescript@5.9.3) + '@typescript-eslint/utils': 8.52.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) debug: 4.4.3 eslint: 9.39.2(jiti@2.6.1) - ts-api-utils: 2.1.0(typescript@5.9.3) + ts-api-utils: 2.4.0(typescript@5.9.3) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.50.1': {} + '@typescript-eslint/types@8.52.0': {} - '@typescript-eslint/typescript-estree@8.50.1(typescript@5.9.3)': + '@typescript-eslint/typescript-estree@8.52.0(typescript@5.9.3)': dependencies: - '@typescript-eslint/project-service': 8.50.1(typescript@5.9.3) - '@typescript-eslint/tsconfig-utils': 8.50.1(typescript@5.9.3) - '@typescript-eslint/types': 8.50.1 - '@typescript-eslint/visitor-keys': 8.50.1 + '@typescript-eslint/project-service': 8.52.0(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.52.0(typescript@5.9.3) + '@typescript-eslint/types': 8.52.0 + '@typescript-eslint/visitor-keys': 8.52.0 debug: 4.4.3 minimatch: 9.0.5 semver: 7.7.3 tinyglobby: 0.2.15 - ts-api-utils: 2.1.0(typescript@5.9.3) + ts-api-utils: 2.4.0(typescript@5.9.3) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.50.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/utils@8.52.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.2(jiti@2.6.1)) - '@typescript-eslint/scope-manager': 8.50.1 - '@typescript-eslint/types': 8.50.1 - '@typescript-eslint/typescript-estree': 8.50.1(typescript@5.9.3) + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2(jiti@2.6.1)) + '@typescript-eslint/scope-manager': 8.52.0 + '@typescript-eslint/types': 8.52.0 + '@typescript-eslint/typescript-estree': 8.52.0(typescript@5.9.3) eslint: 9.39.2(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.50.1': + '@typescript-eslint/visitor-keys@8.52.0': dependencies: - '@typescript-eslint/types': 8.50.1 + '@typescript-eslint/types': 8.52.0 eslint-visitor-keys: 4.2.1 '@unrs/resolver-binding-android-arm-eabi@1.11.1': @@ -5839,7 +5820,7 @@ snapshots: next: 16.1.1(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) react: 19.2.3 - '@vercel/oidc@3.0.5': {} + '@vercel/oidc@3.1.0': {} '@vercel/speed-insights@1.3.1(next@16.1.1(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react@19.2.3)': optionalDependencies: @@ -5886,11 +5867,11 @@ snapshots: adler-32@1.3.1: {} - ai@6.0.7(zod@4.3.5): + ai@6.0.27(zod@4.3.5): dependencies: - '@ai-sdk/gateway': 3.0.6(zod@4.3.5) - '@ai-sdk/provider': 3.0.1 - '@ai-sdk/provider-utils': 4.0.2(zod@4.3.5) + '@ai-sdk/gateway': 3.0.11(zod@4.3.5) + '@ai-sdk/provider': 3.0.2 + '@ai-sdk/provider-utils': 4.0.4(zod@4.3.5) '@opentelemetry/api': 1.9.0 zod: 4.3.5 @@ -6000,7 +5981,7 @@ snapshots: dependencies: possible-typed-array-names: 1.1.0 - axe-core@4.11.0: {} + axe-core@4.11.1: {} axobject-query@4.1.0: {} @@ -6013,7 +5994,7 @@ snapshots: base64-arraybuffer@1.0.2: optional: true - baseline-browser-mapping@2.9.11: {} + baseline-browser-mapping@2.9.14: {} better-auth@1.4.10(drizzle-kit@0.31.8)(drizzle-orm@0.45.1(@opentelemetry/api@1.9.0)(@types/pg@8.16.0)(kysely@0.28.9)(pg@8.16.3))(next@16.1.1(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(pg@8.16.3)(react-dom@19.2.3(react@19.2.3))(react@19.2.3): dependencies: @@ -6061,8 +6042,8 @@ snapshots: browserslist@4.28.1: dependencies: - baseline-browser-mapping: 2.9.11 - caniuse-lite: 1.0.30001761 + baseline-browser-mapping: 2.9.14 + caniuse-lite: 1.0.30001763 electron-to-chromium: 1.5.267 node-releases: 2.0.27 update-browserslist-db: 1.2.3(browserslist@4.28.1) @@ -6092,7 +6073,7 @@ snapshots: camelcase@6.3.0: {} - caniuse-lite@1.0.30001761: {} + caniuse-lite@1.0.30001763: {} canvg@3.0.11: dependencies: @@ -6457,8 +6438,6 @@ snapshots: es-toolkit@1.43.0: {} - es6-promise@4.2.8: {} - esbuild-register@3.6.0(esbuild@0.25.12): dependencies: debug: 4.4.3 @@ -6553,18 +6532,18 @@ snapshots: escape-string-regexp@4.0.0: {} - eslint-config-next@16.1.1(@typescript-eslint/parser@8.50.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3): + eslint-config-next@16.1.1(@typescript-eslint/parser@8.52.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3): dependencies: '@next/eslint-plugin-next': 16.1.1 eslint: 9.39.2(jiti@2.6.1) eslint-import-resolver-node: 0.3.9 eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.2(jiti@2.6.1)) - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.50.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.2(jiti@2.6.1)) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.52.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.2(jiti@2.6.1)) eslint-plugin-jsx-a11y: 6.10.2(eslint@9.39.2(jiti@2.6.1)) eslint-plugin-react: 7.37.5(eslint@9.39.2(jiti@2.6.1)) eslint-plugin-react-hooks: 7.0.1(eslint@9.39.2(jiti@2.6.1)) globals: 16.4.0 - typescript-eslint: 8.50.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + typescript-eslint: 8.52.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) optionalDependencies: typescript: 5.9.3 transitivePeerDependencies: @@ -6592,22 +6571,22 @@ snapshots: tinyglobby: 0.2.15 unrs-resolver: 1.11.1 optionalDependencies: - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.50.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.2(jiti@2.6.1)) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.52.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.2(jiti@2.6.1)) transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.1(@typescript-eslint/parser@8.50.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.2(jiti@2.6.1)): + eslint-module-utils@2.12.1(@typescript-eslint/parser@8.52.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.2(jiti@2.6.1)): dependencies: debug: 3.2.7 optionalDependencies: - '@typescript-eslint/parser': 8.50.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/parser': 8.52.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) eslint: 9.39.2(jiti@2.6.1) eslint-import-resolver-node: 0.3.9 eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.2(jiti@2.6.1)) transitivePeerDependencies: - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.50.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.2(jiti@2.6.1)): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.52.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.2(jiti@2.6.1)): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -6618,7 +6597,7 @@ snapshots: doctrine: 2.1.0 eslint: 9.39.2(jiti@2.6.1) eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.50.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.2(jiti@2.6.1)) + eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.52.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.2(jiti@2.6.1)) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -6630,7 +6609,7 @@ snapshots: string.prototype.trimend: 1.0.9 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 8.50.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/parser': 8.52.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack @@ -6642,7 +6621,7 @@ snapshots: array-includes: 3.1.9 array.prototype.flatmap: 1.3.3 ast-types-flow: 0.0.8 - axe-core: 4.11.0 + axe-core: 4.11.1 axobject-query: 4.1.0 damerau-levenshtein: 1.0.8 emoji-regex: 9.2.2 @@ -6699,7 +6678,7 @@ snapshots: eslint@9.39.2(jiti@2.6.1): dependencies: - '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.2(jiti@2.6.1)) + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2(jiti@2.6.1)) '@eslint-community/regexpp': 4.12.2 '@eslint/config-array': 0.21.1 '@eslint/config-helpers': 0.4.2 @@ -6719,7 +6698,7 @@ snapshots: eslint-scope: 8.4.0 eslint-visitor-keys: 4.2.1 espree: 10.4.0 - esquery: 1.6.0 + esquery: 1.7.0 esutils: 2.0.3 fast-deep-equal: 3.1.3 file-entry-cache: 8.0.0 @@ -6746,7 +6725,7 @@ snapshots: esprima@4.0.1: {} - esquery@1.6.0: + esquery@1.7.0: dependencies: estraverse: 5.3.0 @@ -6833,10 +6812,10 @@ snapshots: frac@1.1.2: {} - framer-motion@12.23.27(react-dom@19.2.3(react@19.2.3))(react@19.2.3): + framer-motion@12.25.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3): dependencies: - motion-dom: 12.23.23 - motion-utils: 12.23.6 + motion-dom: 12.24.11 + motion-utils: 12.24.10 tslib: 2.8.1 optionalDependencies: react: 19.2.3 @@ -6973,7 +6952,7 @@ snapshots: immer@10.2.0: {} - immer@11.1.0: {} + immer@11.1.3: {} import-fresh@3.3.1: dependencies: @@ -7291,15 +7270,15 @@ snapshots: minimist@1.2.8: {} - motion-dom@12.23.23: + motion-dom@12.24.11: dependencies: - motion-utils: 12.23.6 + motion-utils: 12.24.10 - motion-utils@12.23.6: {} + motion-utils@12.24.10: {} - motion@12.23.27(react-dom@19.2.3(react@19.2.3))(react@19.2.3): + motion@12.25.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3): dependencies: - framer-motion: 12.23.27(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + framer-motion: 12.25.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) tslib: 2.8.1 optionalDependencies: react: 19.2.3 @@ -7332,8 +7311,8 @@ snapshots: dependencies: '@next/env': 16.1.1 '@swc/helpers': 0.5.15 - baseline-browser-mapping: 2.9.11 - caniuse-lite: 1.0.30001761 + baseline-browser-mapping: 2.9.14 + caniuse-lite: 1.0.30001763 postcss: 8.4.31 react: 19.2.3 react-dom: 19.2.3(react@19.2.3) @@ -7526,8 +7505,6 @@ snapshots: punycode@2.3.1: {} - querystringify@2.2.0: {} - queue-microtask@1.2.3: {} raf@3.4.1: @@ -7644,13 +7621,11 @@ snapshots: require-package-name@2.0.1: {} - requires-port@1.0.0: {} - reselect@5.1.1: {} - resend@6.6.0: + resend@6.7.0: dependencies: - svix: 1.76.1 + svix: 1.84.1 resolve-dir@1.0.1: dependencies: @@ -7830,6 +7805,11 @@ snapshots: stackblur-canvas@2.7.0: optional: true + standardwebhooks@1.0.0: + dependencies: + '@stablelib/base64': 1.0.1 + fast-sha256: 1.3.0 + stop-iteration-iterator@1.1.0: dependencies: es-errors: 1.3.0 @@ -7915,13 +7895,9 @@ snapshots: svg-pathdata@6.0.3: optional: true - svix@1.76.1: + svix@1.84.1: dependencies: - '@stablelib/base64': 1.0.1 - '@types/node': 22.19.3 - es6-promise: 4.2.8 - fast-sha256: 1.3.0 - url-parse: 1.5.10 + standardwebhooks: 1.0.0 uuid: 10.0.0 tailwind-merge@3.4.0: {} @@ -7946,7 +7922,7 @@ snapshots: dependencies: is-number: 7.0.0 - ts-api-utils@2.1.0(typescript@5.9.3): + ts-api-utils@2.4.0(typescript@5.9.3): dependencies: typescript: 5.9.3 @@ -8003,12 +7979,12 @@ snapshots: possible-typed-array-names: 1.1.0 reflect.getprototypeof: 1.0.10 - typescript-eslint@8.50.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3): + typescript-eslint@8.52.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.50.1(@typescript-eslint/parser@8.50.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/parser': 8.50.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/typescript-estree': 8.50.1(typescript@5.9.3) - '@typescript-eslint/utils': 8.50.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/eslint-plugin': 8.52.0(@typescript-eslint/parser@8.52.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/parser': 8.52.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/typescript-estree': 8.52.0(typescript@5.9.3) + '@typescript-eslint/utils': 8.52.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) eslint: 9.39.2(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: @@ -8023,8 +7999,6 @@ snapshots: has-symbols: 1.1.0 which-boxed-primitive: 1.1.1 - undici-types@6.21.0: {} - undici-types@7.16.0: {} unrs-resolver@1.11.1: @@ -8061,11 +8035,6 @@ snapshots: dependencies: punycode: 2.3.1 - url-parse@1.5.10: - dependencies: - querystringify: 2.2.0 - requires-port: 1.0.0 - use-callback-ref@1.3.3(@types/react@19.2.7)(react@19.2.3): dependencies: react: 19.2.3