Merge branch 'dev' into test
This commit is contained in:
@@ -112,9 +112,6 @@ export function AuthEmailPanel({
|
|||||||
setShowOptions(false);
|
setShowOptions(false);
|
||||||
onGoogle?.();
|
onGoogle?.();
|
||||||
}}
|
}}
|
||||||
onEmail={() => {
|
|
||||||
// 在 email 模式下不再显示 Email 入口
|
|
||||||
}}
|
|
||||||
googleSlot={googleSlot}
|
googleSlot={googleSlot}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -11,7 +11,6 @@
|
|||||||
* `AuthGoogleLoginSubmitted` 事件,状态机内部调 next-auth/react 的 signIn(provider)
|
* `AuthGoogleLoginSubmitted` 事件,状态机内部调 next-auth/react 的 signIn(provider)
|
||||||
* - busy / error 状态来自 `useAuthState()`(与邮箱登录同源)
|
* - busy / error 状态来自 `useAuthState()`(与邮箱登录同源)
|
||||||
* - "Other Sign-in Options" 链接打开底部弹层
|
* - "Other Sign-in Options" 链接打开底部弹层
|
||||||
* - 弹层 Email 按钮 → 触发 `onSwitchToEmail`(父级派发 `AuthPanelModeChanged`)
|
|
||||||
*/
|
*/
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
@@ -24,11 +23,7 @@ import { AuthOtherOptionsDialog } from "./auth-other-options-dialog";
|
|||||||
import { AuthProviderIcon } from "./auth-provider-icon";
|
import { AuthProviderIcon } from "./auth-provider-icon";
|
||||||
import styles from "./auth-facebook-panel.module.css";
|
import styles from "./auth-facebook-panel.module.css";
|
||||||
|
|
||||||
export interface AuthFacebookPanelProps {
|
export function AuthFacebookPanel() {
|
||||||
onSwitchToEmail: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function AuthFacebookPanel({ onSwitchToEmail }: AuthFacebookPanelProps) {
|
|
||||||
const [showOptions, setShowOptions] = useState(false);
|
const [showOptions, setShowOptions] = useState(false);
|
||||||
const { isLoading, errorMessage } = useAuthState();
|
const { isLoading, errorMessage } = useAuthState();
|
||||||
const authDispatch = useAuthDispatch();
|
const authDispatch = useAuthDispatch();
|
||||||
@@ -98,7 +93,6 @@ export function AuthFacebookPanel({ onSwitchToEmail }: AuthFacebookPanelProps) {
|
|||||||
mode="facebook"
|
mode="facebook"
|
||||||
onFacebook={() => handleFacebook()}
|
onFacebook={() => handleFacebook()}
|
||||||
onGoogle={() => handleGoogle()}
|
onGoogle={() => handleGoogle()}
|
||||||
onEmail={onSwitchToEmail}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -9,12 +9,11 @@
|
|||||||
* - 固定底部、宽 100%(≤500px)、顶部圆角 28px
|
* - 固定底部、宽 100%(≤500px)、顶部圆角 28px
|
||||||
* - drag handle 40×4 灰胶囊
|
* - drag handle 40×4 灰胶囊
|
||||||
* - 标题 "Other Sign-in Options" 24px bold 深色
|
* - 标题 "Other Sign-in Options" 24px bold 深色
|
||||||
* - 条件渲染 Email / Facebook 按钮(40px 白胶囊 + 边框 + 图标)
|
* - email 模式下渲染 Facebook 按钮(40px 白胶囊 + 边框 + 图标)
|
||||||
* - 始终渲染 Google 按钮
|
* - 始终渲染 Google 按钮
|
||||||
* - Cancel 文本按钮
|
* - Cancel 文本按钮
|
||||||
*/
|
*/
|
||||||
import type { ReactNode } from "react";
|
import type { ReactNode } from "react";
|
||||||
import { Mail } from "lucide-react";
|
|
||||||
|
|
||||||
import { BottomSheet } from "@/app/_components/core/bottom-sheet";
|
import { BottomSheet } from "@/app/_components/core/bottom-sheet";
|
||||||
|
|
||||||
@@ -27,7 +26,6 @@ export interface AuthOtherOptionsDialogProps {
|
|||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
onFacebook: () => void;
|
onFacebook: () => void;
|
||||||
onGoogle: () => void;
|
onGoogle: () => void;
|
||||||
onEmail: () => void;
|
|
||||||
/** 当前面板模式:facebook 模式下显示 Email + Google;email 模式下显示 Facebook + Google。 */
|
/** 当前面板模式:facebook 模式下显示 Email + Google;email 模式下显示 Facebook + Google。 */
|
||||||
mode: "facebook" | "email";
|
mode: "facebook" | "email";
|
||||||
/** 自定义子节点(如嵌入 GIS 按钮) */
|
/** 自定义子节点(如嵌入 GIS 按钮) */
|
||||||
@@ -39,7 +37,6 @@ export function AuthOtherOptionsDialog({
|
|||||||
onClose,
|
onClose,
|
||||||
onFacebook,
|
onFacebook,
|
||||||
onGoogle,
|
onGoogle,
|
||||||
onEmail,
|
|
||||||
mode,
|
mode,
|
||||||
googleSlot,
|
googleSlot,
|
||||||
}: AuthOtherOptionsDialogProps) {
|
}: AuthOtherOptionsDialogProps) {
|
||||||
@@ -53,17 +50,7 @@ export function AuthOtherOptionsDialog({
|
|||||||
<div className={styles.handle} aria-hidden="true" />
|
<div className={styles.handle} aria-hidden="true" />
|
||||||
<h2 className={styles.title}>Other Sign-in Options</h2>
|
<h2 className={styles.title}>Other Sign-in Options</h2>
|
||||||
|
|
||||||
{mode === "facebook" ? (
|
{mode === "email" ? (
|
||||||
<AuthSocialButton
|
|
||||||
icon={<Mail size={20} aria-hidden="true" />}
|
|
||||||
onClick={() => {
|
|
||||||
onClose();
|
|
||||||
onEmail();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Email Sign In / Register
|
|
||||||
</AuthSocialButton>
|
|
||||||
) : (
|
|
||||||
<AuthSocialButton
|
<AuthSocialButton
|
||||||
icon={<AuthProviderIcon provider="facebook" />}
|
icon={<AuthProviderIcon provider="facebook" />}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
@@ -73,7 +60,7 @@ export function AuthOtherOptionsDialog({
|
|||||||
>
|
>
|
||||||
Facebook Sign In
|
Facebook Sign In
|
||||||
</AuthSocialButton>
|
</AuthSocialButton>
|
||||||
)}
|
) : null}
|
||||||
|
|
||||||
{googleSlot ? (
|
{googleSlot ? (
|
||||||
<div className={styles.googleSlot}>{googleSlot}</div>
|
<div className={styles.googleSlot}>{googleSlot}</div>
|
||||||
|
|||||||
@@ -16,8 +16,6 @@ export function AuthPanel() {
|
|||||||
const dispatch = useAuthDispatch();
|
const dispatch = useAuthDispatch();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
const switchToEmail = () =>
|
|
||||||
dispatch({ type: "AuthPanelModeChanged", mode: "email" });
|
|
||||||
const switchToFacebook = () =>
|
const switchToFacebook = () =>
|
||||||
dispatch({ type: "AuthPanelModeChanged", mode: "facebook" });
|
dispatch({ type: "AuthPanelModeChanged", mode: "facebook" });
|
||||||
|
|
||||||
@@ -41,7 +39,7 @@ export function AuthPanel() {
|
|||||||
</button>
|
</button>
|
||||||
|
|
||||||
{state.authPanelMode === "facebook" ? (
|
{state.authPanelMode === "facebook" ? (
|
||||||
<AuthFacebookPanel onSwitchToEmail={switchToEmail} />
|
<AuthFacebookPanel />
|
||||||
) : (
|
) : (
|
||||||
<AuthEmailPanel
|
<AuthEmailPanel
|
||||||
onSwitchToFacebook={() => {
|
onSwitchToFacebook={() => {
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ export function ChatQuotaExhaustedBanner({
|
|||||||
onUnlock();
|
onUnlock();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
router.push(ROUTES.subscription);
|
router.push(ROUTES.auth);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -4,12 +4,6 @@
|
|||||||
*
|
*
|
||||||
* 派发时机:仅 mount 时一次(`useEffect` deps = `[dispatch]`,永远不重跑)。
|
* 派发时机:仅 mount 时一次(`useEffect` deps = `[dispatch]`,永远不重跑)。
|
||||||
*
|
*
|
||||||
* 与原 `AuthStatusCheckSubmitted` 的区别:
|
|
||||||
* - 原版本有两个 useEffect:① mount + ② loginStatus 变化 re-check
|
|
||||||
* - re-check 是 dead code —— 状态机 onDone 已经把 loginStatus 写对,
|
|
||||||
* 再读 storage 只会拿到相同值(no-op),徒增死循环防护复杂度
|
|
||||||
* - 新版本只保留 ①,命名 `AuthInit` 与 `UserInit` 对齐(user-machine 的同模式)
|
|
||||||
*
|
|
||||||
* 与 <OAuthSessionSync /> 平级:
|
* 与 <OAuthSessionSync /> 平级:
|
||||||
* - AuthStatusChecker: 启动时一次性 init("自己启动时同步")
|
* - AuthStatusChecker: 启动时一次性 init("自己启动时同步")
|
||||||
* - OAuthSessionSync: 持续监听 NextAuth session("别人在写")
|
* - OAuthSessionSync: 持续监听 NextAuth session("别人在写")
|
||||||
|
|||||||
Reference in New Issue
Block a user