diff --git a/CHANGELOG.md b/CHANGELOG.md index 589e10d..f0e40f0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ e este projeto adere ao [Versionamento Semântico](https://semver.org/lang/pt-BR ### Alterado +- Tipografia: a aplicação passou a carregar apenas a família `America` (`regular`, `medium` e `bold`) como fonte global, removendo a personalização por usuário e a distinção de fonte para valores monetários. - Queries e organização de domínios: o dashboard passou a nomear queries de leitura com sufixo `-queries.ts` e `preferences-queries.ts`, relatórios adotaram nomes explícitos como `cards-report-queries.ts`, `category-report-queries.ts`, `category-chart-queries.ts` e `establishments/queries.ts`, `insights/queries.ts` foi renomeado para `constants.ts` e as leituras reutilizáveis de lançamentos foram concentradas em `transactions/queries.ts`, deixando `page-helpers.ts` focado em parsing, filtros e transformação. ## [2.0.0] - 2026-03-09 diff --git a/README.md b/README.md index 4bca9bb..4a46049 100644 --- a/README.md +++ b/README.md @@ -78,7 +78,7 @@ A ideia é simples: ter um lugar onde consigo ver todas as minhas contas, cartõ 📲 **OpenMonetis Companion** — App Android que captura notificações bancárias (Nubank, Itaú, Bradesco, Inter, C6 e outros) e envia como pré-lançamentos para revisão. [Repositório](https://github.com/felipegcoutinho/openmonetis-companion). -⚙️ **Personalização** — Tema dark/light, modo privacidade, fontes customizáveis, preferências por usuário. +⚙️ **Personalização** — Tema dark/light, modo privacidade e preferências por usuário. ### Stack técnica diff --git a/public/fonts/aeonikfono-medium.woff2 b/public/fonts/aeonikfono-medium.woff2 deleted file mode 100644 index 5c84152..0000000 Binary files a/public/fonts/aeonikfono-medium.woff2 and /dev/null differ diff --git a/public/fonts/aeonikfono-regular.woff2 b/public/fonts/aeonikfono-regular.woff2 deleted file mode 100644 index d61b0a2..0000000 Binary files a/public/fonts/aeonikfono-regular.woff2 and /dev/null differ diff --git a/public/fonts/ai-sans-regular.woff2 b/public/fonts/ai-sans-regular.woff2 deleted file mode 100644 index b323b20..0000000 Binary files a/public/fonts/ai-sans-regular.woff2 and /dev/null differ diff --git a/public/fonts/ai-sans-semibold.woff2 b/public/fonts/ai-sans-semibold.woff2 deleted file mode 100644 index 895cfa9..0000000 Binary files a/public/fonts/ai-sans-semibold.woff2 and /dev/null differ diff --git a/public/fonts/anthropic-sans.woff2 b/public/fonts/anthropic-sans.woff2 deleted file mode 100644 index eddbf30..0000000 Binary files a/public/fonts/anthropic-sans.woff2 and /dev/null differ diff --git a/public/fonts/font_index.ts b/public/fonts/font_index.ts index ef35153..3fe3967 100644 --- a/public/fonts/font_index.ts +++ b/public/fonts/font_index.ts @@ -1,74 +1,6 @@ -import { - Fira_Code, - Fira_Sans, - Geist, - IBM_Plex_Mono, - Inter, - JetBrains_Mono, - Reddit_Sans, - Roboto, - Ubuntu, -} from "next/font/google"; import localFont from "next/font/local"; -const ai_sans = localFont({ - src: [ - { - path: "./ai-sans-regular.woff2", - weight: "400", - style: "normal", - }, - { - path: "./ai-sans-semibold.woff2", - weight: "700", - style: "normal", - }, - ], - display: "swap", - variable: "--font-ai-sans", -}); - -const aeonik = localFont({ - src: [ - { - path: "./aeonikfono-regular.woff2", - weight: "400", - style: "normal", - }, - { - path: "./aeonikfono-medium.woff2", - weight: "600", - style: "normal", - }, - ], - display: "swap", - variable: "--font-aeonik", -}); - -const itau = localFont({ - src: [ - { - path: "./itau-text-regular.woff2", - weight: "400", - style: "normal", - }, - { - path: "./itau-text-bold.woff2", - weight: "700", - style: "normal", - }, - ], - display: "swap", - variable: "--font-itau", -}); - -const anthropic_sans = localFont({ - src: "./anthropic-sans.woff2", - display: "swap", - variable: "--font-anthropic-sans", -}); - -const america = localFont({ +export const america = localFont({ src: [ { path: "./america-regular.woff2", @@ -77,12 +9,12 @@ const america = localFont({ }, { path: "./america-medium.woff2", - weight: "700", + weight: "500", style: "normal", }, { path: "./america-bold.woff2", - weight: "900", + weight: "700", style: "normal", }, ], @@ -90,144 +22,4 @@ const america = localFont({ variable: "--font-america", }); -const inter = Inter({ - subsets: ["latin"], - display: "swap", - variable: "--font-inter", -}); - -const geist_sans = Geist({ - subsets: ["latin"], - display: "swap", - variable: "--font-geist", -}); - -const roboto = Roboto({ - subsets: ["latin"], - display: "swap", - variable: "--font-roboto", -}); - -const reddit_sans = Reddit_Sans({ - subsets: ["latin"], - display: "swap", - variable: "--font-reddit-sans", -}); - -const fira_sans = Fira_Sans({ - weight: ["400", "500", "600", "700"], - subsets: ["latin"], - display: "swap", - variable: "--font-fira-sans", -}); - -const ubuntu = Ubuntu({ - weight: ["400"], - subsets: ["latin"], - display: "swap", - variable: "--font-ubuntu", -}); - -const jetbrains_mono = JetBrains_Mono({ - subsets: ["latin"], - display: "swap", - variable: "--font-jetbrains-mono", -}); - -const fira_code = Fira_Code({ - subsets: ["latin"], - display: "swap", - variable: "--font-fira-code", -}); - -const ibm_plex_mono = IBM_Plex_Mono({ - weight: ["400", "500", "600"], - subsets: ["latin"], - display: "swap", - variable: "--font-ibm-plex-mono", -}); - -export const DEFAULT_FONT_KEY = "ai-sans"; - -export const FONT_OPTIONS = [ - { key: "ai-sans", label: "Open AI Sans", variable: "var(--font-ai-sans)" }, - { key: "america", label: "America", variable: "var(--font-america)" }, - { key: "aeonik", label: "Aeonik", variable: "var(--font-aeonik)" }, - { - key: "anthropic-sans", - label: "Anthropic Sans", - variable: "var(--font-anthropic-sans)", - }, - { key: "fira-code", label: "Fira Code", variable: "var(--font-fira-code)" }, - { - key: "fira-sans", - label: "Fira Sans", - variable: "var(--font-fira-sans)", - }, - { - key: "itau", - label: "Itaú Sans", - variable: "var(--font-itau)", - }, - { key: "geist", label: "Geist Sans", variable: "var(--font-geist)" }, - { - key: "ibm-plex-mono", - label: "IBM Plex Mono", - variable: "var(--font-ibm-plex-mono)", - }, - { key: "inter", label: "Inter", variable: "var(--font-inter)" }, - { - key: "jetbrains-mono", - label: "JetBrains Mono", - variable: "var(--font-jetbrains-mono)", - }, - { - key: "reddit-sans", - label: "Reddit Sans", - variable: "var(--font-reddit-sans)", - }, - { key: "roboto", label: "Roboto", variable: "var(--font-roboto)" }, - { key: "ubuntu", label: "Ubuntu", variable: "var(--font-ubuntu)" }, -] as const; - -export type FontKey = (typeof FONT_OPTIONS)[number]["key"]; - -export const FONT_KEYS = FONT_OPTIONS.map((option) => option.key) as [ - FontKey, - ...FontKey[], -]; - -const VALID_FONT_KEY_SET = new Set(FONT_KEYS); - -const allFonts = [ - ai_sans, - anthropic_sans, - inter, - geist_sans, - roboto, - reddit_sans, - fira_sans, - ubuntu, - jetbrains_mono, - fira_code, - ibm_plex_mono, - itau, - america, - aeonik, -]; - -export const allFontVariables = allFonts.map((f) => f.variable).join(" "); - -function isValidFontKey(value: string): value is FontKey { - return VALID_FONT_KEY_SET.has(value); -} - -export function normalizeFontKey(value: string | null | undefined): FontKey { - if (!value) return DEFAULT_FONT_KEY; - return isValidFontKey(value) ? value : DEFAULT_FONT_KEY; -} - -export function getFontVariable(key: string): string { - const option = FONT_OPTIONS.find((o) => o.key === key); - return option?.variable ?? `var(--font-${DEFAULT_FONT_KEY})`; -} +export const americaFontVariable = america.variable; diff --git a/public/fonts/itau-text-bold.woff2 b/public/fonts/itau-text-bold.woff2 deleted file mode 100644 index 102cebb..0000000 Binary files a/public/fonts/itau-text-bold.woff2 and /dev/null differ diff --git a/public/fonts/itau-text-regular.woff2 b/public/fonts/itau-text-regular.woff2 deleted file mode 100644 index 35149a9..0000000 Binary files a/public/fonts/itau-text-regular.woff2 and /dev/null differ diff --git a/src/app/(dashboard)/layout.tsx b/src/app/(dashboard)/layout.tsx index 8a9b543..f90d4ae 100644 --- a/src/app/(dashboard)/layout.tsx +++ b/src/app/(dashboard)/layout.tsx @@ -1,12 +1,10 @@ import { fetchDashboardNotifications } from "@/features/dashboard/notifications-queries"; import { fetchPendingInboxCount } from "@/features/inbox/queries"; import { AppNavbar } from "@/shared/components/navigation/navbar/app-navbar"; -import { FontProvider } from "@/shared/components/providers/font-provider"; import { PrivacyProvider } from "@/shared/components/providers/privacy-provider"; import { getUserSession } from "@/shared/lib/auth/server"; import { fetchPagadoresWithAccess } from "@/shared/lib/payers/access"; import { PAGADOR_ROLE_ADMIN } from "@/shared/lib/payers/constants"; -import { fetchUserFontPreferences } from "@/shared/lib/preferences/fonts"; import { parsePeriodParam } from "@/shared/utils/period"; export default async function DashboardLayout({ @@ -36,35 +34,27 @@ export default async function DashboardLayout({ const { period: currentPeriod } = parsePeriodParam( singlePeriodoParam ?? null, ); - // Buscar notificações, contagem de pré-lançamentos e preferências de fonte em paralelo - const [notificationsSnapshot, preLancamentosCount, fontPrefs] = - await Promise.all([ - fetchDashboardNotifications(session.user.id, currentPeriod), - fetchPendingInboxCount(session.user.id), - fetchUserFontPreferences(session.user.id), - ]); + const [notificationsSnapshot, preLancamentosCount] = await Promise.all([ + fetchDashboardNotifications(session.user.id, currentPeriod), + fetchPendingInboxCount(session.user.id), + ]); return ( - - - -
-
-
-
- {children} -
+ + +
+
+
+
+ {children}
- - +
+ ); } diff --git a/src/app/(dashboard)/settings/page.tsx b/src/app/(dashboard)/settings/page.tsx index 450667e..4d5fe5a 100644 --- a/src/app/(dashboard)/settings/page.tsx +++ b/src/app/(dashboard)/settings/page.tsx @@ -10,7 +10,6 @@ import { UpdateEmailForm } from "@/features/settings/components/update-email-for import { UpdateNameForm } from "@/features/settings/components/update-name-form"; import { UpdatePasswordForm } from "@/features/settings/components/update-password-form"; import { fetchAjustesPageData } from "@/features/settings/queries"; -import { DEFAULT_FONT_KEY } from "@/public/fonts/font_index"; import { Card } from "@/shared/components/ui/card"; import { Tabs, @@ -78,8 +77,6 @@ export default async function Page() { lancamentosColumnOrder={ userPreferences?.lancamentosColumnOrder ?? null } - systemFont={userPreferences?.systemFont ?? DEFAULT_FONT_KEY} - moneyFont={userPreferences?.moneyFont ?? DEFAULT_FONT_KEY} />
diff --git a/src/app/globals.css b/src/app/globals.css index a5668fe..1d5c829 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -9,10 +9,6 @@ } :root { - /* Font customization */ - --font-app: var(--font-ai-sans); - --font-money: var(--font-ai-sans); - /* Base surfaces - warm cream with subtle orange undertone */ --background: oklch(98.01% 0.00331 67.026); --foreground: #201207; @@ -186,8 +182,7 @@ } @theme inline { - --default-font-family: var(--font-app); - --default-mono-font-family: var(--font-money); + --default-font-family: var(--font-america); --color-background: var(--background); --color-foreground: var(--foreground); --color-card: var(--card); @@ -259,6 +254,7 @@ body { @apply bg-background text-foreground; + font-family: var(--font-america), sans-serif; } *::selection { diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 0ab25e7..3fac6f2 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,10 +1,10 @@ import { Analytics } from "@vercel/analytics/next"; import { SpeedInsights } from "@vercel/speed-insights/next"; import type { Metadata } from "next"; -import { allFontVariables } from "@/public/fonts/font_index"; import { ThemeProvider } from "@/shared/components/providers/theme-provider"; import { Toaster } from "@/shared/components/ui/sonner"; import "./globals.css"; +import { america } from "@/public/fonts/font_index"; export const metadata: Metadata = { title: { @@ -21,7 +21,11 @@ export default function RootLayout({ children: React.ReactNode; }>) { return ( - + diff --git a/src/features/settings/actions.ts b/src/features/settings/actions.ts index 0186873..5330eec 100644 --- a/src/features/settings/actions.ts +++ b/src/features/settings/actions.ts @@ -7,7 +7,6 @@ import { revalidatePath } from "next/cache"; import { headers } from "next/headers"; import { z } from "zod"; import { account, pagadores, tokensApi } from "@/db/schema"; -import { DEFAULT_FONT_KEY, FONT_KEYS } from "@/public/fonts/font_index"; import { auth } from "@/shared/lib/auth/config"; import { db, schema } from "@/shared/lib/db"; import { PAGADOR_ROLE_ADMIN } from "@/shared/lib/payers/constants"; @@ -56,8 +55,6 @@ const deleteAccountSchema = z.object({ const updatePreferencesSchema = z.object({ extratoNoteAsColumn: z.boolean(), lancamentosColumnOrder: z.array(z.string()).nullable(), - systemFont: z.enum(FONT_KEYS).default(DEFAULT_FONT_KEY), - moneyFont: z.enum(FONT_KEYS).default(DEFAULT_FONT_KEY), }); // Actions @@ -404,8 +401,6 @@ export async function updatePreferencesAction( .set({ extratoNoteAsColumn: validated.extratoNoteAsColumn, lancamentosColumnOrder: validated.lancamentosColumnOrder, - systemFont: validated.systemFont, - moneyFont: validated.moneyFont, updatedAt: new Date(), }) .where(eq(schema.preferenciasUsuario.userId, session.user.id)); @@ -415,8 +410,6 @@ export async function updatePreferencesAction( userId: session.user.id, extratoNoteAsColumn: validated.extratoNoteAsColumn, lancamentosColumnOrder: validated.lancamentosColumnOrder, - systemFont: validated.systemFont, - moneyFont: validated.moneyFont, }); } diff --git a/src/features/settings/components/preferences-form.tsx b/src/features/settings/components/preferences-form.tsx index e75748d..3e26839 100644 --- a/src/features/settings/components/preferences-form.tsx +++ b/src/features/settings/components/preferences-form.tsx @@ -18,31 +18,20 @@ import { import { CSS } from "@dnd-kit/utilities"; import { RiDragMove2Line } from "@remixicon/react"; import { useRouter } from "next/navigation"; -import { useEffect, useState, useTransition } from "react"; +import { useState, useTransition } from "react"; import { toast } from "sonner"; import { updatePreferencesAction } from "@/features/settings/actions"; import { DEFAULT_LANCAMENTOS_COLUMN_ORDER, LANCAMENTOS_COLUMN_LABELS, } from "@/features/transactions/column-order"; -import { FONT_OPTIONS } from "@/public/fonts/font_index"; -import { useFont } from "@/shared/components/providers/font-provider"; import { Button } from "@/shared/components/ui/button"; import { Label } from "@/shared/components/ui/label"; -import { - Select, - SelectContent, - SelectItem, - SelectTrigger, - SelectValue, -} from "@/shared/components/ui/select"; import { Switch } from "@/shared/components/ui/switch"; interface PreferencesFormProps { extratoNoteAsColumn: boolean; lancamentosColumnOrder: string[] | null; - systemFont: string; - moneyFont: string; } function SortableColumnItem({ id }: { id: string }) { @@ -85,8 +74,6 @@ function SortableColumnItem({ id }: { id: string }) { export function PreferencesForm({ extratoNoteAsColumn: initialExtratoNoteAsColumn, lancamentosColumnOrder: initialColumnOrder, - systemFont: initialSystemFont, - moneyFont: initialMoneyFont, }: PreferencesFormProps) { const router = useRouter(); const [isPending, startTransition] = useTransition(); @@ -98,9 +85,6 @@ export function PreferencesForm({ ? initialColumnOrder : DEFAULT_LANCAMENTOS_COLUMN_ORDER, ); - const [selectedSystemFont, setSelectedSystemFont] = - useState(initialSystemFont); - const [selectedMoneyFont, setSelectedMoneyFont] = useState(initialMoneyFont); const sensors = useSensors( useSensor(PointerSensor, { activationConstraint: { distance: 8 } }), @@ -118,17 +102,6 @@ export function PreferencesForm({ } }; - const fontCtx = useFont(); - - // Live preview: update CSS vars when font selection changes - useEffect(() => { - fontCtx.setSystemFont(selectedSystemFont); - }, [selectedSystemFont, fontCtx.setSystemFont]); - - useEffect(() => { - fontCtx.setMoneyFont(selectedMoneyFont); - }, [selectedMoneyFont, fontCtx.setMoneyFont]); - const handleSubmit = async (event: React.FormEvent) => { event.preventDefault(); @@ -136,8 +109,6 @@ export function PreferencesForm({ const result = await updatePreferencesAction({ extratoNoteAsColumn, lancamentosColumnOrder: columnOrder, - systemFont: selectedSystemFont, - moneyFont: selectedMoneyFont, }); if (result.success) { @@ -151,70 +122,6 @@ export function PreferencesForm({ return (
- {/* Seção 1: Tipografia */} -
-
-

Tipografia

-

- Personalize as fontes usadas na interface e nos valores monetários. -

-
- - {/* Fonte do sistema */} -
- - -
- - {/* Fonte de valores */} -
- - -
-
- -
- {/* Seção: Extrato / Lançamentos */}
diff --git a/src/features/settings/queries.ts b/src/features/settings/queries.ts index 8d32fd1..f9e6003 100644 --- a/src/features/settings/queries.ts +++ b/src/features/settings/queries.ts @@ -1,13 +1,10 @@ import { desc, eq } from "drizzle-orm"; import { tokensApi } from "@/db/schema"; -import { type FontKey, normalizeFontKey } from "@/public/fonts/font_index"; import { db, schema } from "@/shared/lib/db"; export interface UserPreferences { extratoNoteAsColumn: boolean; lancamentosColumnOrder: string[] | null; - systemFont: FontKey; - moneyFont: FontKey; } export interface ApiToken { @@ -35,8 +32,6 @@ export async function fetchUserPreferences( .select({ extratoNoteAsColumn: schema.preferenciasUsuario.extratoNoteAsColumn, lancamentosColumnOrder: schema.preferenciasUsuario.lancamentosColumnOrder, - systemFont: schema.preferenciasUsuario.systemFont, - moneyFont: schema.preferenciasUsuario.moneyFont, }) .from(schema.preferenciasUsuario) .where(eq(schema.preferenciasUsuario.userId, userId)) @@ -44,11 +39,7 @@ export async function fetchUserPreferences( if (!result[0]) return null; - return { - ...result[0], - systemFont: normalizeFontKey(result[0].systemFont), - moneyFont: normalizeFontKey(result[0].moneyFont), - }; + return result[0]; } export async function fetchApiTokens(userId: string): Promise { diff --git a/src/shared/components/money-values.tsx b/src/shared/components/money-values.tsx index 594fb01..100e183 100644 --- a/src/shared/components/money-values.tsx +++ b/src/shared/components/money-values.tsx @@ -19,7 +19,6 @@ function MoneyValues({ amount, className, showPositiveSign = false }: Props) { return ( void; - setMoneyFont: (key: string) => void; -}; - -const FontContext = createContext(null); - -export function FontProvider({ - systemFont: initialSystemFont, - moneyFont: initialMoneyFont, - children, -}: { - systemFont: string; - moneyFont: string; - children: React.ReactNode; -}) { - const [systemFont, setSystemFontState] = useState(initialSystemFont); - const [moneyFont, setMoneyFontState] = useState(initialMoneyFont); - - useEffect(() => { - document.documentElement.style.setProperty( - "--font-app", - getFontVariable(systemFont), - ); - document.documentElement.style.setProperty( - "--font-money", - getFontVariable(moneyFont), - ); - }, [systemFont, moneyFont]); - - const value = useMemo( - () => ({ - systemFont, - moneyFont, - setSystemFont: setSystemFontState, - setMoneyFont: setMoneyFontState, - }), - [systemFont, moneyFont], - ); - - return ( - <> -