mirror of
https://github.com/chillpadclub/bedolaga-cabinet.git
synced 2026-07-30 02:23:47 +00:00
fix: unify toast notifications and improve visual/behavior
- Solid opaque background with colored left border instead of translucent gradient - Max 3 visible toasts with oldest eviction - Telegram safe area support via env(safe-area-inset-*) - Dismiss by clicking anywhere on toast, removed X button - Adaptive width: full-width on mobile, fixed on desktop - AdminEmailTemplates: removed local toast, migrated to useNotify - AdminUsers: migrated from useToast to useNotify
This commit is contained in:
@@ -169,10 +169,6 @@ function TemplateEditor({
|
||||
const [editSubject, setEditSubject] = useState('');
|
||||
const [editBody, setEditBody] = useState('');
|
||||
const [isDirty, setIsDirty] = useState(false);
|
||||
const [toast, setToast] = useState<{
|
||||
type: 'success' | 'error' | 'info';
|
||||
message: string;
|
||||
} | null>(null);
|
||||
const textareaRef = useRef<HTMLTextAreaElement>(null);
|
||||
|
||||
const langData: EmailTemplateLanguageData | undefined = detail.languages[activeLang];
|
||||
@@ -186,11 +182,6 @@ function TemplateEditor({
|
||||
}
|
||||
}, [activeLang, langData]);
|
||||
|
||||
const showToast = useCallback((type: 'success' | 'error' | 'info', message: string) => {
|
||||
setToast({ type, message });
|
||||
setTimeout(() => setToast(null), 3000);
|
||||
}, []);
|
||||
|
||||
// Extract body content from full HTML (strip base template wrapper)
|
||||
const extractBodyContent = useCallback((html: string): string => {
|
||||
// If it's wrapped in the base template, extract just the content div
|
||||
@@ -230,10 +221,10 @@ function TemplateEditor({
|
||||
queryKey: ['admin', 'email-template', detail.notification_type],
|
||||
});
|
||||
setIsDirty(false);
|
||||
showToast('success', t('admin.emailTemplates.saved'));
|
||||
notify.success(t('admin.emailTemplates.saved'));
|
||||
},
|
||||
onError: () => {
|
||||
showToast('error', t('common.error'));
|
||||
notify.error(t('common.error'));
|
||||
},
|
||||
});
|
||||
|
||||
@@ -246,10 +237,10 @@ function TemplateEditor({
|
||||
queryKey: ['admin', 'email-template', detail.notification_type],
|
||||
});
|
||||
setIsDirty(false);
|
||||
showToast('success', t('admin.emailTemplates.resetted'));
|
||||
notify.success(t('admin.emailTemplates.resetted'));
|
||||
},
|
||||
onError: () => {
|
||||
showToast('error', t('common.error'));
|
||||
notify.error(t('common.error'));
|
||||
},
|
||||
});
|
||||
|
||||
@@ -260,10 +251,10 @@ function TemplateEditor({
|
||||
language: activeLang,
|
||||
}),
|
||||
onSuccess: (data) => {
|
||||
showToast('success', `${t('admin.emailTemplates.testSent')} → ${data.sent_to}`);
|
||||
notify.success(`${t('admin.emailTemplates.testSent')} → ${data.sent_to}`);
|
||||
},
|
||||
onError: () => {
|
||||
showToast('error', t('common.error'));
|
||||
notify.error(t('common.error'));
|
||||
},
|
||||
});
|
||||
|
||||
@@ -360,7 +351,7 @@ function TemplateEditor({
|
||||
title={t('admin.emailTemplates.clickToCopy')}
|
||||
onClick={() => {
|
||||
navigator.clipboard.writeText(`{${v}}`);
|
||||
showToast('success', `Copied {${v}}`);
|
||||
notify.success(`Copied {${v}}`);
|
||||
}}
|
||||
>
|
||||
{`{${v}}`}
|
||||
@@ -448,21 +439,6 @@ function TemplateEditor({
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Toast */}
|
||||
{toast && (
|
||||
<div
|
||||
className={`fixed left-4 right-4 top-32 z-[100] mx-auto max-w-sm animate-fade-in rounded-xl px-4 py-3 text-center text-sm font-medium shadow-lg sm:left-1/2 sm:right-auto sm:-translate-x-1/2 ${
|
||||
toast.type === 'success'
|
||||
? 'bg-success-500 text-white'
|
||||
: toast.type === 'info'
|
||||
? 'bg-dark-700 text-dark-100 ring-1 ring-dark-600'
|
||||
: 'bg-error-500 text-white'
|
||||
}`}
|
||||
>
|
||||
{toast.message}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user