Move chat and notifications out of Connect into top-right icons.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
a62cf057e8
commit
377db2284f
@ -8,12 +8,19 @@ export const metadata: Metadata = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const LOGS = [
|
const LOGS = [
|
||||||
|
{
|
||||||
|
date: "2026-09-04",
|
||||||
|
tag: "导航精简",
|
||||||
|
items: [
|
||||||
|
"私信与通知移出 Connect 菜单/页脚/个人中心快捷入口,统一用右上角 ✉️ / 🔔 图标进入",
|
||||||
|
],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
date: "2026-09-04",
|
date: "2026-09-04",
|
||||||
tag: "活动报名 · Connect 数据",
|
tag: "活动报名 · Connect 数据",
|
||||||
items: [
|
items: [
|
||||||
"报名成功 toast:线上/混合直达直播间,线下引导导出日历;报名确认写入通知箱",
|
"报名成功 toast:线上/混合直达直播间,线下引导导出日历;报名确认写入通知箱",
|
||||||
"个人中心新增 Connect 数据条(喜欢我的 / 互相喜欢 / 私信 / 已报名),可点进对应页面",
|
"个人中心新增 Connect 数据条(喜欢我的 / 互相喜欢 / 已报名),可点进对应页面",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@ -2781,6 +2781,7 @@ img { max-width: 100%; display: block; }
|
|||||||
|
|
||||||
.profile-connect-stats {
|
.profile-connect-stats {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
|
grid-template-columns: repeat(3, 1fr);
|
||||||
}
|
}
|
||||||
|
|
||||||
.profile-stat-card {
|
.profile-stat-card {
|
||||||
|
|||||||
@ -60,7 +60,7 @@ export default function ProfilePage() {
|
|||||||
const [stats, setStats] = useState<ProfileStats | null>(null);
|
const [stats, setStats] = useState<ProfileStats | null>(null);
|
||||||
const [favoriteDests, setFavoriteDests] = useState<Destination[]>([]);
|
const [favoriteDests, setFavoriteDests] = useState<Destination[]>([]);
|
||||||
const [rsvps, setRsvps] = useState<Meetup[]>([]);
|
const [rsvps, setRsvps] = useState<Meetup[]>([]);
|
||||||
const [connect, setConnect] = useState({ likes: 0, matches: 0, chats: 0 });
|
const [connect, setConnect] = useState({ likes: 0, matches: 0 });
|
||||||
const [trip, setTrip] = useState<TripItem[]>([]);
|
const [trip, setTrip] = useState<TripItem[]>([]);
|
||||||
const [meta, setMeta] = useState<PlanMeta | null>(null);
|
const [meta, setMeta] = useState<PlanMeta | null>(null);
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
@ -113,11 +113,9 @@ export default function ProfilePage() {
|
|||||||
Promise.all([
|
Promise.all([
|
||||||
api.getMatchLikesReceived(token).catch(() => []),
|
api.getMatchLikesReceived(token).catch(() => []),
|
||||||
api.getMutualMatches(token).catch(() => ({ items: [] })),
|
api.getMutualMatches(token).catch(() => ({ items: [] })),
|
||||||
api.getConversations(token).catch(() => []),
|
]).then(([likes, matches]) => ({
|
||||||
]).then(([likes, matches, chats]) => ({
|
|
||||||
likes: likes.length,
|
likes: likes.length,
|
||||||
matches: matches.items?.length ?? 0,
|
matches: matches.items?.length ?? 0,
|
||||||
chats: chats.length,
|
|
||||||
})),
|
})),
|
||||||
]).then(([s, f, v, myMeetups, connectStats]) => {
|
]).then(([s, f, v, myMeetups, connectStats]) => {
|
||||||
setStats(s);
|
setStats(s);
|
||||||
@ -244,11 +242,6 @@ export default function ProfilePage() {
|
|||||||
<strong>{connect.matches}</strong>
|
<strong>{connect.matches}</strong>
|
||||||
<span>{t.profile.statMatches}</span>
|
<span>{t.profile.statMatches}</span>
|
||||||
</Link>
|
</Link>
|
||||||
<Link href="/chat" className="profile-stat-card profile-stat-link">
|
|
||||||
<span className="stat-emoji">✉️</span>
|
|
||||||
<strong>{connect.chats}</strong>
|
|
||||||
<span>{t.profile.statChats}</span>
|
|
||||||
</Link>
|
|
||||||
<Link href="/meetups" className="profile-stat-card profile-stat-link">
|
<Link href="/meetups" className="profile-stat-card profile-stat-link">
|
||||||
<span className="stat-emoji">🎉</span>
|
<span className="stat-emoji">🎉</span>
|
||||||
<strong>{rsvps.length}</strong>
|
<strong>{rsvps.length}</strong>
|
||||||
@ -439,8 +432,6 @@ export default function ProfilePage() {
|
|||||||
<Link href="/next-stop" className="quick-card">{t.profile.qNext}</Link>
|
<Link href="/next-stop" className="quick-card">{t.profile.qNext}</Link>
|
||||||
<Link href="/meetups" className="quick-card">{t.profile.qMeetups}</Link>
|
<Link href="/meetups" className="quick-card">{t.profile.qMeetups}</Link>
|
||||||
<Link href="/dating" className="quick-card">{t.profile.qDating}</Link>
|
<Link href="/dating" className="quick-card">{t.profile.qDating}</Link>
|
||||||
<Link href="/chat" className="quick-card">{t.profile.qChat}</Link>
|
|
||||||
<Link href="/notifications" className="quick-card">{t.profile.qNotif}</Link>
|
|
||||||
<Link href="/join" className="quick-card">{vip ? t.profile.qVipMember : t.profile.qVip}</Link>
|
<Link href="/join" className="quick-card">{vip ? t.profile.qVipMember : t.profile.qVip}</Link>
|
||||||
<Link href="/digital" className="quick-card">{t.profile.qDigital}</Link>
|
<Link href="/digital" className="quick-card">{t.profile.qDigital}</Link>
|
||||||
<Link href="/ai" className="quick-card">{t.profile.qAi}</Link>
|
<Link href="/ai" className="quick-card">{t.profile.qAi}</Link>
|
||||||
|
|||||||
@ -54,7 +54,7 @@ export default function Footer() {
|
|||||||
<Link href="/meetups">{t.footer.meetups}</Link>
|
<Link href="/meetups">{t.footer.meetups}</Link>
|
||||||
<Link href="/community">{t.footer.community}</Link>
|
<Link href="/community">{t.footer.community}</Link>
|
||||||
<Link href="/dating">{t.footer.dating}</Link>
|
<Link href="/dating">{t.footer.dating}</Link>
|
||||||
<Link href="/chat">{t.footer.chat}</Link>
|
<Link href="/join">{t.footer.join}</Link>
|
||||||
</div>
|
</div>
|
||||||
<div className="footer-links">
|
<div className="footer-links">
|
||||||
<h4>{t.footer.grow}</h4>
|
<h4>{t.footer.grow}</h4>
|
||||||
@ -64,7 +64,6 @@ export default function Footer() {
|
|||||||
<Link href="/submit">{t.submit.tag}</Link>
|
<Link href="/submit">{t.submit.tag}</Link>
|
||||||
<Link href="/feedback">{t.nav.feedback}</Link>
|
<Link href="/feedback">{t.nav.feedback}</Link>
|
||||||
<Link href="/tools">{t.footer.toolkit}</Link>
|
<Link href="/tools">{t.footer.toolkit}</Link>
|
||||||
<Link href="/join">{t.footer.join}</Link>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="footer-links">
|
<div className="footer-links">
|
||||||
<h4>{t.footer.account}</h4>
|
<h4>{t.footer.account}</h4>
|
||||||
|
|||||||
@ -57,8 +57,6 @@ export default function Navbar() {
|
|||||||
{ href: "/meetups", label: t.nav.meetups, section: "meetups" },
|
{ href: "/meetups", label: t.nav.meetups, section: "meetups" },
|
||||||
{ href: "/community", label: t.nav.community, section: "community" },
|
{ href: "/community", label: t.nav.community, section: "community" },
|
||||||
{ href: "/dating", label: t.nav.dating, section: "dating" },
|
{ href: "/dating", label: t.nav.dating, section: "dating" },
|
||||||
{ href: "/chat", label: t.nav.chat, section: "chat" },
|
|
||||||
{ href: "/notifications", label: t.nav.notifications, section: "notifications" },
|
|
||||||
{ href: "/join", label: t.nav.join, section: "join" },
|
{ href: "/join", label: t.nav.join, section: "join" },
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -142,7 +140,6 @@ export default function Navbar() {
|
|||||||
if (l.href.startsWith("/#")) return isHome && active === l.section;
|
if (l.href.startsWith("/#")) return isHome && active === l.section;
|
||||||
if (l.href === "/book") return pathname.startsWith("/book");
|
if (l.href === "/book") return pathname.startsWith("/book");
|
||||||
if (l.href === "/digital") return pathname.startsWith("/digital");
|
if (l.href === "/digital") return pathname.startsWith("/digital");
|
||||||
if (l.href === "/chat") return pathname.startsWith("/chat");
|
|
||||||
if (l.href === "/dating") return pathname.startsWith("/dating");
|
if (l.href === "/dating") return pathname.startsWith("/dating");
|
||||||
if (l.href === "/meetups") return pathname.startsWith("/meetups");
|
if (l.href === "/meetups") return pathname.startsWith("/meetups");
|
||||||
if (l.href === "/community") return pathname.startsWith("/community");
|
if (l.href === "/community") return pathname.startsWith("/community");
|
||||||
@ -228,7 +225,7 @@ export default function Navbar() {
|
|||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
{/* Right chrome: language / theme / notifications — always top-right */}
|
{/* Right chrome: language / theme / chat / notifications — always top-right */}
|
||||||
<div className="nav-utils" aria-label="preferences">
|
<div className="nav-utils" aria-label="preferences">
|
||||||
<button type="button" className="nav-lang-btn" onClick={toggleLocale} aria-label={t.nav.lang}>
|
<button type="button" className="nav-lang-btn" onClick={toggleLocale} aria-label={t.nav.lang}>
|
||||||
{locale === "zh" ? "EN" : "中文"}
|
{locale === "zh" ? "EN" : "中文"}
|
||||||
@ -236,6 +233,20 @@ export default function Navbar() {
|
|||||||
<button type="button" className="nav-cta" onClick={toggleTheme} aria-label={t.nav.theme}>
|
<button type="button" className="nav-cta" onClick={toggleTheme} aria-label={t.nav.theme}>
|
||||||
<span className="theme-icon">{theme === "dark" ? "🌙" : "☀️"}</span>
|
<span className="theme-icon">{theme === "dark" ? "🌙" : "☀️"}</span>
|
||||||
</button>
|
</button>
|
||||||
|
{user ? (
|
||||||
|
<Link href="/chat" className="nav-notify" aria-label={t.nav.chat}>
|
||||||
|
✉️
|
||||||
|
</Link>
|
||||||
|
) : (
|
||||||
|
<Link
|
||||||
|
href={`/login?next=${encodeURIComponent("/chat")}`}
|
||||||
|
className="nav-notify nav-notify-guest"
|
||||||
|
aria-label={t.nav.chat}
|
||||||
|
title={t.nav.login}
|
||||||
|
>
|
||||||
|
✉️
|
||||||
|
</Link>
|
||||||
|
)}
|
||||||
{user ? (
|
{user ? (
|
||||||
<Link href="/notifications" className="nav-notify" aria-label={t.nav.notifications}>
|
<Link href="/notifications" className="nav-notify" aria-label={t.nav.notifications}>
|
||||||
🔔{unread > 0 && <em className="nav-notify-badge">{unread}</em>}
|
🔔{unread > 0 && <em className="nav-notify-badge">{unread}</em>}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user