@oxyhq/services
Version:
132 lines (126 loc) • 3.69 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
exports.useSettingToggle = useSettingToggle;
exports.useSettingToggles = useSettingToggles;
var _react = require("react");
var _sonner = require("../../lib/sonner");
/**
* Hook for handling boolean toggle settings with optimistic updates.
* Automatically reverts to the previous value if the save fails.
*
* @example
* const { value, toggle, isSaving } = useSettingToggle({
* initialValue: user.notificationsEnabled,
* onSave: (value) => api.updateNotifications(value),
* errorMessage: 'Failed to update notifications',
* });
*
* <Switch value={value} onValueChange={toggle} disabled={isSaving} />
*/
function useSettingToggle(options) {
const {
initialValue,
onSave,
successMessage,
errorMessage = 'Failed to save setting',
revertOnError = true,
showSuccessToast = false
} = options;
const [value, setValue] = (0, _react.useState)(initialValue);
const [isSaving, setIsSaving] = (0, _react.useState)(false);
// Update value when initialValue changes (e.g., from server)
(0, _react.useEffect)(() => {
setValue(initialValue);
}, [initialValue]);
const toggle = (0, _react.useCallback)(async () => {
const previousValue = value;
const newValue = !value;
// Optimistic update
setValue(newValue);
setIsSaving(true);
try {
await onSave(newValue);
if (showSuccessToast && successMessage) {
_sonner.toast.success(successMessage);
}
} catch (err) {
// Revert on error
if (revertOnError) {
setValue(previousValue);
}
_sonner.toast.error(errorMessage || err?.message || 'An error occurred');
} finally {
setIsSaving(false);
}
}, [value, onSave, successMessage, errorMessage, revertOnError, showSuccessToast]);
return {
value,
isSaving,
toggle,
setValue
};
}
/**
* Hook for managing multiple toggle settings at once.
* Useful when you have several related boolean settings.
*/
function useSettingToggles(options) {
const {
initialValues,
onSave,
errorMessage = 'Failed to save setting',
revertOnError = true
} = options;
const [values, setValues] = (0, _react.useState)(initialValues);
const [savingKeys, setSavingKeys] = (0, _react.useState)(new Set());
// Update values when initialValues change
(0, _react.useEffect)(() => {
setValues(initialValues);
}, [initialValues]);
const toggle = (0, _react.useCallback)(async key => {
const previousValue = values[key];
const newValue = !previousValue;
// Optimistic update
setValues(prev => ({
...prev,
[key]: newValue
}));
setSavingKeys(prev => new Set(prev).add(key));
try {
await onSave(key, newValue);
} catch (err) {
// Revert on error
if (revertOnError) {
setValues(prev => ({
...prev,
[key]: previousValue
}));
}
const message = typeof errorMessage === 'function' ? errorMessage(key) : errorMessage;
_sonner.toast.error(message || err?.message || 'An error occurred');
} finally {
setSavingKeys(prev => {
const next = new Set(prev);
next.delete(key);
return next;
});
}
}, [values, onSave, errorMessage, revertOnError]);
const setValuesExternal = (0, _react.useCallback)(newValues => {
setValues(prev => ({
...prev,
...newValues
}));
}, []);
return {
values,
savingKeys,
toggle,
setValues: setValuesExternal
};
}
var _default = exports.default = useSettingToggle;
//# sourceMappingURL=useSettingToggle.js.map