From f9ab758926d87c87f3bf18a4bfae051e71051602 Mon Sep 17 00:00:00 2001
From: eric
Date: Fri, 4 Sep 2026 07:17:48 -0500
Subject: [PATCH] Polish dating profile link, likes title, and offline RSVP
calendar export.
Co-authored-by: Cursor
---
frontend/src/app/changelog/page.tsx | 8 +++++++
frontend/src/app/globals.css | 27 +++++++++++++++++++++
frontend/src/app/profile/page.tsx | 29 ++++++++++++++++++-----
frontend/src/components/DatingClient.tsx | 8 +++++++
frontend/src/components/MeetupsClient.tsx | 24 +++++++++++++++----
frontend/src/lib/i18n/dictionaries.ts | 6 +++--
6 files changed, 90 insertions(+), 12 deletions(-)
diff --git a/frontend/src/app/changelog/page.tsx b/frontend/src/app/changelog/page.tsx
index bfb912b..9e73783 100644
--- a/frontend/src/app/changelog/page.tsx
+++ b/frontend/src/app/changelog/page.tsx
@@ -8,6 +8,14 @@ export const metadata: Metadata = {
};
const LOGS = [
+ {
+ date: "2026-09-04",
+ tag: "匹配资料 · 报名日历",
+ items: [
+ "匹配卡片可「查看资料」;喜欢页标题改为中性「喜欢」",
+ "线下报名成功自动下载日历;个人中心每场 RSVP 可加入日历",
+ ],
+ },
{
date: "2026-09-04",
tag: "导航精简",
diff --git a/frontend/src/app/globals.css b/frontend/src/app/globals.css
index 8c55d76..2e6b3ec 100644
--- a/frontend/src/app/globals.css
+++ b/frontend/src/app/globals.css
@@ -10601,6 +10601,21 @@ a.profile-stat-link:hover {
margin: 16px 0;
}
+.dating-view-profile {
+ display: inline-block;
+ margin-top: 4px;
+ font-size: 0.85rem;
+ color: var(--accent, #e8a87c);
+ text-decoration: none;
+ pointer-events: auto;
+ position: relative;
+ z-index: 2;
+}
+
+.dating-view-profile:hover {
+ text-decoration: underline;
+}
+
.dating-actions {
display: flex;
justify-content: center;
@@ -11567,6 +11582,18 @@ a.weather-card:hover {
margin-left: auto;
}
+.profile-rsvp-actions {
+ margin-left: auto;
+ display: flex;
+ flex-wrap: wrap;
+ gap: 0.4rem;
+ justify-content: flex-end;
+}
+
+.profile-rsvp-actions .btn {
+ margin-left: 0;
+}
+
.compare-history {
margin: 0 0 1.5rem;
padding: 1rem 1.15rem;
diff --git a/frontend/src/app/profile/page.tsx b/frontend/src/app/profile/page.tsx
index 0075636..7d931e4 100644
--- a/frontend/src/app/profile/page.tsx
+++ b/frontend/src/app/profile/page.tsx
@@ -237,7 +237,7 @@ export default function ProfilePage() {
{connect.likes}
{t.profile.statLikes}
-
+
✨
{connect.matches}
{t.profile.statMatches}
@@ -410,11 +410,28 @@ export default function ProfilePage() {
{m.city} · {m.date} {m.time}
- {(m.mode === "online" || m.mode === "hybrid") && (
-
- {t.profile.openLive}
-
- )}
+
+ {(m.mode === "online" || m.mode === "hybrid") && (
+
+ {t.profile.openLive}
+
+ )}
+
+
))}
diff --git a/frontend/src/components/DatingClient.tsx b/frontend/src/components/DatingClient.tsx
index f390016..0a8b752 100644
--- a/frontend/src/components/DatingClient.tsx
+++ b/frontend/src/components/DatingClient.tsx
@@ -337,6 +337,14 @@ export default function DatingClient() {
))}
+ e.stopPropagation()}
+ onClick={(e) => e.stopPropagation()}
+ >
+ {t.dating.viewProfile} →
+
diff --git a/frontend/src/components/MeetupsClient.tsx b/frontend/src/components/MeetupsClient.tsx
index 108481f..3acb2b7 100644
--- a/frontend/src/components/MeetupsClient.tsx
+++ b/frontend/src/components/MeetupsClient.tsx
@@ -129,10 +129,26 @@ export default function MeetupsClient({ meetups }: Props) {
const res = await api.rsvpMeetup(meetup.id, undefined, token);
setRsvpIds(new Set(rsvpIds).add(meetup.id));
const live = meetup.mode === "online" || meetup.mode === "hybrid";
- toast(res.message || t.meetups.rsvpOk, "success", {
- href: live ? meetupEventHref(meetup) : "/profile",
- label: live ? t.meetups.liveBtn : t.meetups.rsvpCalCta,
- });
+ if (live) {
+ toast(res.message || t.meetups.rsvpOk, "success", {
+ href: meetupEventHref(meetup),
+ label: t.meetups.liveBtn,
+ });
+ } else {
+ const ics = buildMeetupIcs([meetup], meetup.title);
+ if (ics) {
+ downloadMeetupIcs(`nomadro-${meetup.id}.ics`, ics);
+ toast(res.message || t.meetups.rsvpOk, "success", {
+ href: "/profile",
+ label: t.meetups.viewRsvps,
+ });
+ } else {
+ toast(res.message || t.meetups.rsvpOk, "success", {
+ href: "/profile",
+ label: t.meetups.viewRsvps,
+ });
+ }
+ }
void loadPeers(meetup.id);
} catch {
toast(t.meetups.rsvpFail, "error");
diff --git a/frontend/src/lib/i18n/dictionaries.ts b/frontend/src/lib/i18n/dictionaries.ts
index aaf3237..2f9ae9c 100644
--- a/frontend/src/lib/i18n/dictionaries.ts
+++ b/frontend/src/lib/i18n/dictionaries.ts
@@ -422,7 +422,7 @@ export const zh = {
matched: "你和",
keepSwiping: "继续滑",
chatNow: "去聊天",
- likesTitle: "我喜欢的",
+ likesTitle: "喜欢",
likesSubtitle: "你右滑喜欢的游民会出现在这里",
likesEmpty: "还没有喜欢任何人,去滑一张卡片吧",
backSwipe: "返回匹配",
@@ -686,6 +686,7 @@ export const zh = {
meetPeers: "同城可能认识的人",
goDating: "去匹配",
rsvpCalCta: "导出日历",
+ viewRsvps: "查看报名",
viewProfile: "查看资料",
},
community: {
@@ -1696,7 +1697,7 @@ export const en: { [K in keyof typeof zh]: typeof zh[K] extends string ? string
matched: "You matched with",
keepSwiping: "Keep swiping",
chatNow: "Open chat",
- likesTitle: "People you liked",
+ likesTitle: "Likes",
likesSubtitle: "Profiles you swiped right on",
likesEmpty: "No likes yet — go swipe some cards",
backSwipe: "Back to match",
@@ -1960,6 +1961,7 @@ export const en: { [K in keyof typeof zh]: typeof zh[K] extends string ? string
meetPeers: "People you may meet nearby",
goDating: "Go match",
rsvpCalCta: "Export calendar",
+ viewRsvps: "View RSVPs",
viewProfile: "View profile",
},
community: {