実装完了

Backend(Django)
backend/apps/mail/serializers.py

MailEmailListSerializer を新規追加(フロントエンド向けメール一覧用)
feedback_token フィールドを含む(フィードバックリンク表示用)
backend/apps/mail/views.py

MailEmailCreateView → MailEmailView に変更(GET+POST を統合)
GET /api/mail/emails/ : JWT認証でメール履歴取得(最新100件、account/verdict フィルター対応)
POST /api/mail/emails/ : APIキー認証でWindmillからのメール記録(既存動作を維持)
get_permissions() でメソッドごとに認証方法を切替
MailStatsView を新規追加
GET /api/mail/stats/ : 今日の処理件数、LINE通知数、フィードバック待ち、ルール数を返す
backend/apps/mail/urls.py

emails/ → MailEmailView(GET+POST)
stats/ → MailStatsView を追加
Frontend(Next.js)
frontend/src/app/mail/history/page.tsx (新規作成)

メール処理履歴の一覧テーブル
アカウント・LLM判定でフィルタリング可能
LLM判定・フィードバック状態をバッジで表示
フィードバックトークンがあれば「回答」リンクを表示
frontend/src/app/dashboard/page.tsx (再設計)

2カラムのモジュールカード形式に変更
作付け計画カード: 年度セレクタ、集計数値、作物別集計、クイックアクセス
メール通知カード: 今日の処理件数、LINE通知数、フィードバック待ち、ルール数、メール履歴・ルール管理ボタン
This commit is contained in:
Akira
2026-02-22 15:01:50 +09:00
parent 7c40480599
commit 04b1ca1bb9
8 changed files with 504 additions and 121 deletions

View File

@@ -1,7 +1,7 @@
'use client';
import { useRouter, usePathname } from 'next/navigation';
import { LogOut, Wheat, MapPin, FileText, Upload, LayoutDashboard, Mail } from 'lucide-react';
import { LogOut, Wheat, MapPin, FileText, Upload, LayoutDashboard, Mail, History, Shield } from 'lucide-react';
import { logout } from '@/lib/api';
export default function Navbar() {
@@ -79,14 +79,25 @@ export default function Navbar() {
</button>
<button
onClick={() => router.push('/mail/rules')}
onClick={() => router.push('/mail/history')}
className={`flex items-center px-3 py-2 text-sm rounded-md transition-colors ${
pathname?.startsWith('/mail/')
isActive('/mail/history')
? 'text-green-700 bg-green-50'
: 'text-gray-700 hover:text-gray-900 hover:bg-gray-100'
}`}
>
<Mail className="h-4 w-4 mr-2" />
<History className="h-4 w-4 mr-2" />
</button>
<button
onClick={() => router.push('/mail/rules')}
className={`flex items-center px-3 py-2 text-sm rounded-md transition-colors ${
isActive('/mail/rules')
? 'text-green-700 bg-green-50'
: 'text-gray-700 hover:text-gray-900 hover:bg-gray-100'
}`}
>
<Shield className="h-4 w-4 mr-2" />
</button>
</div>