feat(frontend): clarify chart profile management
This commit is contained in:
@@ -1644,11 +1644,20 @@ button:disabled { cursor: default; opacity: .45; }
|
||||
.default-chart-card strong { display: block; margin: 4px 0; color: var(--color-ink); font-size: var(--type-body-md); font-weight: 500; }
|
||||
.chart-library-panel { display: grid; gap: var(--space-5); margin-top: var(--space-5); }
|
||||
.chart-library-group { display: grid; gap: var(--space-3); }
|
||||
.chart-library-group > b { color: var(--color-ink); font-size: var(--type-caption); font-weight: 600; }
|
||||
.chart-library-group-heading { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); }
|
||||
.chart-library-group-heading b, .chart-library-group-heading small { display: block; }
|
||||
.chart-library-group-heading b { color: var(--color-ink); font-size: var(--type-caption); font-weight: 650; }
|
||||
.chart-library-group-heading small { margin-top: 3px; color: var(--color-ink-secondary); font-size: var(--type-caption); font-weight: 400; }
|
||||
.chart-library-count { display: grid; min-width: 24px; height: 24px; place-items: center; border-radius: 999px; background: var(--color-canvas-muted); color: var(--color-ink-secondary); font-size: 11px; }
|
||||
.chart-library-item { display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); padding: var(--space-4); border: 1px solid var(--color-border); border-radius: var(--radius-lg); background: var(--color-canvas); }
|
||||
.chart-library-item-main { min-width: 0; }
|
||||
.chart-library-item strong, .chart-library-item small { display: block; }
|
||||
.chart-library-item strong { color: var(--color-ink); font-size: var(--type-body-md); font-weight: 500; }
|
||||
.chart-library-item small, .chart-library-item > span, .empty-library-copy { color: var(--color-ink-secondary); font-size: var(--type-caption); }
|
||||
.chart-library-item small + small { margin-top: 3px; }
|
||||
.chart-library-item-title { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; margin-bottom: 5px; }
|
||||
.chart-role-badge, .chart-default-badge { display: inline-flex; align-items: center; min-height: 20px; padding: 0 7px; border-radius: 999px; background: var(--color-canvas-muted); color: var(--color-ink-secondary); font-size: 10px; font-weight: 650; }
|
||||
.chart-role-badge.is-self, .chart-default-badge { background: var(--color-action-soft); color: var(--color-action-hover); }
|
||||
.chart-library-actions { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: var(--space-2); }
|
||||
.chart-library-actions > * { max-width: 100%; }
|
||||
.chart-library-form { padding-top: var(--space-4); border-top: 1px solid var(--color-border); }
|
||||
|
||||
+63
-37
@@ -601,6 +601,24 @@ function profilePlaceLabel(profile: Profile) {
|
||||
return selectedBirthPlace(profile)?.label || "地点未完整";
|
||||
}
|
||||
|
||||
function profileBirthTimeLabel(profile: Profile) {
|
||||
if (profile.time) return profile.time;
|
||||
if (profile.birthTimePeriod) return `${profile.birthTimePeriod}(时分待确认)`;
|
||||
return "出生时间待补全";
|
||||
}
|
||||
|
||||
function profileBirthTimeStatusLabel(profile: Profile) {
|
||||
if (profile.birthTimeStatus === "confirmed") return "时间已确认";
|
||||
if (profile.birthTimeStatus === "candidate" || profile.birthTimeStatus === "accepted") return "时间为候选";
|
||||
if (profile.birthTimeStatus === "rectifying" || profile.birthTimeStatus === "assessing") return "正在评估时间";
|
||||
return "时间待确认";
|
||||
}
|
||||
|
||||
function formatChartUpdatedAt(updatedAt: number) {
|
||||
if (!Number.isFinite(updatedAt) || updatedAt <= 0) return "刚刚更新";
|
||||
return `更新于 ${new Intl.DateTimeFormat("zh-CN", { month: "numeric", day: "numeric" }).format(new Date(updatedAt))}`;
|
||||
}
|
||||
|
||||
function buildSynastryQuestion(selfProfile: Profile, partnerProfile: Profile, relationshipType: SynastryRelationshipType) {
|
||||
const relationshipLabel = relationshipType === "business" ? "商业合作" : relationshipType === "family" ? "亲友/家庭" : relationshipType === "general" ? "其他关系" : "婚恋";
|
||||
const evidenceRequest = relationshipType === "business"
|
||||
@@ -3866,43 +3884,51 @@ export default function Home() {
|
||||
renderChartLibrary() {
|
||||
return (
|
||||
<>
|
||||
<p className="settings-dialog-copy">管理本人和其他人的出生资料,之后可直接用于切换默认星盘或发起合盘。</p>
|
||||
<div className="chart-library-panel" aria-label="星盘库">
|
||||
<div className="chart-library-group">
|
||||
<b>本人</b>
|
||||
{chartLibrary.filter((record) => record.role === "self").map((record) => (
|
||||
<article className="chart-library-item" key={record.id}>
|
||||
<div>
|
||||
<strong>{record.profile.name || "未命名"}</strong>
|
||||
<small>{record.profile.date} {record.profile.time} · {profilePlaceLabel(record.profile)}</small>
|
||||
</div>
|
||||
<span>当前默认</span>
|
||||
</article>
|
||||
))}
|
||||
</div>
|
||||
<div className="chart-library-group">
|
||||
<b>其他</b>
|
||||
{chartLibrary.filter((record) => record.role === "other").length === 0 && <p className="empty-library-copy">还没有其他星盘。</p>}
|
||||
{chartLibrary.filter((record) => record.role === "other").map((record) => (
|
||||
<article className="chart-library-item" key={record.id}>
|
||||
<div>
|
||||
<strong>{record.profile.name || "未命名"}</strong>
|
||||
<small>{record.profile.date} {record.profile.time} · {profilePlaceLabel(record.profile)}</small>
|
||||
</div>
|
||||
<div className="chart-library-actions">
|
||||
<select aria-label="关系类型" value={synastryRelationshipType} onChange={(event) => setSynastryRelationshipType(event.target.value as SynastryRelationshipType)} disabled={synastryPendingId !== null}>
|
||||
<option value="romance">婚恋</option>
|
||||
<option value="business">商业合作</option>
|
||||
<option value="family">亲友/家庭</option>
|
||||
<option value="general">其他关系</option>
|
||||
</select>
|
||||
<button className="button-secondary" type="button" onClick={() => void draftSynastryQuestionFromChart(record, synastryRelationshipType)} disabled={synastryPendingId !== null}>{synastryPendingId === record.id ? "正在计算合盘..." : "用于合盘"}</button>
|
||||
<button className="button-secondary" type="button" onClick={() => void makeDefaultChart(record)} disabled={profileSaving}>设为默认</button>
|
||||
<button className="button-secondary" type="button" onClick={() => deleteOtherChart(record.id)}>删除</button>
|
||||
</div>
|
||||
</article>
|
||||
))}
|
||||
</div>
|
||||
<p className="settings-dialog-copy">管理本人和其他人的出生资料。本人资料用于默认解盘,其他人资料可用于合盘或单独查看。</p>
|
||||
<div className="chart-library-panel" aria-label="星盘资料管理">
|
||||
<div className="chart-library-group">
|
||||
<div className="chart-library-group-heading">
|
||||
<div><b>我的星盘</b><small>当前账号的默认资料</small></div>
|
||||
<span className="chart-library-count">{chartLibrary.filter((record) => record.role === "self").length}</span>
|
||||
</div>
|
||||
{chartLibrary.filter((record) => record.role === "self").map((record) => (
|
||||
<article className="chart-library-item" key={record.id}>
|
||||
<div className="chart-library-item-main">
|
||||
<div className="chart-library-item-title"><strong>{record.profile.name || "未命名"}</strong><span className="chart-role-badge is-self">本人</span><span className="chart-default-badge">当前默认</span></div>
|
||||
<small>{record.profile.date || "出生日期待补全"} · {profileBirthTimeLabel(record.profile)} · {profilePlaceLabel(record.profile)}</small>
|
||||
<small>{profileBirthTimeStatusLabel(record.profile)} · {formatChartUpdatedAt(record.updatedAt)}</small>
|
||||
</div>
|
||||
</article>
|
||||
))}
|
||||
{chartLibrary.filter((record) => record.role === "self").length === 0 && <p className="empty-library-copy">请先在个人资料中补全你的出生资料。</p>}
|
||||
</div>
|
||||
<div className="chart-library-group">
|
||||
<div className="chart-library-group-heading">
|
||||
<div><b>其他人的星盘</b><small>亲友、伴侣或客户资料</small></div>
|
||||
<span className="chart-library-count">{chartLibrary.filter((record) => record.role === "other").length}</span>
|
||||
</div>
|
||||
{chartLibrary.filter((record) => record.role === "other").length === 0 && <p className="empty-library-copy">还没有其他星盘,先添加一份资料。</p>}
|
||||
{chartLibrary.filter((record) => record.role === "other").map((record) => (
|
||||
<article className="chart-library-item" key={record.id}>
|
||||
<div className="chart-library-item-main">
|
||||
<div className="chart-library-item-title"><strong>{record.profile.name || "未命名"}</strong><span className="chart-role-badge">其他人</span></div>
|
||||
<small>{record.profile.date || "出生日期待补全"} · {profileBirthTimeLabel(record.profile)} · {profilePlaceLabel(record.profile)}</small>
|
||||
<small>{profileBirthTimeStatusLabel(record.profile)} · {formatChartUpdatedAt(record.updatedAt)}</small>
|
||||
</div>
|
||||
<div className="chart-library-actions">
|
||||
<select aria-label={`${record.profile.name || "其他人"}的关系类型`} value={synastryRelationshipType} onChange={(event) => setSynastryRelationshipType(event.target.value as SynastryRelationshipType)} disabled={synastryPendingId !== null}>
|
||||
<option value="romance">婚恋</option>
|
||||
<option value="business">商业合作</option>
|
||||
<option value="family">亲友/家庭</option>
|
||||
<option value="general">其他关系</option>
|
||||
</select>
|
||||
<button className="button-secondary" type="button" onClick={() => void draftSynastryQuestionFromChart(record, synastryRelationshipType)} disabled={synastryPendingId !== null}>{synastryPendingId === record.id ? "正在计算合盘..." : "用于合盘"}</button>
|
||||
<button className="button-secondary" type="button" onClick={() => void makeDefaultChart(record)} disabled={profileSaving}>设为默认</button>
|
||||
<button className="button-secondary" type="button" onClick={() => deleteOtherChart(record.id)}>删除</button>
|
||||
</div>
|
||||
</article>
|
||||
))}
|
||||
</div>
|
||||
{synastryReportCard && (
|
||||
<article className="synastry-report-card" aria-label="合盘结果摘要">
|
||||
<div>
|
||||
|
||||
Reference in New Issue
Block a user