diff --git a/src/components/Profile/ProfileView.tsx b/src/components/Profile/ProfileView.tsx index f42d058..c67f04b 100644 --- a/src/components/Profile/ProfileView.tsx +++ b/src/components/Profile/ProfileView.tsx @@ -1,11 +1,18 @@ +import { cn } from "@/lib/utils"; import { RoleList } from "./RoleList"; import { ExternalLinks } from "../Socials/ExternalLinks"; import { ImageUpdate } from "./ImageUpdate"; import { UserAvatar } from "./UserAvatar"; import { UpdateName } from "./UpdateName"; -import { getOfficerQuery, getOfficerByIdQuery } from "@/queries/officer"; -import { useQuery } from "@tanstack/react-query"; +import { + getOfficerQuery, + getOfficerByIdQuery, + updateOfficerStatusMutation, +} from "@/queries/officer"; +import { useMutation, useQuery } from "@tanstack/react-query"; import { Spinner } from "../Spinner"; +import { isExecutive } from "@/lib/admin"; +import { Button } from "../ui/button"; type Props = { officerId?: string; @@ -17,6 +24,11 @@ export function ProfileView({ officerId, editable = false }: Props) { officerId ? getOfficerByIdQuery(officerId) : getOfficerQuery ); + const { data: viewer } = useQuery(getOfficerQuery); + const isViewerExecutive = viewer ? isExecutive(viewer) : false; + + const { mutate: updateStatus } = useMutation(updateOfficerStatusMutation); + if (isLoading) { return ; } @@ -57,6 +69,42 @@ export function ProfileView({ officerId, editable = false }: Props) {
+ +
+
+
+ {officer.isActive ? "Active" : "Inactive"} +
+ {isViewerExecutive && officerId && ( + + )} +
diff --git a/src/functions/officer.ts b/src/functions/officer.ts index a69650c..a4ca2f4 100644 --- a/src/functions/officer.ts +++ b/src/functions/officer.ts @@ -1,6 +1,7 @@ import { auth } from "@/lib/firebase"; import { OfficerSchema, type Officer } from "@/schemas/officer"; import { fetchWithAuth } from "./fetch"; +import { isExecutive } from "@/lib/admin"; export async function getCurrentOfficer(): Promise { const idToken = await auth.currentUser?.getIdToken(); @@ -98,6 +99,28 @@ export async function updateAcademicInfo( return OfficerSchema.parse(res); } +export async function updateOfficerStatus({ + officerId, + isActive, +}: { + officerId: string; + isActive: boolean; +}): Promise { + const currentUser = await getCurrentOfficer(); + if (!currentUser) throw new Error("Current user not found"); + if (!isExecutive(currentUser)) throw new Error("Unauthorized"); + + const officer = await fetchWithAuth(`/updateOfficer?id=${officerId}`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ isActive }), + }); + const res = await officer.json(); + return OfficerSchema.parse(res); +} + export async function getAllOfficers(): Promise { const officers = await fetchWithAuth(`/getOfficers`, { method: "GET", diff --git a/src/lib/admin.ts b/src/lib/admin.ts index efba617..6e69da4 100644 --- a/src/lib/admin.ts +++ b/src/lib/admin.ts @@ -9,3 +9,11 @@ export function isAdmin(account: GetAdminLevel) { return account.level > 1; } } + +export function isExecutive(account: GetAdminLevel) { + if ("accessLevel" in account) { + return account.accessLevel > 2; + } else { + return account.level > 2; + } +} diff --git a/src/lib/table.tsx b/src/lib/table.tsx index 7fd2c41..20e668a 100644 --- a/src/lib/table.tsx +++ b/src/lib/table.tsx @@ -13,6 +13,7 @@ import { } from "@tanstack/match-sorter-utils"; import { RoleList } from "@/components/Profile/RoleList"; import { Link } from "@tanstack/react-router"; +import { cn } from "@/lib/utils"; export const divisions = [ "All", @@ -172,9 +173,24 @@ export const columns = [ header: () => Active, cell: ({ row }) => (
- - {row.original.isActive ? "🟢" : "🔴"} - +
+
+ {row.original.isActive ? "Active" : "Inactive"} +
), }), diff --git a/src/queries/officer.ts b/src/queries/officer.ts index 33a47c9..cfb30f5 100644 --- a/src/queries/officer.ts +++ b/src/queries/officer.ts @@ -5,6 +5,7 @@ import { updateAcademicInfo, updateOfficerImage, updateOfficerName, + updateOfficerStatus, } from "@/functions/officer"; import { mutationOptions, queryOptions } from "@tanstack/react-query"; @@ -46,3 +47,14 @@ export const updateAcademicInfoMutationOptions = mutationOptions({ context.client.invalidateQueries(getAllOfficersQuery); }, }); + +export const updateOfficerStatusMutation = mutationOptions({ + mutationFn: updateOfficerStatus, + onSuccess: (res, variables, __, context) => { + context.client.setQueryData( + getOfficerByIdQuery(variables.officerId).queryKey, + res + ); + context.client.refetchQueries(getAllOfficersQuery); + }, +});