From ac7eb8627acb2d763d299f33adc5ad26d7fc1579 Mon Sep 17 00:00:00 2001 From: David Gu Date: Mon, 17 Nov 2025 00:59:14 -0500 Subject: [PATCH 1/3] Available user types filtered based on user role --- src/components/forms/EditUserForm.tsx | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/components/forms/EditUserForm.tsx b/src/components/forms/EditUserForm.tsx index a9708b9..37c4594 100644 --- a/src/components/forms/EditUserForm.tsx +++ b/src/components/forms/EditUserForm.tsx @@ -25,10 +25,11 @@ import { } from "../ui/select"; import { toast } from "sonner"; import { InputMultiSelect, InputMultiSelectTrigger } from "../ui/multiselect"; -import { useState } from "react"; +import { useState, useMemo } from "react"; import { UserColumn } from "@/components/usertable/columns"; import { SetUserTypeModel } from "juno-sdk/build/main/internal/api"; import { ProjectColumn } from "@/app/(dashboard)/admin/projects/columns"; +import { useUserSession, UserType } from "../providers/SessionProvider"; export const userTypeMap = { SUPERADMIN: 0, @@ -55,6 +56,23 @@ const EditUserForm = ({ initialUserData: UserColumn; onUserUpdate?: (updatedUser: UserColumn) => void; }) => { + const { user: currentUser } = useUserSession(); + + // Filter available user types based on current user's permissions + // SUPERADMIN can set any type + // ADMIN can only set USER type + // USER shouldn't be able to edit (but we'll still filter just in case) + const availableUserTypes = useMemo(() => { + if (!currentUser) return ["USER"]; + + if (currentUser.type === UserType.SUPERADMIN) { + return Object.keys(userTypeMap); + } else if (currentUser.type === UserType.ADMIN) { + return ["USER"]; + } else { + return ["USER"]; + } + }, [currentUser]); const setUserTypeForm = useForm>({ resolver: zodResolver(setUserTypeSchema), defaultValues: { @@ -194,7 +212,7 @@ const EditUserForm = ({ - {Object.keys(userTypeMap).map((type) => ( + {availableUserTypes.map((type) => ( {type} From c22bc62c529457b7af7ba97858def224604fdcaa Mon Sep 17 00:00:00 2001 From: David Gu Date: Mon, 17 Nov 2025 01:00:40 -0500 Subject: [PATCH 2/3] Forgot to do linting --- src/components/forms/EditUserForm.tsx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/components/forms/EditUserForm.tsx b/src/components/forms/EditUserForm.tsx index 37c4594..f2afb13 100644 --- a/src/components/forms/EditUserForm.tsx +++ b/src/components/forms/EditUserForm.tsx @@ -38,7 +38,7 @@ export const userTypeMap = { } as const; const userTypeEnum = z.enum( - Object.keys(userTypeMap) as [keyof typeof userTypeMap], + Object.keys(userTypeMap) as [keyof typeof userTypeMap] ); const setUserTypeSchema = z.object({ @@ -64,7 +64,7 @@ const EditUserForm = ({ // USER shouldn't be able to edit (but we'll still filter just in case) const availableUserTypes = useMemo(() => { if (!currentUser) return ["USER"]; - + if (currentUser.type === UserType.SUPERADMIN) { return Object.keys(userTypeMap); } else if (currentUser.type === UserType.ADMIN) { @@ -86,7 +86,7 @@ const EditUserForm = ({ }); const handleSetUserType = async ( - data: Required>, + data: Required> ) => { try { // Update user type @@ -108,18 +108,18 @@ const EditUserForm = ({ // Find projects to unlink (in initial but not in selected) const projectsToUnlink = initialProjectIds.filter( - (id) => !selectedProjects.includes(id), + (id) => !selectedProjects.includes(id) ); // Find projects to link (in selected but not in initial) const projectsToLink = selectedProjects.filter( - (id) => !initialProjectIds.includes(id), + (id) => !initialProjectIds.includes(id) ); // Unlink projects that were removed const unlinkPromises = projectsToUnlink.map((projectId) => { const projectName = projectData.find( - (p) => parseInt(p.id) === parseInt(projectId), + (p) => parseInt(p.id) === parseInt(projectId) )?.name; return unlinkUserFromProject({ projectName, @@ -130,7 +130,7 @@ const EditUserForm = ({ // Link projects that were added const linkPromises = projectsToLink.map((projectId) => { const projectName = projectData.find( - (p) => parseInt(p.id) === parseInt(projectId), + (p) => parseInt(p.id) === parseInt(projectId) )?.name; return linkUserToProject({ projectName, @@ -173,7 +173,7 @@ const EditUserForm = ({ const [selectedProjects, setSelectedProjects] = useState( initialUserData.projects ? initialUserData.projects.map((id) => id.toString()) - : [], + : [] ); const projectOptions = projectData.map((project) => ({ From 90fbb7b95e5f7dbc0ce8ab767461789ed372b331 Mon Sep 17 00:00:00 2001 From: Long Lam Date: Thu, 19 Feb 2026 23:53:09 -0500 Subject: [PATCH 3/3] fix: format --- src/components/forms/EditUserForm.tsx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/components/forms/EditUserForm.tsx b/src/components/forms/EditUserForm.tsx index f2afb13..2bfe5ea 100644 --- a/src/components/forms/EditUserForm.tsx +++ b/src/components/forms/EditUserForm.tsx @@ -38,7 +38,7 @@ export const userTypeMap = { } as const; const userTypeEnum = z.enum( - Object.keys(userTypeMap) as [keyof typeof userTypeMap] + Object.keys(userTypeMap) as [keyof typeof userTypeMap], ); const setUserTypeSchema = z.object({ @@ -86,7 +86,7 @@ const EditUserForm = ({ }); const handleSetUserType = async ( - data: Required> + data: Required>, ) => { try { // Update user type @@ -108,18 +108,18 @@ const EditUserForm = ({ // Find projects to unlink (in initial but not in selected) const projectsToUnlink = initialProjectIds.filter( - (id) => !selectedProjects.includes(id) + (id) => !selectedProjects.includes(id), ); // Find projects to link (in selected but not in initial) const projectsToLink = selectedProjects.filter( - (id) => !initialProjectIds.includes(id) + (id) => !initialProjectIds.includes(id), ); // Unlink projects that were removed const unlinkPromises = projectsToUnlink.map((projectId) => { const projectName = projectData.find( - (p) => parseInt(p.id) === parseInt(projectId) + (p) => parseInt(p.id) === parseInt(projectId), )?.name; return unlinkUserFromProject({ projectName, @@ -130,7 +130,7 @@ const EditUserForm = ({ // Link projects that were added const linkPromises = projectsToLink.map((projectId) => { const projectName = projectData.find( - (p) => parseInt(p.id) === parseInt(projectId) + (p) => parseInt(p.id) === parseInt(projectId), )?.name; return linkUserToProject({ projectName, @@ -173,7 +173,7 @@ const EditUserForm = ({ const [selectedProjects, setSelectedProjects] = useState( initialUserData.projects ? initialUserData.projects.map((id) => id.toString()) - : [] + : [], ); const projectOptions = projectData.map((project) => ({