@replyke/core
Version:
Replyke: Build interactive apps with social features like comments, votes, feeds, user lists, notifications, and more.
105 lines • 4.59 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.useUserActions = useUserActions;
const react_1 = require("react");
const hooks_1 = require("../../store/hooks");
const userSlice_1 = require("../../store/slices/userSlice");
const userApi_1 = require("../../store/api/userApi");
/**
* Redux-powered hook that provides current user management actions
* Focused on current user operations only
*/
function useUserActions() {
const dispatch = (0, hooks_1.useReplykeDispatch)();
// RTK Query mutations for current user
const [updateUserMutation] = (0, userApi_1.useUpdateUserMutation)();
// User data management actions
const handleSetUser = (0, react_1.useCallback)((user) => {
// IMPORTANT: Validate that user has required data before setting
// This prevents empty or partial user objects from being set to state
if (user && !user.id) {
console.warn('Attempted to set user without id - ignoring invalid user data');
return;
}
dispatch((0, userSlice_1.setUser)(user));
dispatch((0, userSlice_1.clearError)());
}, [dispatch]);
const handleClearUser = (0, react_1.useCallback)(() => {
dispatch((0, userSlice_1.clearUser)());
dispatch((0, userSlice_1.clearError)());
}, [dispatch]);
// Update user with optimistic updates for instant UI feedback
const updateUser = (0, react_1.useCallback)(async ({ projectId, userId, update, currentUser }) => {
if (!projectId || !userId) {
throw new Error("Project ID and User ID are required");
}
dispatch((0, userSlice_1.setUpdating)(true));
dispatch((0, userSlice_1.clearError)());
// Store original user state for potential reversion
const originalUser = currentUser;
// Build optimistic update excluding fields that require server transformation:
// - File uploads (avatar/banner as File) - we don't know the final URL
// - Location - server transforms { latitude, longitude } to GeoJSON format
const optimisticUpdate = {};
if (update.name !== undefined)
optimisticUpdate.name = update.name;
if (update.username !== undefined)
optimisticUpdate.username = update.username;
if (update.bio !== undefined)
optimisticUpdate.bio = update.bio;
if (update.birthdate !== undefined)
optimisticUpdate.birthdate = update.birthdate;
if (update.metadata !== undefined)
optimisticUpdate.metadata = update.metadata;
// Only apply avatar optimistically if it's a string URL (not a file upload)
if (typeof update.avatar === 'string' || update.avatar === null) {
optimisticUpdate.avatar = update.avatar;
}
// OPTIMISTIC UPDATE: Apply changes immediately for instant UI feedback
if (Object.keys(optimisticUpdate).length > 0) {
dispatch((0, userSlice_1.updateUserOptimistic)(optimisticUpdate));
}
try {
const result = await updateUserMutation({
projectId,
userId,
update
}).unwrap();
// Replace optimistic update with real server data
dispatch((0, userSlice_1.setUser)(result));
return result;
}
catch (error) {
// REVERT OPTIMISTIC UPDATE: Restore original user state on API failure
if (originalUser) {
dispatch((0, userSlice_1.setUser)(originalUser));
}
const errorMessage = error instanceof Error ? error.message : 'Failed to update user';
dispatch((0, userSlice_1.setError)(errorMessage));
throw error;
}
finally {
dispatch((0, userSlice_1.setUpdating)(false));
}
}, [updateUserMutation, dispatch]);
// Removed other-user methods - use existing legacy hooks instead:
// - useFetchUser
// - useFetchUserByForeignId
// - useCheckUsernameAvailability
// - useFetchUserSuggestions
// Error handling actions
const clearUserError = (0, react_1.useCallback)(() => {
dispatch((0, userSlice_1.clearError)());
}, [dispatch]);
return {
// Current user data management
setUser: handleSetUser,
clearUser: handleClearUser,
// Current user operations
updateUser,
// Error handling
clearError: clearUserError,
};
}
exports.default = useUserActions;
//# sourceMappingURL=useUserActions.js.map