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:
@@ -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,23 +69,24 @@ 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 {
|
...item,
|
||||||
...item,
|
email: saved.email ?? item.email,
|
||||||
email: saved.email ?? item.email,
|
inApp: saved.inApp ?? item.inApp,
|
||||||
inApp: saved.inApp ?? item.inApp,
|
};
|
||||||
};
|
}
|
||||||
}
|
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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
Reference in New Issue
Block a user