feat: amplia opcoes de fontes e normaliza preferencias
This commit is contained in:
@@ -10,6 +10,7 @@ import { account, pagadores, tokensApi } from "@/db/schema";
|
|||||||
import { auth } from "@/lib/auth/config";
|
import { auth } from "@/lib/auth/config";
|
||||||
import { db, schema } from "@/lib/db";
|
import { db, schema } from "@/lib/db";
|
||||||
import { PAGADOR_ROLE_ADMIN } from "@/lib/pagadores/constants";
|
import { PAGADOR_ROLE_ADMIN } from "@/lib/pagadores/constants";
|
||||||
|
import { DEFAULT_FONT_KEY, FONT_KEYS } from "@/public/fonts/font_index";
|
||||||
|
|
||||||
type ActionResponse<T = void> = {
|
type ActionResponse<T = void> = {
|
||||||
success: boolean;
|
success: boolean;
|
||||||
@@ -52,28 +53,12 @@ const deleteAccountSchema = z.object({
|
|||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
const VALID_FONTS = [
|
|
||||||
"ai-sans",
|
|
||||||
"anthropic-sans",
|
|
||||||
"fira-code",
|
|
||||||
"fira-sans",
|
|
||||||
"geist",
|
|
||||||
"ibm-plex-mono",
|
|
||||||
"inter",
|
|
||||||
"jetbrains-mono",
|
|
||||||
"reddit-sans",
|
|
||||||
"roboto",
|
|
||||||
"sf-pro-display",
|
|
||||||
"sf-pro-rounded",
|
|
||||||
"ubuntu",
|
|
||||||
] as const;
|
|
||||||
|
|
||||||
const updatePreferencesSchema = z.object({
|
const updatePreferencesSchema = z.object({
|
||||||
disableMagnetlines: z.boolean(),
|
disableMagnetlines: z.boolean(),
|
||||||
extratoNoteAsColumn: z.boolean(),
|
extratoNoteAsColumn: z.boolean(),
|
||||||
lancamentosColumnOrder: z.array(z.string()).nullable(),
|
lancamentosColumnOrder: z.array(z.string()).nullable(),
|
||||||
systemFont: z.enum(VALID_FONTS).default("ai-sans"),
|
systemFont: z.enum(FONT_KEYS).default(DEFAULT_FONT_KEY),
|
||||||
moneyFont: z.enum(VALID_FONTS).default("ai-sans"),
|
moneyFont: z.enum(FONT_KEYS).default(DEFAULT_FONT_KEY),
|
||||||
});
|
});
|
||||||
|
|
||||||
// Actions
|
// Actions
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
import { desc, eq } from "drizzle-orm";
|
import { desc, eq } from "drizzle-orm";
|
||||||
import { tokensApi } from "@/db/schema";
|
import { tokensApi } from "@/db/schema";
|
||||||
import { db, schema } from "@/lib/db";
|
import { db, schema } from "@/lib/db";
|
||||||
|
import { type FontKey, normalizeFontKey } from "@/public/fonts/font_index";
|
||||||
|
|
||||||
export interface UserPreferences {
|
export interface UserPreferences {
|
||||||
disableMagnetlines: boolean;
|
disableMagnetlines: boolean;
|
||||||
extratoNoteAsColumn: boolean;
|
extratoNoteAsColumn: boolean;
|
||||||
lancamentosColumnOrder: string[] | null;
|
lancamentosColumnOrder: string[] | null;
|
||||||
systemFont: string;
|
systemFont: FontKey;
|
||||||
moneyFont: string;
|
moneyFont: FontKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ApiToken {
|
export interface ApiToken {
|
||||||
@@ -43,7 +44,13 @@ export async function fetchUserPreferences(
|
|||||||
.where(eq(schema.preferenciasUsuario.userId, userId))
|
.where(eq(schema.preferenciasUsuario.userId, userId))
|
||||||
.limit(1);
|
.limit(1);
|
||||||
|
|
||||||
return result[0] || null;
|
if (!result[0]) return null;
|
||||||
|
|
||||||
|
return {
|
||||||
|
...result[0],
|
||||||
|
systemFont: normalizeFontKey(result[0].systemFont),
|
||||||
|
moneyFont: normalizeFontKey(result[0].moneyFont),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchApiTokens(userId: string): Promise<ApiToken[]> {
|
export async function fetchApiTokens(userId: string): Promise<ApiToken[]> {
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import { UpdatePasswordForm } from "@/components/ajustes/update-password-form";
|
|||||||
import { Card } from "@/components/ui/card";
|
import { Card } from "@/components/ui/card";
|
||||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||||
import { auth } from "@/lib/auth/config";
|
import { auth } from "@/lib/auth/config";
|
||||||
|
import { DEFAULT_FONT_KEY } from "@/public/fonts/font_index";
|
||||||
import { fetchAjustesPageData } from "./data";
|
import { fetchAjustesPageData } from "./data";
|
||||||
|
|
||||||
export default async function Page() {
|
export default async function Page() {
|
||||||
@@ -75,8 +76,8 @@ export default async function Page() {
|
|||||||
lancamentosColumnOrder={
|
lancamentosColumnOrder={
|
||||||
userPreferences?.lancamentosColumnOrder ?? null
|
userPreferences?.lancamentosColumnOrder ?? null
|
||||||
}
|
}
|
||||||
systemFont={userPreferences?.systemFont ?? "ai-sans"}
|
systemFont={userPreferences?.systemFont ?? DEFAULT_FONT_KEY}
|
||||||
moneyFont={userPreferences?.moneyFont ?? "ai-sans"}
|
moneyFont={userPreferences?.moneyFont ?? DEFAULT_FONT_KEY}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ import {
|
|||||||
DEFAULT_LANCAMENTOS_COLUMN_ORDER,
|
DEFAULT_LANCAMENTOS_COLUMN_ORDER,
|
||||||
LANCAMENTOS_COLUMN_LABELS,
|
LANCAMENTOS_COLUMN_LABELS,
|
||||||
} from "@/lib/lancamentos/column-order";
|
} from "@/lib/lancamentos/column-order";
|
||||||
import { FONT_OPTIONS, getFontVariable } from "@/public/fonts/font_index";
|
import { FONT_OPTIONS } from "@/public/fonts/font_index";
|
||||||
|
|
||||||
interface PreferencesFormProps {
|
interface PreferencesFormProps {
|
||||||
disableMagnetlines: boolean;
|
disableMagnetlines: boolean;
|
||||||
@@ -189,14 +189,6 @@ export function PreferencesForm({
|
|||||||
))}
|
))}
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
</Select>
|
</Select>
|
||||||
<p
|
|
||||||
className="text-sm text-muted-foreground pt-1"
|
|
||||||
style={{
|
|
||||||
fontFamily: getFontVariable(selectedSystemFont),
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Suas finanças em um só lugar
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Fonte de valores */}
|
{/* Fonte de valores */}
|
||||||
@@ -223,14 +215,6 @@ export function PreferencesForm({
|
|||||||
))}
|
))}
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
</Select>
|
</Select>
|
||||||
<p
|
|
||||||
className="text-sm text-muted-foreground pt-1 tabular-nums"
|
|
||||||
style={{
|
|
||||||
fontFamily: getFontVariable(selectedMoneyFont),
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
R$ 1.234,56
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +1,20 @@
|
|||||||
import { eq } from "drizzle-orm";
|
import { eq } from "drizzle-orm";
|
||||||
import { cache } from "react";
|
import { cache } from "react";
|
||||||
import { db, schema } from "@/lib/db";
|
import { db, schema } from "@/lib/db";
|
||||||
|
import {
|
||||||
|
DEFAULT_FONT_KEY,
|
||||||
|
type FontKey,
|
||||||
|
normalizeFontKey,
|
||||||
|
} from "@/public/fonts/font_index";
|
||||||
|
|
||||||
export type FontPreferences = {
|
export type FontPreferences = {
|
||||||
systemFont: string;
|
systemFont: FontKey;
|
||||||
moneyFont: string;
|
moneyFont: FontKey;
|
||||||
};
|
};
|
||||||
|
|
||||||
const DEFAULT_FONT_PREFS: FontPreferences = {
|
const DEFAULT_FONT_PREFS: FontPreferences = {
|
||||||
systemFont: "ai-sans",
|
systemFont: DEFAULT_FONT_KEY,
|
||||||
moneyFont: "ai-sans",
|
moneyFont: DEFAULT_FONT_KEY,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const fetchUserFontPreferences = cache(
|
export const fetchUserFontPreferences = cache(
|
||||||
@@ -26,8 +31,8 @@ export const fetchUserFontPreferences = cache(
|
|||||||
if (!result[0]) return DEFAULT_FONT_PREFS;
|
if (!result[0]) return DEFAULT_FONT_PREFS;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
systemFont: result[0].systemFont,
|
systemFont: normalizeFontKey(result[0].systemFont),
|
||||||
moneyFont: result[0].moneyFont,
|
moneyFont: normalizeFontKey(result[0].moneyFont),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -14,12 +14,12 @@ import localFont from "next/font/local";
|
|||||||
const ai_sans = localFont({
|
const ai_sans = localFont({
|
||||||
src: [
|
src: [
|
||||||
{
|
{
|
||||||
path: "./AISans-Regular.woff2",
|
path: "./ai-sans-regular.woff2",
|
||||||
weight: "400",
|
weight: "400",
|
||||||
style: "normal",
|
style: "normal",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "./AISans-Semibold.woff2",
|
path: "./ai-sans-semibold.woff2",
|
||||||
weight: "700",
|
weight: "700",
|
||||||
style: "normal",
|
style: "normal",
|
||||||
},
|
},
|
||||||
@@ -28,66 +28,29 @@ const ai_sans = localFont({
|
|||||||
variable: "--font-ai-sans",
|
variable: "--font-ai-sans",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
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({
|
const anthropic_sans = localFont({
|
||||||
src: "./anthropicSans.woff2",
|
src: "./anthropic-sans.woff2",
|
||||||
display: "swap",
|
display: "swap",
|
||||||
variable: "--font-anthropic-sans",
|
variable: "--font-anthropic-sans",
|
||||||
});
|
});
|
||||||
|
|
||||||
const sf_pro_display = localFont({
|
|
||||||
src: [
|
|
||||||
{
|
|
||||||
path: "./SF-Pro-Display-Regular.otf",
|
|
||||||
weight: "400",
|
|
||||||
style: "normal",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "./SF-Pro-Display-Medium.otf",
|
|
||||||
weight: "500",
|
|
||||||
style: "normal",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "./SF-Pro-Display-Semibold.otf",
|
|
||||||
weight: "600",
|
|
||||||
style: "normal",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "./SF-Pro-Display-Bold.otf",
|
|
||||||
weight: "700",
|
|
||||||
style: "normal",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
display: "swap",
|
|
||||||
variable: "--font-sf-pro-display",
|
|
||||||
});
|
|
||||||
|
|
||||||
const sf_pro_rounded = localFont({
|
|
||||||
src: [
|
|
||||||
{
|
|
||||||
path: "./SF-Pro-Rounded-Regular.otf",
|
|
||||||
weight: "400",
|
|
||||||
style: "normal",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "./SF-Pro-Rounded-Medium.otf",
|
|
||||||
weight: "500",
|
|
||||||
style: "normal",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "./SF-Pro-Rounded-Semibold.otf",
|
|
||||||
weight: "600",
|
|
||||||
style: "normal",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "./SF-Pro-Rounded-Bold.otf",
|
|
||||||
weight: "700",
|
|
||||||
style: "normal",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
display: "swap",
|
|
||||||
variable: "--font-sf-pro-rounded",
|
|
||||||
});
|
|
||||||
|
|
||||||
const inter = Inter({
|
const inter = Inter({
|
||||||
subsets: ["latin"],
|
subsets: ["latin"],
|
||||||
display: "swap",
|
display: "swap",
|
||||||
@@ -145,14 +108,10 @@ const ibm_plex_mono = IBM_Plex_Mono({
|
|||||||
variable: "--font-ibm-plex-mono",
|
variable: "--font-ibm-plex-mono",
|
||||||
});
|
});
|
||||||
|
|
||||||
export type FontOption = {
|
export const DEFAULT_FONT_KEY = "ai-sans";
|
||||||
key: string;
|
|
||||||
label: string;
|
|
||||||
variable: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const FONT_OPTIONS: FontOption[] = [
|
export const FONT_OPTIONS = [
|
||||||
{ key: "ai-sans", label: "AI Sans", variable: "var(--font-ai-sans)" },
|
{ key: "ai-sans", label: "Open AI Sans", variable: "var(--font-ai-sans)" },
|
||||||
{
|
{
|
||||||
key: "anthropic-sans",
|
key: "anthropic-sans",
|
||||||
label: "Anthropic Sans",
|
label: "Anthropic Sans",
|
||||||
@@ -164,6 +123,11 @@ export const FONT_OPTIONS: FontOption[] = [
|
|||||||
label: "Fira Sans",
|
label: "Fira Sans",
|
||||||
variable: "var(--font-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: "geist", label: "Geist Sans", variable: "var(--font-geist)" },
|
||||||
{
|
{
|
||||||
key: "ibm-plex-mono",
|
key: "ibm-plex-mono",
|
||||||
@@ -182,29 +146,21 @@ export const FONT_OPTIONS: FontOption[] = [
|
|||||||
variable: "var(--font-reddit-sans)",
|
variable: "var(--font-reddit-sans)",
|
||||||
},
|
},
|
||||||
{ key: "roboto", label: "Roboto", variable: "var(--font-roboto)" },
|
{ key: "roboto", label: "Roboto", variable: "var(--font-roboto)" },
|
||||||
{
|
|
||||||
key: "sf-pro-display",
|
|
||||||
label: "SF Pro Display",
|
|
||||||
variable: "var(--font-sf-pro-display)",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "sf-pro-rounded",
|
|
||||||
label: "SF Pro Rounded",
|
|
||||||
variable: "var(--font-sf-pro-rounded)",
|
|
||||||
},
|
|
||||||
{ key: "ubuntu", label: "Ubuntu", variable: "var(--font-ubuntu)" },
|
{ 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[],
|
||||||
];
|
];
|
||||||
|
|
||||||
/** @deprecated Use FONT_OPTIONS */
|
const VALID_FONT_KEY_SET = new Set<string>(FONT_KEYS);
|
||||||
export const SYSTEM_FONT_OPTIONS = FONT_OPTIONS;
|
|
||||||
/** @deprecated Use FONT_OPTIONS */
|
|
||||||
export const MONEY_FONT_OPTIONS = FONT_OPTIONS;
|
|
||||||
|
|
||||||
const allFonts = [
|
const allFonts = [
|
||||||
ai_sans,
|
ai_sans,
|
||||||
anthropic_sans,
|
anthropic_sans,
|
||||||
sf_pro_display,
|
|
||||||
sf_pro_rounded,
|
|
||||||
inter,
|
inter,
|
||||||
geist_sans,
|
geist_sans,
|
||||||
roboto,
|
roboto,
|
||||||
@@ -214,15 +170,21 @@ const allFonts = [
|
|||||||
jetbrains_mono,
|
jetbrains_mono,
|
||||||
fira_code,
|
fira_code,
|
||||||
ibm_plex_mono,
|
ibm_plex_mono,
|
||||||
|
itau,
|
||||||
];
|
];
|
||||||
|
|
||||||
export const allFontVariables = allFonts.map((f) => f.variable).join(" ");
|
export const allFontVariables = allFonts.map((f) => f.variable).join(" ");
|
||||||
|
|
||||||
// Backward compatibility
|
function isValidFontKey(value: string): value is FontKey {
|
||||||
export const main_font = ai_sans;
|
return VALID_FONT_KEY_SET.has(value);
|
||||||
export const money_font = ai_sans;
|
}
|
||||||
|
|
||||||
|
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 {
|
export function getFontVariable(key: string): string {
|
||||||
const option = FONT_OPTIONS.find((o) => o.key === key);
|
const option = FONT_OPTIONS.find((o) => o.key === key);
|
||||||
return option?.variable ?? "var(--font-ai-sans)";
|
return option?.variable ?? `var(--font-${DEFAULT_FONT_KEY})`;
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
public/fonts/itau-text-bold.woff2
Normal file
BIN
public/fonts/itau-text-bold.woff2
Normal file
Binary file not shown.
BIN
public/fonts/itau-text-regular.woff2
Normal file
BIN
public/fonts/itau-text-regular.woff2
Normal file
Binary file not shown.
Reference in New Issue
Block a user