mirror of
https://github.com/felipegcoutinho/openmonetis.git
synced 2026-05-09 11:01:45 +00:00
feat(auth): redesign visual das páginas de autenticação
O sidebar de autenticação ganha mockup animado de faturas e três itens de funcionalidade no rodapé, substituindo o texto descritivo anterior. As páginas de login e cadastro recebem gradiente decorativo de fundo e exibem o logo no topo em viewports mobile. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,9 +1,19 @@
|
||||
import { LoginForm } from "@/features/auth/components/login-form";
|
||||
import { Logo } from "@/shared/components/logo";
|
||||
|
||||
export default function LoginPage() {
|
||||
return (
|
||||
<div className="flex min-h-svh flex-col items-center justify-center bg-linear-to-b from-background via-background to-muted/20 px-5 py-8 md:px-8 md:py-10">
|
||||
<div className="w-full max-w-sm md:max-w-5xl">
|
||||
<div className="relative flex min-h-svh flex-col items-center justify-center overflow-hidden bg-linear-to-b from-background via-background to-muted/20 px-5 py-8 md:px-8 md:py-10">
|
||||
<div className="pointer-events-none absolute inset-0">
|
||||
<div className="absolute -right-32 -top-32 h-72 w-72 rounded-full bg-primary/10 blur-3xl" />
|
||||
<div className="absolute -bottom-32 -left-32 h-72 w-72 rounded-full bg-primary/7 blur-3xl" />
|
||||
</div>
|
||||
|
||||
<div className="relative mb-6 flex md:hidden">
|
||||
<Logo variant="compact" colorIcon />
|
||||
</div>
|
||||
|
||||
<div className="relative w-full max-w-sm md:max-w-5xl">
|
||||
<LoginForm />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,9 +1,19 @@
|
||||
import { SignupForm } from "@/features/auth/components/signup-form";
|
||||
import { Logo } from "@/shared/components/logo";
|
||||
|
||||
export default function Page() {
|
||||
export default function SignupPage() {
|
||||
return (
|
||||
<div className="flex min-h-svh flex-col items-center justify-center bg-linear-to-b from-background via-background to-muted/20 px-5 py-8 md:px-8 md:py-10">
|
||||
<div className="w-full max-w-sm md:max-w-5xl">
|
||||
<div className="relative flex min-h-svh flex-col items-center justify-center overflow-hidden bg-linear-to-b from-background via-background to-muted/20 px-5 py-8 md:px-8 md:py-10">
|
||||
<div className="pointer-events-none absolute inset-0">
|
||||
<div className="absolute -right-32 -top-32 h-72 w-72 rounded-full bg-primary/10 blur-3xl" />
|
||||
<div className="absolute -bottom-32 -left-32 h-72 w-72 rounded-full bg-primary/7 blur-3xl" />
|
||||
</div>
|
||||
|
||||
<div className="relative mb-6 flex md:hidden">
|
||||
<Logo variant="compact" colorIcon />
|
||||
</div>
|
||||
|
||||
<div className="relative w-full max-w-sm md:max-w-5xl">
|
||||
<SignupForm />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
89
src/features/auth/components/auth-sidebar-invoices-mock.tsx
Normal file
89
src/features/auth/components/auth-sidebar-invoices-mock.tsx
Normal file
@@ -0,0 +1,89 @@
|
||||
import Image from "next/image";
|
||||
import { resolveLogoSrc } from "@/shared/lib/logo";
|
||||
import { formatCurrency } from "@/shared/utils/currency";
|
||||
|
||||
type MockInvoice = {
|
||||
cardName: string;
|
||||
logo: string;
|
||||
amount: number;
|
||||
dueLabel: string;
|
||||
};
|
||||
|
||||
const MOCK_INVOICES: MockInvoice[] = [
|
||||
{
|
||||
cardName: "Nubank",
|
||||
logo: "nubank.png",
|
||||
amount: 1898,
|
||||
dueLabel: "Vence em 3 dias",
|
||||
},
|
||||
{
|
||||
cardName: "Itaú",
|
||||
logo: "itau.png",
|
||||
amount: 1923,
|
||||
dueLabel: "Vence em 8 dias",
|
||||
},
|
||||
];
|
||||
|
||||
function MockInvoiceItem({
|
||||
invoice,
|
||||
divider,
|
||||
}: {
|
||||
invoice: MockInvoice;
|
||||
divider: boolean;
|
||||
}) {
|
||||
const logoSrc = resolveLogoSrc(invoice.logo);
|
||||
|
||||
return (
|
||||
<div className={divider ? "border-b border-border/60" : undefined}>
|
||||
<div className="flex items-center justify-between py-2.5">
|
||||
<div className="flex min-w-0 flex-1 items-center gap-2.5 py-0.5">
|
||||
<div className="flex size-9 shrink-0 items-center justify-center overflow-hidden rounded-full">
|
||||
{logoSrc && (
|
||||
<Image
|
||||
src={logoSrc}
|
||||
alt={`Logo ${invoice.cardName}`}
|
||||
width={36}
|
||||
height={36}
|
||||
className="h-full w-full object-contain"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<div className="min-w-0">
|
||||
<p className="text-sm font-medium text-foreground">
|
||||
{invoice.cardName}
|
||||
</p>
|
||||
<p className="text-xs text-muted-foreground">{invoice.dueLabel}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex shrink-0 flex-col items-end gap-0.5">
|
||||
<span className="text-sm font-medium tracking-tighter text-foreground">
|
||||
{formatCurrency(invoice.amount)}
|
||||
</span>
|
||||
<span className="text-xs font-medium text-primary">Pagar</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function AuthSidebarInvoicesMock() {
|
||||
return (
|
||||
<div className="rounded-xl border bg-card shadow-sm">
|
||||
<div className="border-b px-4 py-3">
|
||||
<span className="text-sm font-medium text-foreground">Faturas</span>
|
||||
<p className="mt-0.5 text-xs text-muted-foreground">
|
||||
Resumo das faturas do período
|
||||
</p>
|
||||
</div>
|
||||
<div className="px-4">
|
||||
{MOCK_INVOICES.map((invoice, index) => (
|
||||
<MockInvoiceItem
|
||||
key={invoice.cardName}
|
||||
invoice={invoice}
|
||||
divider={index < MOCK_INVOICES.length - 1}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,5 +1,28 @@
|
||||
import {
|
||||
RiBankCardLine,
|
||||
RiBarChart2Line,
|
||||
RiShieldCheckLine,
|
||||
} from "@remixicon/react";
|
||||
import { Logo } from "@/shared/components/logo";
|
||||
import { DotPattern } from "@/shared/components/ui/dot-pattern";
|
||||
import { AuthSidebarInvoicesMock } from "./auth-sidebar-invoices-mock";
|
||||
|
||||
function FeatureItem({
|
||||
icon: Icon,
|
||||
text,
|
||||
}: {
|
||||
icon: React.ComponentType<{ className?: string }>;
|
||||
text: string;
|
||||
}) {
|
||||
return (
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="flex h-7 w-7 shrink-0 items-center justify-center rounded-lg bg-black/12">
|
||||
<Icon className="h-3.5 w-3.5 text-black/55" />
|
||||
</div>
|
||||
<span className="text-sm font-medium text-black/68">{text}</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function AuthSidebar() {
|
||||
return (
|
||||
@@ -15,6 +38,7 @@ function AuthSidebar() {
|
||||
/>
|
||||
<div className="absolute inset-0 bg-linear-to-br from-white/9 via-transparent to-black/7" />
|
||||
</div>
|
||||
|
||||
<div className="relative flex flex-1 flex-col justify-between p-10 lg:p-12">
|
||||
<Logo
|
||||
variant="compact"
|
||||
@@ -22,14 +46,25 @@ function AuthSidebar() {
|
||||
className="opacity-92 [&_img]:brightness-0 [&_img]:saturate-0"
|
||||
/>
|
||||
|
||||
<div className="max-w-sm space-y-4.5">
|
||||
<h2 className="text-[2rem] font-semibold leading-[1.04] tracking-[-0.03em] text-black/84 lg:text-[2.35rem]">
|
||||
Controle suas finanças com clareza e foco diário.
|
||||
</h2>
|
||||
<p className="max-w-2xs text-sm leading-6 text-black/68">
|
||||
Centralize despesas, organize cartões e acompanhe metas mensais em
|
||||
um painel inteligente feito para o seu dia a dia.
|
||||
</p>
|
||||
<div className="flex flex-1 items-center justify-center py-10">
|
||||
<div className="w-full rotate-[1.5deg]">
|
||||
<AuthSidebarInvoicesMock />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-3">
|
||||
<FeatureItem
|
||||
icon={RiBarChart2Line}
|
||||
text="Controle de gastos por categoria"
|
||||
/>
|
||||
<FeatureItem
|
||||
icon={RiBankCardLine}
|
||||
text="Faturas e cartões centralizados"
|
||||
/>
|
||||
<FeatureItem
|
||||
icon={RiShieldCheckLine}
|
||||
text="Seus dados, sem rastreamento"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user