diff --git a/src/utils/Fetcher.jsx b/src/utils/Fetcher.jsx index f188f47..8d6ba5c 100644 --- a/src/utils/Fetcher.jsx +++ b/src/utils/Fetcher.jsx @@ -668,7 +668,13 @@ const RestoreBackup = (encryptionKey, backupData) => { }) } -const RegisterDeviceToken = (token, deviceId, platform, appVersion, deviceModel) => { +const RegisterDeviceToken = ( + token, + deviceId, + platform, + appVersion, + deviceModel, +) => { return Fetch(`/devices/tokens`, { method: 'POST', headers: HEADERS(), @@ -700,6 +706,44 @@ const GetDeviceTokens = (active = true) => { }) } +// Child User Management Functions +const CreateChildUser = (childName, displayName, password) => { + return Fetch(`/users/subaccounts`, { + method: 'POST', + headers: HEADERS(), + body: JSON.stringify({ + childName, + displayName, + password, + }), + }) +} + +const GetChildUsers = () => { + return Fetch(`/users/subaccounts`, { + method: 'GET', + headers: HEADERS(), + }) +} + +const UpdateChildPassword = (childUserId, password) => { + return Fetch(`/users/subaccounts/password`, { + method: 'PUT', + headers: HEADERS(), + body: JSON.stringify({ + childUserId, + password, + }), + }) +} + +const DeleteChildUser = childUserId => { + return Fetch(`/users/subaccounts/${childUserId}`, { + method: 'DELETE', + headers: HEADERS(), + }) +} + export { AcceptCircleMemberRequest, ApproveChore, @@ -711,10 +755,12 @@ export { CompleteSubTask, ConfirmMFA, CreateBackup, + CreateChildUser, CreateChore, CreateLabel, CreateLongLiveToken, CreateThing, + DeleteChildUser, DeleteChore, DeleteChoreHistory, DeleteCircleMember, @@ -727,6 +773,7 @@ export { GetAllCircleMembers, GetAllUsers, GetArchivedChores, + GetChildUsers, GetChoreByID, GetChoreDetailById, GetChoreHistory, @@ -768,6 +815,7 @@ export { StartChore, UnArchiveChore, UnregisterDeviceToken, + UpdateChildPassword, UpdateChoreAssignee, UpdateChoreHistory, UpdateChorePriority, diff --git a/src/utils/UserHelpers.js b/src/utils/UserHelpers.js new file mode 100644 index 0000000..188b936 --- /dev/null +++ b/src/utils/UserHelpers.js @@ -0,0 +1,66 @@ +// User type detection and permission utilities + +export const USER_TYPES = { + PARENT: 0, + CHILD: 1, +} + +export const isParentUser = (user) => { + if (!user) return false + return user.userType === USER_TYPES.PARENT && !user.parentUserId +} + +export const isChildUser = (user) => { + if (!user) return false + return user.userType === USER_TYPES.CHILD && user.parentUserId !== null +} + +export const canManageChildUsers = (user) => { + return isParentUser(user) +} + +export const canCreateChores = (user) => { + // Both parent and child users can create chores + return user && (isParentUser(user) || isChildUser(user)) +} + +export const canManageCircle = (user) => { + // Only parent users can manage circle settings + return isParentUser(user) +} + +export const canAccessAdminSettings = (user) => { + // Only parent users can access admin settings like API tokens, MFA, etc. + return isParentUser(user) +} + +export const getUserDisplayInfo = (user) => { + if (!user) return { displayName: '', username: '', userType: 'unknown' } + + return { + displayName: user.displayName || user.username, + username: user.username, + userType: isParentUser(user) ? 'parent' : isChildUser(user) ? 'child' : 'unknown', + parentUserId: user.parentUserId, + circleID: user.circleID, + } +} + +export const getChildUsernameFromCombined = (combinedUsername) => { + // Extract child name from format: parent_child + const parts = combinedUsername.split('_') + if (parts.length >= 2) { + return parts.slice(1).join('_') // In case child name contains underscores + } + return combinedUsername +} + +export const getParentUsernameFromCombined = (combinedUsername) => { + // Extract parent name from format: parent_child + const parts = combinedUsername.split('_') + return parts[0] || combinedUsername +} + +export const buildChildUsername = (parentUsername, childName) => { + return `${parentUsername}_${childName}` +} \ No newline at end of file