From d1228324ca3901ffdfd2a1918ce9c4f8257c41cb Mon Sep 17 00:00:00 2001 From: chenhang Date: Mon, 22 Jun 2026 11:27:13 +0800 Subject: [PATCH] fix(auth): enable dev email login testing --- .../auth/components/auth-facebook-panel.tsx | 9 ++++- .../components/auth-other-options-dialog.tsx | 33 +++++++++++-------- src/app/auth/components/auth-panel.tsx | 4 ++- src/app/auth/components/email-login-form.tsx | 12 +++++-- src/app/subscription/page.tsx | 27 +++++---------- .../subscription/subscription-page-client.tsx | 19 +++++++++++ 6 files changed, 67 insertions(+), 37 deletions(-) create mode 100644 src/app/subscription/subscription-page-client.tsx diff --git a/src/app/auth/components/auth-facebook-panel.tsx b/src/app/auth/components/auth-facebook-panel.tsx index 55f40d9a..74800de7 100644 --- a/src/app/auth/components/auth-facebook-panel.tsx +++ b/src/app/auth/components/auth-facebook-panel.tsx @@ -23,7 +23,13 @@ import { AuthOtherOptionsDialog } from "./auth-other-options-dialog"; import { AuthProviderIcon } from "./auth-provider-icon"; import styles from "./auth-facebook-panel.module.css"; -export function AuthFacebookPanel() { +export interface AuthFacebookPanelProps { + onSwitchToEmail: () => void; +} + +export function AuthFacebookPanel({ + onSwitchToEmail, +}: AuthFacebookPanelProps) { const [showOptions, setShowOptions] = useState(false); const { isLoading, errorMessage } = useAuthState(); const authDispatch = useAuthDispatch(); @@ -93,6 +99,7 @@ export function AuthFacebookPanel() { mode="facebook" onFacebook={() => handleFacebook()} onGoogle={() => handleGoogle()} + onEmail={onSwitchToEmail} /> ); diff --git a/src/app/auth/components/auth-other-options-dialog.tsx b/src/app/auth/components/auth-other-options-dialog.tsx index e0afb162..0e89fe82 100644 --- a/src/app/auth/components/auth-other-options-dialog.tsx +++ b/src/app/auth/components/auth-other-options-dialog.tsx @@ -1,21 +1,9 @@ "use client"; -/** - * "其他登录方式" 底部弹层 - * - * 原始 Dart: lib/ui/auth/widgets/auth_other_options_dialog.dart - * (showModalBottomSheet:白卡 + 顶部圆角 radius28 + drag handle) - * - * 视觉规格(与 Dart 对齐): - * - 固定底部、宽 100%(≤500px)、顶部圆角 28px - * - drag handle 40×4 灰胶囊 - * - 标题 "Other Sign-in Options" 24px bold 深色 - * - email 模式下渲染 Facebook 按钮(40px 白胶囊 + 边框 + 图标) - * - 始终渲染 Google 按钮 - * - Cancel 文本按钮 - */ import type { ReactNode } from "react"; +import { MdEmail } from "react-icons/md"; import { BottomSheet } from "@/app/_components/core/bottom-sheet"; +import { AppEnvUtil } from "@/utils"; import { AuthProviderIcon } from "./auth-provider-icon"; import { AuthSocialButton } from "./auth-social-button"; @@ -26,6 +14,7 @@ export interface AuthOtherOptionsDialogProps { onClose: () => void; onFacebook: () => void; onGoogle: () => void; + onEmail?: () => void; /** 当前面板模式:facebook 模式下显示 Email + Google;email 模式下显示 Facebook + Google。 */ mode: "facebook" | "email"; /** 自定义子节点(如嵌入 GIS 按钮) */ @@ -37,9 +26,13 @@ export function AuthOtherOptionsDialog({ onClose, onFacebook, onGoogle, + onEmail, mode, googleSlot, }: AuthOtherOptionsDialogProps) { + const showDevEmailOption = + AppEnvUtil.isDevelopment() && mode === "facebook" && onEmail; + return ( ) : null} + {showDevEmailOption ? ( + } + onClick={() => { + onClose(); + onEmail(); + }} + > + Email Sign In + + ) : null} + {googleSlot ? (
{googleSlot}
) : ( diff --git a/src/app/auth/components/auth-panel.tsx b/src/app/auth/components/auth-panel.tsx index b33b28c3..5a21cb4b 100644 --- a/src/app/auth/components/auth-panel.tsx +++ b/src/app/auth/components/auth-panel.tsx @@ -18,6 +18,8 @@ export function AuthPanel() { const switchToFacebook = () => dispatch({ type: "AuthPanelModeChanged", mode: "facebook" }); + const switchToEmail = () => + dispatch({ type: "AuthPanelModeChanged", mode: "email" }); const handleBack = () => { if (state.authPanelMode === "email") { @@ -32,7 +34,7 @@ export function AuthPanel() { {state.authPanelMode === "facebook" ? ( - + ) : ( { diff --git a/src/app/auth/components/email-login-form.tsx b/src/app/auth/components/email-login-form.tsx index ae65e8e0..9cbb9a18 100644 --- a/src/app/auth/components/email-login-form.tsx +++ b/src/app/auth/components/email-login-form.tsx @@ -14,9 +14,11 @@ 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"; +import { AppEnvUtil, Logger } from "@/utils"; const log = new Logger("AppAuthComponentsEmailLoginForm"); +const DEV_DEFAULT_EMAIL = "chanwillian0@gmail.com"; +const DEV_DEFAULT_PASSWORD = "12345678"; export interface EmailLoginFormProps { globalError?: string | null; @@ -28,8 +30,12 @@ export function EmailLoginForm({ isLoading, }: EmailLoginFormProps) { const dispatch = useAuthDispatch(); - const [email, setEmail] = useState(""); - const [password, setPassword] = useState(""); + const [email, setEmail] = useState(() => + AppEnvUtil.isDevelopment() ? DEV_DEFAULT_EMAIL : "", + ); + const [password, setPassword] = useState(() => + AppEnvUtil.isDevelopment() ? DEV_DEFAULT_PASSWORD : "", + ); // 本地校验错误(client-side)—— 校验失败时展示第一个非 null 的错误 // 优先级:local validationError > server globalError const [validationError, setValidationError] = useState(null); diff --git a/src/app/subscription/page.tsx b/src/app/subscription/page.tsx index e9b9625a..a6a87c44 100644 --- a/src/app/subscription/page.tsx +++ b/src/app/subscription/page.tsx @@ -1,21 +1,12 @@ -import { SubscriptionScreen } from "@/app/subscription/subscription-screen"; +import { Suspense } from "react"; -import type { SubscriptionType } from "./subscription-screen"; +import { SubscriptionPageClient } from "./subscription-page-client"; +import { SubscriptionScreen } from "./subscription-screen"; -interface SubscriptionPageProps { - searchParams: Promise<{ - type?: string | string[]; - }>; -} - -function toSubscriptionType(value: string | string[] | undefined): SubscriptionType { - const type = Array.isArray(value) ? value[0] : value; - return type === "voice" ? "voice" : "vip"; -} - -export default async function SubscriptionPage({ - searchParams, -}: SubscriptionPageProps) { - const params = await searchParams; - return ; +export default function SubscriptionPage() { + return ( + }> + + + ); } diff --git a/src/app/subscription/subscription-page-client.tsx b/src/app/subscription/subscription-page-client.tsx new file mode 100644 index 00000000..4aab8c03 --- /dev/null +++ b/src/app/subscription/subscription-page-client.tsx @@ -0,0 +1,19 @@ +"use client"; + +import { useSearchParams } from "next/navigation"; + +import { + SubscriptionScreen, + type SubscriptionType, +} from "./subscription-screen"; + +function toSubscriptionType(value: string | null): SubscriptionType { + return value === "voice" ? "voice" : "vip"; +} + +export function SubscriptionPageClient() { + const searchParams = useSearchParams(); + const subscriptionType = toSubscriptionType(searchParams.get("type")); + + return ; +}