作付け計画画面 (/allocation):

年度をlocalStorageに保存・復元(ブラウザを閉じても維持、明示的に変えるまで固定)
過去年度を表示中は琥珀色のバナー「{year}年度のデータを参照中(過去年度)」+ 「今年度に戻る」ボタン
テーブル枠も過去年度では薄いセピア調に変化
デフォルトは今年度(2026)
帳票出力画面 (/reports):

デフォルトを 2025 固定 → new Date().getFullYear() に変更
セレクタも動的5年分に変更
ダッシュボード (/dashboard):

既に今年度デフォルト(変更不要)
記憶:

CLAUDE.md「重要な設計判断」に年度管理方針を追記済み
MEMORY.md に Phase 2 のグローバル作業年度導入方針を記録済み
This commit is contained in:
Akira
2026-02-20 16:52:38 +09:00
parent 6eb19f75b7
commit 9169018392
3 changed files with 44 additions and 11 deletions

View File

@@ -23,7 +23,13 @@ export default function AllocationPage() {
const [fields, setFields] = useState<Field[]>([]);
const [crops, setCrops] = useState<Crop[]>([]);
const [plans, setPlans] = useState<Plan[]>([]);
const [year, setYear] = useState<number>(2025);
const [year, setYear] = useState<number>(() => {
if (typeof window !== 'undefined') {
const saved = localStorage.getItem('allocationYear');
if (saved) return parseInt(saved);
}
return new Date().getFullYear();
});
const [loading, setLoading] = useState(true);
const [saving, setSaving] = useState<number | null>(null);
const [showSidebar, setShowSidebar] = useState(true);
@@ -44,9 +50,13 @@ export default function AllocationPage() {
const [filterUnassigned, setFilterUnassigned] = useState(false);
useEffect(() => {
localStorage.setItem('allocationYear', String(year));
fetchData();
}, [year]);
const currentYear = new Date().getFullYear();
const isPastYear = year < currentYear;
const fetchData = async (background = false) => {
if (!background) setLoading(true);
try {
@@ -540,7 +550,9 @@ export default function AllocationPage() {
<div className="flex-1 min-w-0 p-4 lg:p-0">
<div className="max-w-7xl mx-auto">
<div className="mb-6 flex flex-col sm:flex-row sm:items-center justify-between gap-4">
<h1 className="text-2xl font-bold text-gray-900"></h1>
<h1 className="text-2xl font-bold text-gray-900">
<span className="text-green-700">{year}</span>
</h1>
{/* スマホ用集計ボタン */}
<button
@@ -569,11 +581,11 @@ export default function AllocationPage() {
id="year"
value={year}
onChange={(e) => setYear(parseInt(e.target.value))}
className="px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-green-500"
className="px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-green-500 font-semibold"
>
<option value={2025}>2025</option>
<option value={2026}>2026</option>
<option value={2027}>2027</option>
{Array.from({ length: 5 }, (_, i) => new Date().getFullYear() - 2 + i).map((y) => (
<option key={y} value={y}>{y}</option>
))}
</select>
<button
@@ -649,6 +661,20 @@ export default function AllocationPage() {
</div>
) : (
<>
{isPastYear && (
<div className="mb-4 p-3 bg-amber-50 border border-amber-300 rounded-md flex items-center justify-between">
<p className="text-sm text-amber-800 font-medium">
{year}
</p>
<button
onClick={() => setYear(currentYear)}
className="text-sm text-amber-700 underline hover:text-amber-900"
>
{currentYear}
</button>
</div>
)}
<div className="mb-4 p-3 bg-blue-50 border border-blue-200 rounded-md">
<p className="text-sm text-blue-800">
💡
@@ -699,7 +725,7 @@ export default function AllocationPage() {
</div>
)}
<div className="bg-white rounded-lg shadow overflow-hidden">
<div className={`rounded-lg shadow overflow-hidden ${isPastYear ? 'bg-amber-50/50 ring-1 ring-amber-200' : 'bg-white'}`}>
<div className="overflow-x-auto">
<table className="min-w-full divide-y divide-gray-200">
<thead className="bg-gray-50">