Implement multi-channel notification system with: - Core notification service with email, push, and in-app channels - Email templates for all notification types (welcome, plant registered, transport alerts, farm alerts, harvest ready, demand matches, weekly digest) - Push notification support with VAPID authentication - In-app notification management with read/unread tracking - Notification scheduler for recurring and scheduled notifications - API endpoints for notifications CRUD, preferences, and subscriptions - UI components (NotificationBell, NotificationList, NotificationItem, PreferencesForm) - Full notifications page with preferences management - Service worker for push notification handling
72 lines
2.5 KiB
TypeScript
72 lines
2.5 KiB
TypeScript
/**
|
|
* Notifications Page
|
|
* Full-page notification management
|
|
*/
|
|
|
|
import React, { useState } from 'react';
|
|
import Head from 'next/head';
|
|
import { NotificationList } from '../components/notifications/NotificationList';
|
|
import { PreferencesForm } from '../components/notifications/PreferencesForm';
|
|
|
|
export default function NotificationsPage() {
|
|
const [activeTab, setActiveTab] = useState<'notifications' | 'preferences'>('notifications');
|
|
const userId = 'demo-user'; // In production, get from auth
|
|
|
|
return (
|
|
<>
|
|
<Head>
|
|
<title>Notifications - LocalGreenChain</title>
|
|
<meta name="description" content="Manage your notifications and preferences" />
|
|
</Head>
|
|
|
|
<div className="min-h-screen bg-gray-50">
|
|
{/* Header */}
|
|
<header className="bg-white border-b">
|
|
<div className="max-w-4xl mx-auto px-4 py-6">
|
|
<h1 className="text-2xl font-bold text-gray-900">Notifications</h1>
|
|
<p className="mt-1 text-gray-600">Manage your notifications and preferences</p>
|
|
</div>
|
|
</header>
|
|
|
|
{/* Tabs */}
|
|
<div className="bg-white border-b">
|
|
<div className="max-w-4xl mx-auto px-4">
|
|
<nav className="flex space-x-8" aria-label="Tabs">
|
|
<button
|
|
onClick={() => setActiveTab('notifications')}
|
|
className={`py-4 px-1 border-b-2 font-medium text-sm ${
|
|
activeTab === 'notifications'
|
|
? 'border-green-500 text-green-600'
|
|
: 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300'
|
|
}`}
|
|
>
|
|
All Notifications
|
|
</button>
|
|
<button
|
|
onClick={() => setActiveTab('preferences')}
|
|
className={`py-4 px-1 border-b-2 font-medium text-sm ${
|
|
activeTab === 'preferences'
|
|
? 'border-green-500 text-green-600'
|
|
: 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300'
|
|
}`}
|
|
>
|
|
Preferences
|
|
</button>
|
|
</nav>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Content */}
|
|
<main className="max-w-4xl mx-auto px-4 py-8">
|
|
{activeTab === 'notifications' ? (
|
|
<div className="bg-white rounded-lg border overflow-hidden">
|
|
<NotificationList userId={userId} showFilters />
|
|
</div>
|
|
) : (
|
|
<PreferencesForm userId={userId} />
|
|
)}
|
|
</main>
|
|
</div>
|
|
</>
|
|
);
|
|
}
|