feat(parent-portal): docker 构建修复 + 禁用 mock + 记录下游待办

Dockerfile 改用 standalone 模式

next.config.js 添加 output standalone

修复 cssnano-simple 构建失败:globals.css 注释含 */ 被误解析

tailwind.config.js 覆盖 boxShadow 为 rgba 格式 + 禁用 ringWidth

组件修复:替换 / 语法为 inline style 或自定义类

otel.ts 添加 webpackIgnore 跳过 optionalDependencies 静态分析

.env.example 默认禁用 mock

新增 .dockerignore 和 docs/nextstep.md

删除 postcss.config.js

验证:Docker 镜像构建成功,容器 healthy,typecheck + lint 零错误
This commit is contained in:
SpecialX
2026-07-13 17:21:39 +08:00
parent 8b729a710f
commit 96a936e154
14 changed files with 453 additions and 55 deletions

View File

@@ -57,9 +57,16 @@ export function AttendanceCalendar({
month,
onMonthChange,
}: AttendanceCalendarProps) {
const { year, month: monthLabel, days, recordMap } = useMemo(() => {
const {
year,
month: monthLabel,
days,
recordMap,
} = useMemo(() => {
const now = new Date();
const target = month ? parseMonth(month) : { year: now.getFullYear(), month: now.getMonth() };
const target = month
? parseMonth(month)
: { year: now.getFullYear(), month: now.getMonth() };
const y = target.year;
const m = target.month;
const firstDay = new Date(y, m, 1);
@@ -96,7 +103,9 @@ export function AttendanceCalendar({
{onMonthChange && (
<button
type="button"
onClick={() => onMonthChange(shiftMonth(formatMonth(year, monthLabel), -1))}
onClick={() =>
onMonthChange(shiftMonth(formatMonth(year, monthLabel), -1))
}
className="rounded px-2 py-1 text-sm text-ink-muted hover:text-ink"
aria-label="上一月"
>
@@ -109,7 +118,9 @@ export function AttendanceCalendar({
{onMonthChange && (
<button
type="button"
onClick={() => onMonthChange(shiftMonth(formatMonth(year, monthLabel), 1))}
onClick={() =>
onMonthChange(shiftMonth(formatMonth(year, monthLabel), 1))
}
className="rounded px-2 py-1 text-sm text-ink-muted hover:text-ink"
aria-label="下一月"
>
@@ -146,14 +157,15 @@ export function AttendanceCalendar({
<div className="mt-1 grid grid-cols-7 gap-1">
{days.map((day, idx) => {
if (day === null) {
return <div key={idx} className="aspect-square" />;
return <div key={idx} style={{ aspectRatio: "1 / 1" }} />;
}
const dateStr = `${year}-${String(monthLabel + 1).padStart(2, "0")}-${String(day).padStart(2, "0")}`;
const record = recordMap.get(dateStr);
return (
<div
key={idx}
className="flex aspect-square flex-col items-center justify-center rounded text-sm"
className="flex flex-col items-center justify-center rounded text-sm"
style={{ aspectRatio: "1 / 1" }}
title={record ? STATUS_LABELS[record.status] : undefined}
>
<span className="text-xs">{day}</span>