Reduce homepage confusion during temporary routing issues

Add a prominent homepage notice for the current reverse-proxy redirect problem and tighten the Gitea activity presentation so the landing page stays readable while users navigate around the temporary deployment constraint.

Constraint: Temporary Nginx reverse-proxy redirects can drop :2000 from navigation URLs and cause 502 responses
Rejected: Move the warning into secondary pages only | Users need the fix before they leave the homepage
Confidence: high
Scope-risk: narrow
Directive: Remove or rewrite the homepage warning once the备案-backed domain setup eliminates the redirect mismatch
Tested: npm run build
Not-tested: Live browser verification against the current reverse-proxy deployment
This commit is contained in:
SepComet 2026-05-07 15:59:29 +08:00
parent 8d6e599ea9
commit 64df5623a5
3 changed files with 129 additions and 19 deletions

View File

@ -1,7 +1,7 @@
--- ---
import type { GiteaActivityData } from '../data/loaders'; import type { GiteaActivityData } from '../data/loaders';
import { site } from '../config'; import { site } from '../config';
import { formatDateTime } from '../utils/datetime'; import { formatDate, formatDateTime } from '../utils/datetime';
import SyncMeta from './SyncMeta.astro'; import SyncMeta from './SyncMeta.astro';
interface Props { interface Props {
@ -12,21 +12,47 @@ const { activity } = Astro.props;
const heatmapLevels = ['#0f172a', '#13233e', '#1d4ed8', '#2563eb', '#22c55e']; const heatmapLevels = ['#0f172a', '#13233e', '#1d4ed8', '#2563eb', '#22c55e'];
const heatmapSize = 70; const heatmapSize = 70;
const heatmapCounts = activity.days.slice(-heatmapSize).map((day) => day.count); const recentDays = activity.days.slice(-heatmapSize);
const heatmapCounts = recentDays.map((day) => day.count);
const maxCount = Math.max(...heatmapCounts, 0); const maxCount = Math.max(...heatmapCounts, 0);
const heatmap = Array.from({ length: heatmapSize }, (_, index) => {
const count = heatmapCounts[index] ?? 0;
if (count <= 0 || maxCount <= 0) { function getCurrentIsoDay() {
return 0; const parts = new Intl.DateTimeFormat('en-CA', {
timeZone: 'Asia/Shanghai',
year: 'numeric',
month: '2-digit',
day: '2-digit',
}).formatToParts(new Date());
const year = parts.find((part) => part.type === 'year')?.value ?? '0000';
const month = parts.find((part) => part.type === 'month')?.value ?? '00';
const day = parts.find((part) => part.type === 'day')?.value ?? '00';
return `${year}-${month}-${day}`;
} }
return Math.min( const currentIsoDay = getCurrentIsoDay();
const heatmap = recentDays.map((day) => {
const count = day.count ?? 0;
const level =
count <= 0 || maxCount <= 0
? 0
: Math.min(
heatmapLevels.length - 1, heatmapLevels.length - 1,
Math.max(1, Math.ceil((count / maxCount) * (heatmapLevels.length - 1))), Math.max(1, Math.ceil((count / maxCount) * (heatmapLevels.length - 1))),
); );
return {
...day,
level,
displayDate: formatDate(day.date) || day.date,
isToday: day.date === currentIsoDay,
};
}); });
const heatmapRangeStart = heatmap[0]?.displayDate;
const heatmapRangeEnd = heatmap.at(-1)?.displayDate;
function cleanText(value?: string) { function cleanText(value?: string) {
return value?.replace(/\s+/g, ' ').trim() || ''; return value?.replace(/\s+/g, ' ').trim() || '';
} }
@ -111,11 +137,12 @@ const isPlaceholder = activity.source === 'placeholder';
/> />
<div class="heatmap" aria-label="Gitea 贡献热力图"> <div class="heatmap" aria-label="Gitea 贡献热力图">
{ {
heatmap.map((level) => ( heatmap.map((day) => (
<span <span
class="heatmap-cell" class:list={['heatmap-cell', day.isToday && 'heatmap-cell--today']}
style={`background:${heatmapLevels[level]};`} style={`background:${heatmapLevels[day.level]};`}
aria-hidden="true" title={`${day.displayDate} · ${day.count} 次提交`}
aria-label={`${day.displayDate}${day.count} 次提交${day.isToday ? ',今天' : ''}`}
/> />
)) ))
} }
@ -127,6 +154,12 @@ const isPlaceholder = activity.source === 'placeholder';
</span> </span>
<span>低 → 高</span> <span>低 → 高</span>
</div> </div>
<p class="heatmap-note">
{heatmapRangeStart && heatmapRangeEnd
? `最近 70 天(${heatmapRangeStart} - ${heatmapRangeEnd}),左上最早、右下最新;悬停可查看具体日期和提交次数。`
: '最近 70 天,左上最早、右下最新;悬停可查看具体日期和提交次数。'}
<span class="heatmap-note__today">描边高亮表示今天。</span>
</p>
</div> </div>
<div class="activity-list"> <div class="activity-list">
@ -135,7 +168,7 @@ const isPlaceholder = activity.source === 'placeholder';
recentActivities.map((item) => ( recentActivities.map((item) => (
<article class="activity-item"> <article class="activity-item">
<p class="activity-item__repo mono">{item.repo}</p> <p class="activity-item__repo mono">{item.repo}</p>
<p class="activity-copy">{item.message}</p> <p class="activity-copy" title={item.message}>{item.message}</p>
<p class="activity-meta activity-item__meta"> <p class="activity-meta activity-item__meta">
<time datetime={item.rawTime}>{item.displayTime}</time> <time datetime={item.rawTime}>{item.displayTime}</time>
</p> </p>

View File

@ -37,6 +37,19 @@ const featuredProjectsUpdatedAt = getLatestDate(
<p class="hero-subtitle">{site.tagline}</p> <p class="hero-subtitle">{site.tagline}</p>
<p class="hero-meta">{site.description}</p> <p class="hero-meta">{site.description}</p>
<div class="hero-notice" role="note" aria-label="访问提示">
<p class="hero-notice__title">临时访问说明</p>
<p class="hero-notice__body">
如果点击顶部导航后页面跳到
<code>106.12.111.150/logs</code>
这类
<strong>不带 :2000</strong>
的地址并出现 502请手动把地址改成
<code>106.12.111.150:2000/对应路径</code>
即可正常访问其他视图。这个问题是当前 Nginx 反代导致的临时现象,等域名备案完成后会恢复正常。
</p>
</div>
<div class="hero-actions"> <div class="hero-actions">
<a class="button-primary" href="/projects">查看精选项目</a> <a class="button-primary" href="/projects">查看精选项目</a>
<a class="button-secondary" href="/logs">阅读开发日志</a> <a class="button-secondary" href="/logs">阅读开发日志</a>

View File

@ -216,6 +216,37 @@ main {
color: var(--muted); color: var(--muted);
} }
.hero-notice {
margin: 0 0 1.25rem;
padding: 1rem 1.1rem;
border: 1px solid rgba(245, 158, 11, 0.35);
border-radius: 1rem;
background: linear-gradient(135deg, rgba(245, 158, 11, 0.14), rgba(249, 115, 22, 0.08));
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.35);
}
.hero-notice__title {
margin: 0 0 0.5rem;
font-family: 'Archivo', sans-serif;
font-size: 0.98rem;
font-weight: 700;
color: #9a3412;
}
.hero-notice__body {
margin: 0;
color: #7c2d12;
line-height: 1.75;
}
.hero-notice code {
padding: 0.12rem 0.4rem;
border-radius: 0.45rem;
background: rgba(255, 255, 255, 0.72);
font-family: 'Fira Code', monospace;
font-size: 0.86em;
}
.hero-actions, .hero-actions,
.inline-links, .inline-links,
.tag-list, .tag-list,
@ -524,7 +555,7 @@ main {
display: grid; display: grid;
grid-template-columns: minmax(0, 1.3fr) minmax(18rem, 0.85fr); grid-template-columns: minmax(0, 1.3fr) minmax(18rem, 0.85fr);
gap: 1.25rem; gap: 1.25rem;
align-items: start; align-items: stretch;
} }
.heatmap { .heatmap {
@ -535,11 +566,19 @@ main {
} }
.heatmap-cell { .heatmap-cell {
position: relative;
aspect-ratio: 1; aspect-ratio: 1;
border-radius: 0.5rem; border-radius: 0.5rem;
border: 1px solid rgba(148, 163, 184, 0.22); border: 1px solid rgba(148, 163, 184, 0.22);
} }
.heatmap-cell--today {
border-color: rgba(255, 255, 255, 0.96);
box-shadow:
0 0 0 2px rgba(59, 130, 246, 0.5),
0 0 0 4px rgba(255, 255, 255, 0.12);
}
.heatmap-legend { .heatmap-legend {
display: flex; display: flex;
align-items: center; align-items: center;
@ -548,6 +587,20 @@ main {
font-size: 0.8rem; font-size: 0.8rem;
} }
.heatmap-note {
margin: 0.75rem 0 0;
color: rgba(226, 232, 240, 0.86);
font-size: 0.84rem;
line-height: 1.7;
}
.heatmap-note__today {
display: inline-block;
margin-left: 0.4rem;
color: #dbeafe;
font-weight: 600;
}
.legend-scale { .legend-scale {
display: inline-flex; display: inline-flex;
gap: 0.35rem; gap: 0.35rem;
@ -562,12 +615,16 @@ main {
.activity-list { .activity-list {
display: grid; display: grid;
grid-template-rows: repeat(4, minmax(0, 1fr));
gap: 0.75rem; gap: 0.75rem;
min-width: 0; min-width: 0;
} }
.activity-item { .activity-item {
display: flex;
flex-direction: column;
min-width: 0; min-width: 0;
min-height: 7.5rem;
padding: 0.95rem 1rem; padding: 0.95rem 1rem;
border: 1px solid rgba(148, 163, 184, 0.22); border: 1px solid rgba(148, 163, 184, 0.22);
border-radius: 1rem; border-radius: 1rem;
@ -581,11 +638,16 @@ main {
} }
.activity-panel .activity-copy { .activity-panel .activity-copy {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
overflow-wrap: anywhere; overflow-wrap: anywhere;
} }
.activity-item__meta { .activity-item__meta {
margin-top: 0.55rem; margin-top: auto;
padding-top: 0.55rem;
} }
.corner-gallery { .corner-gallery {
@ -706,8 +768,10 @@ main {
} }
.card-grid, .card-grid,
.status-panel__grid { .status-panel__grid,
.activity-list {
grid-template-columns: 1fr; grid-template-columns: 1fr;
grid-template-rows: none;
} }
.section-heading, .section-heading,