diff --git a/src/app/auth/components/auth-back-button.module.css b/src/app/auth/components/auth-back-button.module.css new file mode 100644 index 00000000..f29ef8c0 --- /dev/null +++ b/src/app/auth/components/auth-back-button.module.css @@ -0,0 +1,29 @@ +.backButton { + position: absolute; + top: var(--spacing-xl); + left: var(--spacing-xl); + z-index: 2; + display: inline-flex; + align-items: center; + justify-content: center; + width: var(--auth-back-button-size); + height: var(--auth-back-button-size); + padding: 0 2px 0 0; + color: var(--color-auth-text-primary); + cursor: pointer; + background: var(--color-auth-surface); + border: none; + border-radius: 50%; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); + transition: + background 0.15s ease, + transform 0.05s ease; +} + +.backButton:hover { + background: rgba(0, 0, 0, 0.04); +} + +.backButton:active { + transform: scale(0.96); +} diff --git a/src/app/auth/components/auth-back-button.tsx b/src/app/auth/components/auth-back-button.tsx new file mode 100644 index 00000000..5203cec9 --- /dev/null +++ b/src/app/auth/components/auth-back-button.tsx @@ -0,0 +1,22 @@ +"use client"; + +import { ChevronLeft } from "lucide-react"; + +import styles from "./auth-back-button.module.css"; + +export interface AuthBackButtonProps { + onClick: () => void; +} + +export function AuthBackButton({ onClick }: AuthBackButtonProps) { + return ( + + ); +} diff --git a/src/app/auth/components/auth-background.module.css b/src/app/auth/components/auth-background.module.css index a2613091..7ab89f18 100644 --- a/src/app/auth/components/auth-background.module.css +++ b/src/app/auth/components/auth-background.module.css @@ -4,7 +4,7 @@ position: absolute; inset: 0; z-index: 0; - background: var(--color-page-background); + background: #fbf1f2; overflow: hidden; } diff --git a/src/app/auth/components/auth-panel.module.css b/src/app/auth/components/auth-panel.module.css index 2011d5ac..9161dfe0 100644 --- a/src/app/auth/components/auth-panel.module.css +++ b/src/app/auth/components/auth-panel.module.css @@ -2,7 +2,6 @@ * * 视觉规格(与 Dart 对齐): * - panelShell 包裹整个面板(position: relative) - * - 悬浮返回按钮:40×40 白色圆形 + 淡黑阴影,固定 top/left 20px */ .panelShell { position: relative; @@ -12,31 +11,3 @@ width: 100%; min-height: 0; } - -.backButton { - position: absolute; - top: var(--spacing-xl); - left: var(--spacing-xl); - z-index: 2; - display: inline-flex; - align-items: center; - justify-content: center; - width: var(--auth-back-button-size); - height: var(--auth-back-button-size); - border: none; - border-radius: 50%; - background: var(--color-auth-surface); - color: var(--color-auth-text-primary); - padding: 0 2px 0 0; - cursor: pointer; - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); - transition: background 0.15s ease, transform 0.05s ease; -} - -.backButton:hover { - background: rgba(0, 0, 0, 0.04); -} - -.backButton:active { - transform: scale(0.96); -} diff --git a/src/app/auth/components/auth-panel.tsx b/src/app/auth/components/auth-panel.tsx index 6fad6888..b33b28c3 100644 --- a/src/app/auth/components/auth-panel.tsx +++ b/src/app/auth/components/auth-panel.tsx @@ -3,10 +3,10 @@ * 认证面板:顶层 switch(Facebook / Email)+ 悬浮返回按钮 */ import { useRouter } from "next/navigation"; -import { ChevronLeft } from "lucide-react"; import { useAuthDispatch, useAuthState } from "@/stores/auth/auth-context"; +import { AuthBackButton } from "./auth-back-button"; import { AuthEmailPanel } from "./auth-email-panel"; import { AuthFacebookPanel } from "./auth-facebook-panel"; import styles from "./auth-panel.module.css"; @@ -29,14 +29,7 @@ export function AuthPanel() { return (
- + {state.authPanelMode === "facebook" ? ( diff --git a/src/app/auth/components/auth-screen.module.css b/src/app/auth/components/auth-screen.module.css index e340de27..4dcf4685 100644 --- a/src/app/auth/components/auth-screen.module.css +++ b/src/app/auth/components/auth-screen.module.css @@ -10,6 +10,7 @@ flex-direction: column; width: 100%; min-height: 100dvh; + background: #fbf1f2; overflow: hidden; } diff --git a/src/app/auth/components/index.ts b/src/app/auth/components/index.ts index 45497f29..fc76f775 100644 --- a/src/app/auth/components/index.ts +++ b/src/app/auth/components/index.ts @@ -3,6 +3,7 @@ */ export * from "./auth-background"; +export * from "./auth-back-button"; export * from "./auth-divider"; export * from "./auth-email-panel"; export * from "./auth-error-message"; diff --git a/src/app/chat/components/index.ts b/src/app/chat/components/index.ts index 7cf4da87..e0ca93c6 100644 --- a/src/app/chat/components/index.ts +++ b/src/app/chat/components/index.ts @@ -22,3 +22,4 @@ export * from "./message-content"; export * from "./pwa-install-dialog"; export * from "./pwa-install-overlay"; export * from "./text-bubble"; +export * from "./user-message-avatar"; diff --git a/src/app/chat/components/message-avatar.tsx b/src/app/chat/components/message-avatar.tsx index 68abf8c1..fe723ffe 100644 --- a/src/app/chat/components/message-avatar.tsx +++ b/src/app/chat/components/message-avatar.tsx @@ -1,16 +1,7 @@ "use client"; -/** - * MessageAvatar 消息头像 - * - * 原始 Dart: lib/ui/chat/widgets/message_avatar.dart(85 行) - * - * 显示规则: - * - AI 消息:Elio 头像(`/images/chat/pic-chat-elio.png`) - * - 用户消息(有 avatarUrl):用户头像 - * - 用户消息(无 avatarUrl):游客头像(`/images/chat/pic-chat-guest.png`) - */ import Image from "next/image"; +import { UserMessageAvatar } from "./user-message-avatar"; import styles from "./message-avatar.module.css"; export interface MessageAvatarProps { @@ -33,22 +24,5 @@ export function MessageAvatar({ isFromAI, userAvatarUrl }: MessageAvatarProps) { ); } - if (userAvatarUrl && userAvatarUrl.length > 0) { - return ( -
- -
- ); - } - - return ( -
- Guest -
- ); + return ; } diff --git a/src/app/chat/components/user-message-avatar.tsx b/src/app/chat/components/user-message-avatar.tsx new file mode 100644 index 00000000..78b9e615 --- /dev/null +++ b/src/app/chat/components/user-message-avatar.tsx @@ -0,0 +1,30 @@ +"use client"; + +import Image from "next/image"; + +import styles from "./message-avatar.module.css"; + +export interface UserMessageAvatarProps { + avatarUrl?: string | null; +} + +export function UserMessageAvatar({ avatarUrl }: UserMessageAvatarProps) { + if (avatarUrl && avatarUrl.length > 0) { + return ( +
+ +
+ ); + } + + return ( +
+ Guest +
+ ); +} diff --git a/src/app/subscription/components/subscription-screen.module.css b/src/app/subscription/components/subscription-screen.module.css index 45891876..213cee68 100644 --- a/src/app/subscription/components/subscription-screen.module.css +++ b/src/app/subscription/components/subscription-screen.module.css @@ -3,7 +3,7 @@ flex-direction: column; min-height: 100dvh; background: var(--color-page-background); - padding: 0 var(--spacing-lg) var(--spacing-xxl); + padding: 30px 20px 10px; } .header { diff --git a/src/stores/payment/payment-state.ts b/src/stores/payment/payment-state.ts index d3efb821..0aba2068 100644 --- a/src/stores/payment/payment-state.ts +++ b/src/stores/payment/payment-state.ts @@ -27,7 +27,7 @@ export const initialState: PaymentState = { selectedPlanId: "", payChannel: "stripe", autoRenew: true, - agreed: false, + agreed: true, currentOrderId: null, payParams: null, orderStatus: null,