Add whatsapp feature
This commit is contained in:
@@ -0,0 +1,377 @@
|
||||
import React from 'react';
|
||||
import { Bell, MessageSquare, Mail, AlertCircle, Globe } from 'lucide-react';
|
||||
import { Card, Input } from '../../../../../components/ui';
|
||||
import type { NotificationSettings } from '../../../../../api/types/settings';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
interface NotificationSettingsCardProps {
|
||||
settings: NotificationSettings;
|
||||
onChange: (settings: NotificationSettings) => void;
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
const NotificationSettingsCard: React.FC<NotificationSettingsCardProps> = ({
|
||||
settings,
|
||||
onChange,
|
||||
disabled = false,
|
||||
}) => {
|
||||
const { t } = useTranslation('ajustes');
|
||||
|
||||
const handleChange = (field: keyof NotificationSettings) => (
|
||||
e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement>
|
||||
) => {
|
||||
const value = e.target.type === 'checkbox' ? (e.target as HTMLInputElement).checked :
|
||||
e.target.value;
|
||||
onChange({ ...settings, [field]: value });
|
||||
};
|
||||
|
||||
const handleChannelChange = (field: 'po_notification_channels' | 'inventory_alert_channels' | 'production_alert_channels' | 'forecast_alert_channels', channel: string) => {
|
||||
const currentChannels = settings[field];
|
||||
const newChannels = currentChannels.includes(channel)
|
||||
? currentChannels.filter(c => c !== channel)
|
||||
: [...currentChannels, channel];
|
||||
onChange({ ...settings, [field]: newChannels });
|
||||
};
|
||||
|
||||
return (
|
||||
<Card className="p-6">
|
||||
<h3 className="text-lg font-semibold text-[var(--text-primary)] mb-6 flex items-center">
|
||||
<Bell className="w-5 h-5 mr-2 text-[var(--color-primary)]" />
|
||||
{t('notification.title')}
|
||||
</h3>
|
||||
|
||||
<div className="space-y-6">
|
||||
{/* WhatsApp Configuration */}
|
||||
<div>
|
||||
<h4 className="text-sm font-semibold text-[var(--text-secondary)] mb-4 flex items-center">
|
||||
<MessageSquare className="w-4 h-4 mr-2" />
|
||||
{t('notification.whatsapp_config')}
|
||||
</h4>
|
||||
<div className="space-y-4 pl-6">
|
||||
<div className="flex items-center gap-2">
|
||||
<input
|
||||
type="checkbox"
|
||||
id="whatsapp_enabled"
|
||||
checked={settings.whatsapp_enabled}
|
||||
onChange={handleChange('whatsapp_enabled')}
|
||||
disabled={disabled}
|
||||
className="rounded border-[var(--border-primary)]"
|
||||
/>
|
||||
<label htmlFor="whatsapp_enabled" className="text-sm text-[var(--text-secondary)]">
|
||||
{t('notification.whatsapp_enabled')}
|
||||
</label>
|
||||
</div>
|
||||
|
||||
{settings.whatsapp_enabled && (
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 mt-4">
|
||||
<Input
|
||||
label={t('notification.whatsapp_phone_number_id')}
|
||||
value={settings.whatsapp_phone_number_id}
|
||||
onChange={handleChange('whatsapp_phone_number_id')}
|
||||
disabled={disabled}
|
||||
placeholder="123456789012345"
|
||||
helperText={t('notification.whatsapp_phone_number_id_help')}
|
||||
/>
|
||||
|
||||
<Input
|
||||
type="password"
|
||||
label={t('notification.whatsapp_access_token')}
|
||||
value={settings.whatsapp_access_token}
|
||||
onChange={handleChange('whatsapp_access_token')}
|
||||
disabled={disabled}
|
||||
placeholder="EAAxxxxxxxx"
|
||||
helperText={t('notification.whatsapp_access_token_help')}
|
||||
/>
|
||||
|
||||
<Input
|
||||
label={t('notification.whatsapp_business_account_id')}
|
||||
value={settings.whatsapp_business_account_id}
|
||||
onChange={handleChange('whatsapp_business_account_id')}
|
||||
disabled={disabled}
|
||||
placeholder="987654321098765"
|
||||
helperText={t('notification.whatsapp_business_account_id_help')}
|
||||
/>
|
||||
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-[var(--text-secondary)] mb-2">
|
||||
{t('notification.whatsapp_api_version')}
|
||||
</label>
|
||||
<select
|
||||
value={settings.whatsapp_api_version}
|
||||
onChange={handleChange('whatsapp_api_version')}
|
||||
disabled={disabled}
|
||||
className="w-full px-3 py-2 border border-[var(--border-primary)] rounded-lg text-sm bg-[var(--bg-primary)] text-[var(--text-primary)] disabled:bg-[var(--bg-secondary)] disabled:text-[var(--text-secondary)]"
|
||||
>
|
||||
<option value="v18.0">v18.0</option>
|
||||
<option value="v19.0">v19.0</option>
|
||||
<option value="v20.0">v20.0</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-[var(--text-secondary)] mb-2">
|
||||
{t('notification.whatsapp_default_language')}
|
||||
</label>
|
||||
<select
|
||||
value={settings.whatsapp_default_language}
|
||||
onChange={handleChange('whatsapp_default_language')}
|
||||
disabled={disabled}
|
||||
className="w-full px-3 py-2 border border-[var(--border-primary)] rounded-lg text-sm bg-[var(--bg-primary)] text-[var(--text-primary)] disabled:bg-[var(--bg-secondary)] disabled:text-[var(--text-secondary)]"
|
||||
>
|
||||
<option value="es">Español</option>
|
||||
<option value="eu">Euskara</option>
|
||||
<option value="en">English</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{settings.whatsapp_enabled && (
|
||||
<div className="mt-4 p-4 bg-blue-50 dark:bg-blue-900/20 rounded-lg border border-blue-200 dark:border-blue-800">
|
||||
<div className="flex items-start gap-2">
|
||||
<AlertCircle className="w-4 h-4 text-blue-600 dark:text-blue-400 mt-0.5 flex-shrink-0" />
|
||||
<div className="text-xs text-blue-700 dark:text-blue-300">
|
||||
<p className="font-semibold mb-1">{t('notification.whatsapp_setup_note')}</p>
|
||||
<ul className="list-disc list-inside space-y-1">
|
||||
<li>{t('notification.whatsapp_setup_step1')}</li>
|
||||
<li>{t('notification.whatsapp_setup_step2')}</li>
|
||||
<li>{t('notification.whatsapp_setup_step3')}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Email Configuration */}
|
||||
<div>
|
||||
<h4 className="text-sm font-semibold text-[var(--text-secondary)] mb-4 flex items-center">
|
||||
<Mail className="w-4 h-4 mr-2" />
|
||||
{t('notification.email_config')}
|
||||
</h4>
|
||||
<div className="space-y-4 pl-6">
|
||||
<div className="flex items-center gap-2">
|
||||
<input
|
||||
type="checkbox"
|
||||
id="email_enabled"
|
||||
checked={settings.email_enabled}
|
||||
onChange={handleChange('email_enabled')}
|
||||
disabled={disabled}
|
||||
className="rounded border-[var(--border-primary)]"
|
||||
/>
|
||||
<label htmlFor="email_enabled" className="text-sm text-[var(--text-secondary)]">
|
||||
{t('notification.email_enabled')}
|
||||
</label>
|
||||
</div>
|
||||
|
||||
{settings.email_enabled && (
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 mt-4">
|
||||
<Input
|
||||
type="email"
|
||||
label={t('notification.email_from_address')}
|
||||
value={settings.email_from_address}
|
||||
onChange={handleChange('email_from_address')}
|
||||
disabled={disabled}
|
||||
placeholder="orders@yourbakery.com"
|
||||
/>
|
||||
|
||||
<Input
|
||||
label={t('notification.email_from_name')}
|
||||
value={settings.email_from_name}
|
||||
onChange={handleChange('email_from_name')}
|
||||
disabled={disabled}
|
||||
placeholder="Your Bakery Name"
|
||||
/>
|
||||
|
||||
<Input
|
||||
type="email"
|
||||
label={t('notification.email_reply_to')}
|
||||
value={settings.email_reply_to}
|
||||
onChange={handleChange('email_reply_to')}
|
||||
disabled={disabled}
|
||||
placeholder="info@yourbakery.com"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Notification Preferences */}
|
||||
<div>
|
||||
<h4 className="text-sm font-semibold text-[var(--text-secondary)] mb-4 flex items-center">
|
||||
<Globe className="w-4 h-4 mr-2" />
|
||||
{t('notification.preferences')}
|
||||
</h4>
|
||||
<div className="space-y-4 pl-6">
|
||||
{/* PO Notifications */}
|
||||
<div className="space-y-2">
|
||||
<div className="flex items-center gap-2">
|
||||
<input
|
||||
type="checkbox"
|
||||
id="enable_po_notifications"
|
||||
checked={settings.enable_po_notifications}
|
||||
onChange={handleChange('enable_po_notifications')}
|
||||
disabled={disabled}
|
||||
className="rounded border-[var(--border-primary)]"
|
||||
/>
|
||||
<label htmlFor="enable_po_notifications" className="text-sm font-medium text-[var(--text-secondary)]">
|
||||
{t('notification.enable_po_notifications')}
|
||||
</label>
|
||||
</div>
|
||||
{settings.enable_po_notifications && (
|
||||
<div className="pl-6 flex gap-4">
|
||||
<label className="flex items-center gap-2 text-sm text-[var(--text-tertiary)]">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={settings.po_notification_channels.includes('email')}
|
||||
onChange={() => handleChannelChange('po_notification_channels', 'email')}
|
||||
disabled={disabled}
|
||||
className="rounded border-[var(--border-primary)]"
|
||||
/>
|
||||
Email
|
||||
</label>
|
||||
<label className="flex items-center gap-2 text-sm text-[var(--text-tertiary)]">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={settings.po_notification_channels.includes('whatsapp')}
|
||||
onChange={() => handleChannelChange('po_notification_channels', 'whatsapp')}
|
||||
disabled={disabled || !settings.whatsapp_enabled}
|
||||
className="rounded border-[var(--border-primary)]"
|
||||
/>
|
||||
WhatsApp
|
||||
</label>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Inventory Alerts */}
|
||||
<div className="space-y-2">
|
||||
<div className="flex items-center gap-2">
|
||||
<input
|
||||
type="checkbox"
|
||||
id="enable_inventory_alerts"
|
||||
checked={settings.enable_inventory_alerts}
|
||||
onChange={handleChange('enable_inventory_alerts')}
|
||||
disabled={disabled}
|
||||
className="rounded border-[var(--border-primary)]"
|
||||
/>
|
||||
<label htmlFor="enable_inventory_alerts" className="text-sm font-medium text-[var(--text-secondary)]">
|
||||
{t('notification.enable_inventory_alerts')}
|
||||
</label>
|
||||
</div>
|
||||
{settings.enable_inventory_alerts && (
|
||||
<div className="pl-6 flex gap-4">
|
||||
<label className="flex items-center gap-2 text-sm text-[var(--text-tertiary)]">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={settings.inventory_alert_channels.includes('email')}
|
||||
onChange={() => handleChannelChange('inventory_alert_channels', 'email')}
|
||||
disabled={disabled}
|
||||
className="rounded border-[var(--border-primary)]"
|
||||
/>
|
||||
Email
|
||||
</label>
|
||||
<label className="flex items-center gap-2 text-sm text-[var(--text-tertiary)]">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={settings.inventory_alert_channels.includes('whatsapp')}
|
||||
onChange={() => handleChannelChange('inventory_alert_channels', 'whatsapp')}
|
||||
disabled={disabled || !settings.whatsapp_enabled}
|
||||
className="rounded border-[var(--border-primary)]"
|
||||
/>
|
||||
WhatsApp
|
||||
</label>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Production Alerts */}
|
||||
<div className="space-y-2">
|
||||
<div className="flex items-center gap-2">
|
||||
<input
|
||||
type="checkbox"
|
||||
id="enable_production_alerts"
|
||||
checked={settings.enable_production_alerts}
|
||||
onChange={handleChange('enable_production_alerts')}
|
||||
disabled={disabled}
|
||||
className="rounded border-[var(--border-primary)]"
|
||||
/>
|
||||
<label htmlFor="enable_production_alerts" className="text-sm font-medium text-[var(--text-secondary)]">
|
||||
{t('notification.enable_production_alerts')}
|
||||
</label>
|
||||
</div>
|
||||
{settings.enable_production_alerts && (
|
||||
<div className="pl-6 flex gap-4">
|
||||
<label className="flex items-center gap-2 text-sm text-[var(--text-tertiary)]">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={settings.production_alert_channels.includes('email')}
|
||||
onChange={() => handleChannelChange('production_alert_channels', 'email')}
|
||||
disabled={disabled}
|
||||
className="rounded border-[var(--border-primary)]"
|
||||
/>
|
||||
Email
|
||||
</label>
|
||||
<label className="flex items-center gap-2 text-sm text-[var(--text-tertiary)]">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={settings.production_alert_channels.includes('whatsapp')}
|
||||
onChange={() => handleChannelChange('production_alert_channels', 'whatsapp')}
|
||||
disabled={disabled || !settings.whatsapp_enabled}
|
||||
className="rounded border-[var(--border-primary)]"
|
||||
/>
|
||||
WhatsApp
|
||||
</label>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Forecast Alerts */}
|
||||
<div className="space-y-2">
|
||||
<div className="flex items-center gap-2">
|
||||
<input
|
||||
type="checkbox"
|
||||
id="enable_forecast_alerts"
|
||||
checked={settings.enable_forecast_alerts}
|
||||
onChange={handleChange('enable_forecast_alerts')}
|
||||
disabled={disabled}
|
||||
className="rounded border-[var(--border-primary)]"
|
||||
/>
|
||||
<label htmlFor="enable_forecast_alerts" className="text-sm font-medium text-[var(--text-secondary)]">
|
||||
{t('notification.enable_forecast_alerts')}
|
||||
</label>
|
||||
</div>
|
||||
{settings.enable_forecast_alerts && (
|
||||
<div className="pl-6 flex gap-4">
|
||||
<label className="flex items-center gap-2 text-sm text-[var(--text-tertiary)]">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={settings.forecast_alert_channels.includes('email')}
|
||||
onChange={() => handleChannelChange('forecast_alert_channels', 'email')}
|
||||
disabled={disabled}
|
||||
className="rounded border-[var(--border-primary)]"
|
||||
/>
|
||||
Email
|
||||
</label>
|
||||
<label className="flex items-center gap-2 text-sm text-[var(--text-tertiary)]">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={settings.forecast_alert_channels.includes('whatsapp')}
|
||||
onChange={() => handleChannelChange('forecast_alert_channels', 'whatsapp')}
|
||||
disabled={disabled || !settings.whatsapp_enabled}
|
||||
className="rounded border-[var(--border-primary)]"
|
||||
/>
|
||||
WhatsApp
|
||||
</label>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
|
||||
export default NotificationSettingsCard;
|
||||
Reference in New Issue
Block a user