134 lines
4.4 KiB
TypeScript
134 lines
4.4 KiB
TypeScript
"use client";
|
||
|
||
import { useEffect, useState } from "react";
|
||
import { Copyable } from "../Copyable";
|
||
import styles from "../vip.module.css";
|
||
|
||
const COMMUNITY_URL = "https://qun.hackrobot.cn";
|
||
const DEFAULT_PASSWORD = "12345678";
|
||
|
||
function getStorage(key: string): string | null {
|
||
if (typeof window === "undefined") return null;
|
||
return localStorage.getItem(key);
|
||
}
|
||
|
||
function isAnonymousUserId(value: string | null): value is string {
|
||
return !!value && /^user\d+$/.test(value);
|
||
}
|
||
|
||
type CommunityAccessModalProps = {
|
||
open: boolean;
|
||
onClose: () => void;
|
||
};
|
||
|
||
/** 与 WelcomeBlock 同步的社群登录账号解析,用于弹窗展示 */
|
||
export function CommunityAccessModal({ open, onClose }: CommunityAccessModalProps) {
|
||
const userId = typeof window !== "undefined" ? getStorage("userId") : null;
|
||
const [backendMemosAccount, setBackendMemosAccount] = useState<string | null>(null);
|
||
|
||
const memosAccount =
|
||
getStorage("memosAccount") ||
|
||
backendMemosAccount ||
|
||
(isAnonymousUserId(userId) ? userId : null);
|
||
|
||
useEffect(() => {
|
||
if (!open || !userId) return;
|
||
fetch(`/api/vip/linked-email?user_id=${encodeURIComponent(userId)}`, {
|
||
cache: "no-store",
|
||
})
|
||
.then((res) => res.json())
|
||
.then((data) => {
|
||
const linkedAnonymousUserId =
|
||
typeof data?.anonymousUserId === "string" && /^user\d+$/.test(data.anonymousUserId)
|
||
? data.anonymousUserId
|
||
: null;
|
||
if (linkedAnonymousUserId && typeof window !== "undefined") {
|
||
setBackendMemosAccount(linkedAnonymousUserId);
|
||
localStorage.setItem("memosAccount", linkedAnonymousUserId);
|
||
}
|
||
})
|
||
.catch(() => {});
|
||
}, [open, userId]);
|
||
|
||
useEffect(() => {
|
||
if (!open) return;
|
||
const onKey = (e: KeyboardEvent) => {
|
||
if (e.key === "Escape") onClose();
|
||
};
|
||
window.addEventListener("keydown", onKey);
|
||
return () => window.removeEventListener("keydown", onKey);
|
||
}, [open, onClose]);
|
||
|
||
if (!open) return null;
|
||
|
||
return (
|
||
<div
|
||
className={styles.communityModalBackdrop}
|
||
role="presentation"
|
||
onClick={onClose}
|
||
>
|
||
<div
|
||
className={styles.communityModalPanel}
|
||
role="dialog"
|
||
aria-modal="true"
|
||
aria-labelledby="community-modal-title"
|
||
onClick={(e) => e.stopPropagation()}
|
||
>
|
||
<div className={styles.communityModalGlow} aria-hidden />
|
||
<button
|
||
type="button"
|
||
className={styles.communityModalClose}
|
||
onClick={onClose}
|
||
aria-label="关闭"
|
||
>
|
||
×
|
||
</button>
|
||
<div className={styles.communityModalIconWrap}>
|
||
<span className={styles.communityModalIcon}>👥</span>
|
||
</div>
|
||
<h2 id="community-modal-title" className={styles.communityModalTitle}>
|
||
私密社群 · 登录信息
|
||
</h2>
|
||
<p className={styles.communityModalDesc}>
|
||
使用以下信息访问社群站点,可随时点击复制
|
||
</p>
|
||
|
||
<div className={styles.communityModalRows}>
|
||
<div className={styles.communityModalRow}>
|
||
<span className={styles.communityModalLabel}>网址</span>
|
||
<div className={styles.communityModalValueWrap}>
|
||
<Copyable text={COMMUNITY_URL} className={styles.communityModalCopyable}>
|
||
<span className={styles.communityModalMono}>qun.hackrobot.cn</span>
|
||
</Copyable>
|
||
<a
|
||
href={COMMUNITY_URL}
|
||
target="_blank"
|
||
rel="noopener noreferrer"
|
||
className={styles.communityModalOpenLink}
|
||
>
|
||
打开
|
||
</a>
|
||
</div>
|
||
</div>
|
||
<div className={styles.communityModalRow}>
|
||
<span className={styles.communityModalLabel}>账号</span>
|
||
<Copyable text={memosAccount || ""} className={styles.communityModalCopyable}>
|
||
<span className={styles.communityModalMono}>{memosAccount || "—"}</span>
|
||
</Copyable>
|
||
</div>
|
||
<div className={styles.communityModalRow}>
|
||
<span className={styles.communityModalLabel}>密码</span>
|
||
<Copyable text={DEFAULT_PASSWORD} className={styles.communityModalCopyable}>
|
||
<span className={styles.communityModalMono}>{DEFAULT_PASSWORD}</span>
|
||
</Copyable>
|
||
</div>
|
||
</div>
|
||
|
||
<button type="button" className={styles.communityModalDone} onClick={onClose}>
|
||
知道了
|
||
</button>
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|