refactor(auth): migrate shell styles to tailwind
This commit is contained in:
@@ -13,7 +13,6 @@ import { ROUTES } from "@/router/routes";
|
||||
import { useAppNavigator } from "@/router/use-app-navigator";
|
||||
|
||||
import { AuthBackground, AuthPanel } from "./components";
|
||||
import styles from "./components/auth-screen.module.css";
|
||||
import { Logger } from "@/utils";
|
||||
|
||||
const log = new Logger("AppAuthAuthScreen");
|
||||
@@ -51,9 +50,15 @@ export function AuthScreen() {
|
||||
|
||||
return (
|
||||
<MobileShell>
|
||||
<div className={styles.wrapper}>
|
||||
<div className="relative flex min-h-[var(--app-viewport-height,100dvh)] w-full flex-1 flex-col overflow-hidden bg-[#fbf1f2]">
|
||||
<AuthBackground />
|
||||
<div className={styles.content}>
|
||||
<div
|
||||
className="relative z-[2] flex flex-auto flex-col justify-center"
|
||||
style={{
|
||||
padding:
|
||||
"calc(var(--page-padding-y, var(--spacing-lg)) + var(--app-safe-top, 0px)) calc(var(--page-padding-x, var(--spacing-lg)) + var(--app-safe-right, 0px)) calc(var(--page-padding-y, var(--spacing-lg)) + var(--app-safe-bottom, 0px)) calc(var(--page-padding-x, var(--spacing-lg)) + var(--app-safe-left, 0px))",
|
||||
}}
|
||||
>
|
||||
<AuthPanel />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
import { renderToStaticMarkup } from "react-dom/server";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
|
||||
import { AuthBackground } from "../auth-background";
|
||||
import { AuthErrorMessage } from "../auth-error-message";
|
||||
import { EmailLoginForm } from "../email-login-form";
|
||||
import { EmailRegisterForm } from "../email-register-form";
|
||||
|
||||
vi.mock("@/stores/auth/auth-context", () => ({
|
||||
useAuthDispatch: () => vi.fn(),
|
||||
}));
|
||||
|
||||
describe("auth Tailwind components", () => {
|
||||
it("renders AuthErrorMessage only when a message is present", () => {
|
||||
@@ -12,4 +19,34 @@ describe("auth Tailwind components", () => {
|
||||
expect(html).toContain("text-error");
|
||||
expect(html).toContain("Invalid email");
|
||||
});
|
||||
|
||||
it("renders EmailLoginForm with Tailwind form layout", () => {
|
||||
const html = renderToStaticMarkup(<EmailLoginForm />);
|
||||
|
||||
expect(html).toContain("<form");
|
||||
expect(html).toContain("flex");
|
||||
expect(html).toContain("w-full");
|
||||
expect(html).toContain("gap-md");
|
||||
expect(html).toContain("Login");
|
||||
});
|
||||
|
||||
it("renders EmailRegisterForm with Tailwind form layout", () => {
|
||||
const html = renderToStaticMarkup(<EmailRegisterForm />);
|
||||
|
||||
expect(html).toContain("<form");
|
||||
expect(html).toContain("flex");
|
||||
expect(html).toContain("w-full");
|
||||
expect(html).toContain("gap-md");
|
||||
expect(html).toContain("Register");
|
||||
});
|
||||
|
||||
it("renders AuthBackground with Tailwind layout classes", () => {
|
||||
const html = renderToStaticMarkup(<AuthBackground />);
|
||||
|
||||
expect(html).toContain("absolute");
|
||||
expect(html).toContain("inset-0");
|
||||
expect(html).toContain("bg-[#fbf1f2]");
|
||||
expect(html).toContain("object-cover");
|
||||
expect(html).toContain("%2Fimages%2Fauth%2Fbg-login.png");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
/* Auth 背景图片容器(与 splash-background.module.css 同款) */
|
||||
|
||||
.bg {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 0;
|
||||
background: #fbf1f2;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.image {
|
||||
object-fit: cover;
|
||||
object-position: center;
|
||||
}
|
||||
@@ -5,18 +5,17 @@
|
||||
* 资源: /public/images/auth/bg-login.png
|
||||
*/
|
||||
import Image from "next/image";
|
||||
import styles from "./auth-background.module.css";
|
||||
|
||||
export function AuthBackground() {
|
||||
return (
|
||||
<div className={styles.bg}>
|
||||
<div className="absolute inset-0 z-0 overflow-hidden bg-[#fbf1f2]">
|
||||
<Image
|
||||
src="/images/auth/bg-login.png"
|
||||
alt=""
|
||||
fill
|
||||
priority
|
||||
sizes="(max-width: 540px) 100vw, 540px"
|
||||
className={styles.image}
|
||||
className="object-cover object-center"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* 视觉规格(与 Dart 对齐):
|
||||
* - panelShell 包裹整个面板(position: relative)
|
||||
*/
|
||||
.panelShell {
|
||||
position: relative;
|
||||
flex: 1 1 auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
min-height: 0;
|
||||
}
|
||||
@@ -8,7 +8,6 @@ import { useAuthDispatch, useAuthState } from "@/stores/auth/auth-context";
|
||||
|
||||
import { AuthEmailPanel } from "./auth-email-panel";
|
||||
import { AuthFacebookPanel } from "./auth-facebook-panel";
|
||||
import styles from "./auth-panel.module.css";
|
||||
|
||||
export function AuthPanel() {
|
||||
const state = useAuthState();
|
||||
@@ -29,7 +28,7 @@ export function AuthPanel() {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={styles.panelShell}>
|
||||
<div className="relative flex min-h-0 w-full flex-auto flex-col">
|
||||
<BackButton onClick={handleBack} />
|
||||
|
||||
{state.authPanelMode === "facebook" ? (
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
/* auth-screen.module.css
|
||||
* 与 splash-screen.module.css 同款结构(MobileShell 顶层 + .wrapper + .content)
|
||||
* 移动端宽度约束由 ResponsiveMobileShell / MobileShell 统一提供。
|
||||
*/
|
||||
|
||||
.wrapper {
|
||||
position: relative;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
min-height: var(--app-viewport-height, 100dvh);
|
||||
background: #fbf1f2;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.content {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
display: flex;
|
||||
flex: 1 1 auto;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
padding:
|
||||
calc(var(--page-padding-y, var(--spacing-lg)) + var(--app-safe-top, 0px))
|
||||
calc(var(--page-padding-x, var(--spacing-lg)) + var(--app-safe-right, 0px))
|
||||
calc(var(--page-padding-y, var(--spacing-lg)) + var(--app-safe-bottom, 0px))
|
||||
calc(var(--page-padding-x, var(--spacing-lg)) + var(--app-safe-left, 0px));
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
/* 邮箱登录/注册表单样式
|
||||
*
|
||||
*
|
||||
*
|
||||
* 视觉规格(与 Dart 对齐):
|
||||
* - 字段间距 12px(Dart AppSpacing.md)
|
||||
* - 错误横幅与主按钮之间 12px
|
||||
*/
|
||||
.form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--spacing-md);
|
||||
width: 100%;
|
||||
}
|
||||
@@ -13,7 +13,6 @@ import {
|
||||
import { AuthTextField } from "./auth-text-field";
|
||||
import { AuthPrimaryButton } from "./auth-primary-button";
|
||||
import { AuthErrorMessage } from "./auth-error-message";
|
||||
import styles from "./email-form.module.css";
|
||||
import { AppEnvUtil, Logger } from "@/utils";
|
||||
|
||||
const log = new Logger("AppAuthComponentsEmailLoginForm");
|
||||
@@ -76,7 +75,7 @@ export function EmailLoginForm({
|
||||
|
||||
return (
|
||||
<form
|
||||
className={styles.form}
|
||||
className="flex w-full flex-col gap-md"
|
||||
onSubmit={(e) => {
|
||||
e.preventDefault();
|
||||
submit();
|
||||
|
||||
@@ -24,7 +24,6 @@ import {
|
||||
import { AuthTextField } from "./auth-text-field";
|
||||
import { AuthPrimaryButton } from "./auth-primary-button";
|
||||
import { AuthErrorMessage } from "./auth-error-message";
|
||||
import styles from "./email-form.module.css";
|
||||
import { Logger } from "@/utils";
|
||||
|
||||
const log = new Logger("AppAuthComponentsEmailRegisterForm");
|
||||
@@ -112,7 +111,7 @@ export function EmailRegisterForm({
|
||||
|
||||
return (
|
||||
<form
|
||||
className={styles.form}
|
||||
className="flex w-full flex-col gap-md"
|
||||
onSubmit={(e) => {
|
||||
e.preventDefault();
|
||||
submit();
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
.slot {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
min-height: var(--button-height);
|
||||
}
|
||||
Reference in New Issue
Block a user