feat: Implement cancel functionality in settings forms to revert to the last saved state and disable the cancel button when no changes are made.

This commit is contained in:
pradeepkumar
2026-03-20 12:53:13 +05:30
parent 2de25d7448
commit d5e3659ab2
2 changed files with 33 additions and 28 deletions

View File

@@ -54,6 +54,8 @@ export function NotificationsForm({ onSave }: NotificationsFormProps) {
const [notifications, setNotifications] = useState<NotificationCategory[]>(DEFAULT_NOTIFICATIONS); const [notifications, setNotifications] = useState<NotificationCategory[]>(DEFAULT_NOTIFICATIONS);
const [digestFrequency, setDigestFrequency] = useState<DigestFrequency>('instant'); const [digestFrequency, setDigestFrequency] = useState<DigestFrequency>('instant');
const [savedNotifications, setSavedNotifications] = useState<NotificationCategory[]>(DEFAULT_NOTIFICATIONS);
const [savedDigestFrequency, setSavedDigestFrequency] = useState<DigestFrequency>('instant');
const fetchPreferences = useCallback(async () => { const fetchPreferences = useCallback(async () => {
if (!session) return; if (!session) return;
@@ -67,8 +69,7 @@ export function NotificationsForm({ onSave }: NotificationsFormProps) {
const savedPrefs = response.data?.data || response.data || {}; const savedPrefs = response.data?.data || response.data || {};
if (savedPrefs.notifications) { if (savedPrefs.notifications) {
setNotifications((prev) => const updated = DEFAULT_NOTIFICATIONS.map((item) => {
prev.map((item) => {
const saved = savedPrefs.notifications[item.id]; const saved = savedPrefs.notifications[item.id];
if (saved) { if (saved) {
return { return {
@@ -78,12 +79,14 @@ export function NotificationsForm({ onSave }: NotificationsFormProps) {
}; };
} }
return item; return item;
}) });
); setNotifications(updated);
setSavedNotifications(updated);
} }
if (savedPrefs.digestFrequency) { if (savedPrefs.digestFrequency) {
setDigestFrequency(savedPrefs.digestFrequency); setDigestFrequency(savedPrefs.digestFrequency);
setSavedDigestFrequency(savedPrefs.digestFrequency);
} }
} catch { } catch {
console.log('No saved notification preferences found, using defaults'); console.log('No saved notification preferences found, using defaults');
@@ -126,6 +129,8 @@ export function NotificationsForm({ onSave }: NotificationsFormProps) {
await api.put(endpoint, preferences); await api.put(endpoint, preferences);
setSavedNotifications([...notifications]);
setSavedDigestFrequency(digestFrequency);
setSuccess('Notification preferences saved successfully!'); setSuccess('Notification preferences saved successfully!');
if (onSave) { if (onSave) {
@@ -141,9 +146,12 @@ export function NotificationsForm({ onSave }: NotificationsFormProps) {
} }
}; };
const hasChanges = JSON.stringify(notifications) !== JSON.stringify(savedNotifications) || digestFrequency !== savedDigestFrequency;
const handleCancel = () => { const handleCancel = () => {
setNotifications(DEFAULT_NOTIFICATIONS); if (!hasChanges) return;
setDigestFrequency('instant'); setNotifications([...savedNotifications]);
setDigestFrequency(savedDigestFrequency);
setError(null); setError(null);
setSuccess(null); setSuccess(null);
}; };
@@ -297,7 +305,8 @@ export function NotificationsForm({ onSave }: NotificationsFormProps) {
<button <button
type="button" type="button"
onClick={handleCancel} onClick={handleCancel}
className="px-10 py-3 border border-[#00293D]/10 rounded-[15px] font-fractul font-bold text-[14px] text-[#00293D] hover:bg-[#00293D]/5 transition-colors" disabled={!hasChanges || isSaving}
className="px-10 py-3 border border-[#00293D]/10 rounded-[15px] font-fractul font-bold text-[14px] text-[#00293D] hover:bg-[#00293D]/5 transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
> >
Cancel Cancel
</button> </button>

View File

@@ -330,19 +330,15 @@ export function ProfileSettingsForm({
} }
}; };
const hasChanges = originalData
? JSON.stringify(formData) !== JSON.stringify(originalData)
: false;
const handleCancel = () => { const handleCancel = () => {
// Reset to original fetched data (including phone) if (!hasChanges) return;
// Reset to last saved data
if (originalData) { if (originalData) {
setFormData(originalData); setFormData(originalData);
} else if (session?.user) {
// Fallback to session data if original not available
const nameParts = (session.user?.name || '').split(' ');
setFormData(prev => ({
...prev,
firstName: nameParts[0] || prev.firstName,
lastName: nameParts.slice(1).join(' ') || prev.lastName,
email: session.user?.email || prev.email,
}));
} }
setError(null); setError(null);
setSuccessMessage(null); setSuccessMessage(null);
@@ -528,8 +524,8 @@ export function ProfileSettingsForm({
<div className="mt-8 flex justify-end gap-3"> <div className="mt-8 flex justify-end gap-3">
<button <button
onClick={handleCancel} onClick={handleCancel}
disabled={isSaving} disabled={isSaving || !hasChanges}
className="px-8 py-3 border border-[#00293D]/30 text-[#00293D] rounded-[10px] font-serif font-medium text-[14px] hover:bg-[#00293d]/5 transition-colors disabled:opacity-50" className="px-8 py-3 border border-[#00293D]/30 text-[#00293D] rounded-[10px] font-serif font-medium text-[14px] hover:bg-[#00293d]/5 transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
> >
Cancel Cancel
</button> </button>