refactor: Simplify notification UI and improve UX
## ✅ UI/UX Improvements ### Channels Page **Changes:** 1. ✅ Removed "Active/Inactive" badge (redundant with color) 2. ✅ Renamed "Built-in Channels" → "Channels" 3. ✅ Moved "Built-in" badge inline with title 4. ✅ Removed redundant "Subscribe" toggle for push 5. ✅ Unified "Enable/Disable" toggle for all channels 6. ✅ Auto-subscribe when enabling push channel **Layout:** - Title + Built-in badge (inline) - Description - Enable/Disable toggle + Configure button - Green icon when enabled, gray when disabled **Addon Channels:** - Will show "Addon" badge instead of "Built-in" - Same consistent layout ### Events Page **Changes:** 1. ✅ Removed event-level toggle (too dense) 2. ✅ Cleaner header layout 3. ✅ Focus on per-channel toggles only **Logic:** - Each event can enable/disable specific channels - Channel-level toggle (Channels page) = global on/off - Per-event toggle (Events page) = event-specific on/off - Both must be enabled for notification to send ### Expected Behavior **Channel Toggle (Channels Page):** - Disables/enables channel globally - Affects all events - Stored in `woonoow_email_notifications_enabled` - Stored in `woonoow_push_notifications_enabled` **Per-Event Channel Toggle (Events Page):** - Enables/disables channel for specific event - Stored in `woonoow_notification_settings` - Independent per event **Notification Sending Logic:** ``` if (channel_globally_enabled && event_channel_enabled) { send_notification(); } ``` --- **UI is now cleaner and more intuitive!** ✨
This commit is contained in:
@@ -180,8 +180,8 @@ export default function NotificationChannels() {
|
|||||||
</div>
|
</div>
|
||||||
</SettingsCard>
|
</SettingsCard>
|
||||||
|
|
||||||
{/* Built-in Channels */}
|
{/* All Channels */}
|
||||||
<SettingsCard title={__('Built-in Channels')} description={__('Channels included with WooNooW')}>
|
<SettingsCard title={__('Channels')} description={__('Manage notification delivery channels')}>
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
{builtinChannels.map((channel: NotificationChannel) => (
|
{builtinChannels.map((channel: NotificationChannel) => (
|
||||||
<div key={channel.id} className="flex flex-col sm:flex-row sm:items-center gap-4 p-4 rounded-lg border bg-card">
|
<div key={channel.id} className="flex flex-col sm:flex-row sm:items-center gap-4 p-4 rounded-lg border bg-card">
|
||||||
@@ -192,19 +192,11 @@ export default function NotificationChannels() {
|
|||||||
<div className="flex-1 min-w-0">
|
<div className="flex-1 min-w-0">
|
||||||
<div className="flex items-center gap-2 mb-2">
|
<div className="flex items-center gap-2 mb-2">
|
||||||
<h3 className="font-medium">{channel.label}</h3>
|
<h3 className="font-medium">{channel.label}</h3>
|
||||||
</div>
|
|
||||||
<div className="flex flex-wrap items-center gap-2 mb-2">
|
|
||||||
<Badge variant="secondary" className="text-xs">
|
<Badge variant="secondary" className="text-xs">
|
||||||
{__('Built-in')}
|
{__('Built-in')}
|
||||||
</Badge>
|
</Badge>
|
||||||
<Badge
|
|
||||||
variant={channel.enabled ? 'default' : 'secondary'}
|
|
||||||
className={`text-xs ${channel.enabled ? 'bg-green-500 hover:bg-green-600' : ''}`}
|
|
||||||
>
|
|
||||||
{channel.enabled ? __('Active') : __('Inactive')}
|
|
||||||
</Badge>
|
|
||||||
</div>
|
</div>
|
||||||
<p className="text-sm text-muted-foreground mt-1">
|
<p className="text-sm text-muted-foreground">
|
||||||
{channel.id === 'email' &&
|
{channel.id === 'email' &&
|
||||||
__('Email notifications powered by WooCommerce. Configure templates and SMTP settings.')}
|
__('Email notifications powered by WooCommerce. Configure templates and SMTP settings.')}
|
||||||
{channel.id === 'push' &&
|
{channel.id === 'push' &&
|
||||||
@@ -222,6 +214,10 @@ export default function NotificationChannels() {
|
|||||||
checked={channel.enabled}
|
checked={channel.enabled}
|
||||||
onCheckedChange={(checked) => {
|
onCheckedChange={(checked) => {
|
||||||
toggleChannelMutation.mutate({ channelId: channel.id, enabled: checked });
|
toggleChannelMutation.mutate({ channelId: channel.id, enabled: checked });
|
||||||
|
// If enabling push, also subscribe
|
||||||
|
if (channel.id === 'push' && checked && pushSupported && !pushSubscribed) {
|
||||||
|
subscribeToPush.mutate();
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
disabled={toggleChannelMutation.isPending}
|
disabled={toggleChannelMutation.isPending}
|
||||||
/>
|
/>
|
||||||
@@ -239,24 +235,7 @@ export default function NotificationChannels() {
|
|||||||
<Settings className="h-4 w-4 sm:mr-2" />
|
<Settings className="h-4 w-4 sm:mr-2" />
|
||||||
<span className="sm:inline">{__('Configure')}</span>
|
<span className="sm:inline">{__('Configure')}</span>
|
||||||
</Button>
|
</Button>
|
||||||
{channel.id === 'push' && pushSupported && (
|
|
||||||
<div className="flex items-center justify-between sm:justify-start gap-2 p-2 sm:p-0 rounded-lg sm:rounded-none border sm:border-0">
|
|
||||||
<span className="text-sm text-muted-foreground">
|
|
||||||
{pushSubscribed ? __('Subscribed') : __('Not subscribed')}
|
|
||||||
</span>
|
|
||||||
<Switch
|
|
||||||
checked={pushSubscribed}
|
|
||||||
onCheckedChange={(checked) => {
|
|
||||||
if (checked) {
|
|
||||||
subscribeToPush.mutate();
|
|
||||||
} else {
|
|
||||||
unsubscribeFromPush.mutate();
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
disabled={subscribeToPush.isPending || unsubscribeFromPush.isPending}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{channel.id === 'push' && !pushSupported && (
|
{channel.id === 'push' && !pushSupported && (
|
||||||
<Badge variant="destructive" className="text-xs w-full sm:w-auto justify-center">
|
<Badge variant="destructive" className="text-xs w-full sm:w-auto justify-center">
|
||||||
{__('Not Supported')}
|
{__('Not Supported')}
|
||||||
|
|||||||
@@ -130,12 +130,9 @@ export default function NotificationEvents() {
|
|||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
{orderEvents.map((event: NotificationEvent) => (
|
{orderEvents.map((event: NotificationEvent) => (
|
||||||
<div key={event.id} className="pb-6 border-b last:border-0">
|
<div key={event.id} className="pb-6 border-b last:border-0">
|
||||||
<div className="flex items-start justify-between mb-4">
|
<div className="mb-4">
|
||||||
<div className="flex-1">
|
<h3 className="font-medium text-sm">{event.label}</h3>
|
||||||
<h3 className="font-medium text-sm">{event.label}</h3>
|
<p className="text-xs text-muted-foreground mt-1">{event.description}</p>
|
||||||
<p className="text-xs text-muted-foreground mt-1">{event.description}</p>
|
|
||||||
</div>
|
|
||||||
<Switch checked={event.enabled} disabled />
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Channel Selection */}
|
{/* Channel Selection */}
|
||||||
@@ -193,12 +190,9 @@ export default function NotificationEvents() {
|
|||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
{productEvents.map((event: NotificationEvent) => (
|
{productEvents.map((event: NotificationEvent) => (
|
||||||
<div key={event.id} className="pb-6 border-b last:border-0">
|
<div key={event.id} className="pb-6 border-b last:border-0">
|
||||||
<div className="flex items-start justify-between mb-4">
|
<div className="mb-4">
|
||||||
<div className="flex-1">
|
<h3 className="font-medium text-sm">{event.label}</h3>
|
||||||
<h3 className="font-medium text-sm">{event.label}</h3>
|
<p className="text-xs text-muted-foreground mt-1">{event.description}</p>
|
||||||
<p className="text-xs text-muted-foreground mt-1">{event.description}</p>
|
|
||||||
</div>
|
|
||||||
<Switch checked={event.enabled} disabled />
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="space-y-3">
|
<div className="space-y-3">
|
||||||
@@ -255,12 +249,9 @@ export default function NotificationEvents() {
|
|||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
{customerEvents.map((event: NotificationEvent) => (
|
{customerEvents.map((event: NotificationEvent) => (
|
||||||
<div key={event.id} className="pb-6 border-b last:border-0">
|
<div key={event.id} className="pb-6 border-b last:border-0">
|
||||||
<div className="flex items-start justify-between mb-4">
|
<div className="mb-4">
|
||||||
<div className="flex-1">
|
<h3 className="font-medium text-sm">{event.label}</h3>
|
||||||
<h3 className="font-medium text-sm">{event.label}</h3>
|
<p className="text-xs text-muted-foreground mt-1">{event.description}</p>
|
||||||
<p className="text-xs text-muted-foreground mt-1">{event.description}</p>
|
|
||||||
</div>
|
|
||||||
<Switch checked={event.enabled} disabled />
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="space-y-3">
|
<div className="space-y-3">
|
||||||
|
|||||||
Reference in New Issue
Block a user