diff --git a/src/api/skills/skills.api.ts b/src/api/skills/skills.api.ts index 53b2ec5..fe84f5b 100644 --- a/src/api/skills/skills.api.ts +++ b/src/api/skills/skills.api.ts @@ -2,8 +2,10 @@ import { client } from "@/utils/client" import * as Dto from "./skills.dto" export class SkillsApi { - public static async getAllPendingSkillRequests(): Promise { - const { data } = await client.get("/v1/skills/requests") + public static async getAllPendingSkillRequests( + params?: Dto.GetAllPendingSkillsReqDto + ): Promise { + const { data } = await client.get("/v1/skills/requests", { params }) return data } diff --git a/src/api/skills/skills.dto.ts b/src/api/skills/skills.dto.ts index 89a101c..e435028 100644 --- a/src/api/skills/skills.dto.ts +++ b/src/api/skills/skills.dto.ts @@ -8,10 +8,15 @@ export type SkillRequests = { skillId: number skillName: string endorseId: string + status: UserSkillStatusEnum endorsements: TEndorsement[] } -export type GetAllPendingSkillRequestsResDto = { +export type GetAllPendingSkillsReqDto = { + status?: UserSkillStatusEnum +} + +export type GetAllPendingSkillsResDto = { requests: SkillRequests[] users: MinimalUser[] } diff --git a/src/api/skills/skills.enum.ts b/src/api/skills/skills.enum.ts index 5a113b2..0c39841 100644 --- a/src/api/skills/skills.enum.ts +++ b/src/api/skills/skills.enum.ts @@ -3,7 +3,7 @@ export enum SkillTypeEnum { } export enum UserSkillStatusEnum { - APPROVED, - REJECTED, - PENDING, + APPROVED = "APPROVED", + REJECTED = "REJECTED", + PENDING = "PENDING", } diff --git a/src/components/small-screen-warning.tsx b/src/components/small-screen-warning.tsx index 7341c7c..d9052c2 100644 --- a/src/components/small-screen-warning.tsx +++ b/src/components/small-screen-warning.tsx @@ -5,7 +5,7 @@ // --- export const SmallScreenWarning = () => { return ( -
+

Small Screen detected

This application is not supported on devices below 1280px

diff --git a/src/components/tabs.tsx b/src/components/tabs.tsx new file mode 100644 index 0000000..226a5a7 --- /dev/null +++ b/src/components/tabs.tsx @@ -0,0 +1,36 @@ +import Link from "next/link" +import { usePathname } from "next/navigation" + +import { cn } from "@/utils/classname" + +export type TTab = { + order: number + label: string + href: string +} + +type TabsProps = { + tabs: TTab[] +} + +export const Tabs = ({ tabs }: TabsProps) => { + const pathname = usePathname() + const sortedTabs = tabs.sort((a, b) => a.order - b.order) + + return ( +
+ {sortedTabs.map((tab) => ( + + {tab.label} + + ))} +
+ ) +} diff --git a/src/modules/pending-requests/index.ts b/src/modules/pending-requests/index.ts new file mode 100644 index 0000000..b4871e7 --- /dev/null +++ b/src/modules/pending-requests/index.ts @@ -0,0 +1 @@ +export { PendingRequests } from "./pending-requests" diff --git a/src/modules/pending-requests/pending-requests.tsx b/src/modules/pending-requests/pending-requests.tsx new file mode 100644 index 0000000..24d3fcd --- /dev/null +++ b/src/modules/pending-requests/pending-requests.tsx @@ -0,0 +1,72 @@ +import { useQuery } from "@tanstack/react-query" +import Link from "next/link" + +import { SkillsApi } from "@/api/skills" +import { UserSkillStatusEnum } from "@/api/skills/skills.enum" +import { Button } from "@/components/button" +import { PageError } from "@/components/page-error" +import { Shimmer } from "@/components/shimmer" +import { RootLayout } from "@/layouts/root-layout" +import { ROUTES } from "@/routes" +import { useGlobalStore } from "@/store/global-store" + +import { RequestsTable } from "../requests/components/requests-table" +import { RequestsTabs } from "../requests/components/requests-tabs" + +export const PendingRequests = () => { + const isSuperUser = useGlobalStore((store) => store.user?.roles.super_user) + + const { data, isLoading, isError } = useQuery({ + queryKey: ["SkillsApi.getAllPendingSkillRequests"], + queryFn: () => SkillsApi.getAllPendingSkillRequests({ status: UserSkillStatusEnum.PENDING }), + }) + + if (isLoading) { + return ( + +
+ + + + +
+
+ ) + } + + if (isError) { + return ( + + + + ) + } + + return ( + +
+
+
+ +
+ +
+

Pending requests

+ + {isSuperUser && ( + + )} + + +
+ + +
+
+
+ ) +} diff --git a/src/modules/requests/components/requests-table.tsx b/src/modules/requests/components/requests-table.tsx index b9643fd..8db6e37 100644 --- a/src/modules/requests/components/requests-table.tsx +++ b/src/modules/requests/components/requests-table.tsx @@ -5,7 +5,7 @@ import toast from "react-hot-toast" import { MinimalUser } from "@/api/common/minimal-user.types" import { TUserDetails } from "@/api/common/user.types" import { SkillsApi } from "@/api/skills" -import { GetAllPendingSkillRequestsResDto } from "@/api/skills/skills.dto" +import { GetAllPendingSkillsResDto } from "@/api/skills/skills.dto" import { UserSkillStatusEnum } from "@/api/skills/skills.enum" import { Button } from "@/components/button" import { useGlobalStore } from "@/store/global-store" @@ -21,7 +21,7 @@ type CellProps = { } const Cell = ({ className, children }: CellProps) => { - return
{children}
+ return
{children}
} type CommonProps = { @@ -36,19 +36,24 @@ const Th = ({ children }: CommonProps) => { ) } -const Td = ({ children }: CommonProps) => { +type TdProps = CommonProps & { + classNames?: Partial<{ td: string; cell: string }> +} + +const Td = ({ children, classNames }: TdProps) => { return ( - - {children} + + {children} ) } const TableHeader = () => { return ( - + Name Skill + Skill status Endorsements @@ -58,9 +63,10 @@ const TableHeader = () => { type RequestActionsProps = { skillId: number endorseId: string + skillStatus: UserSkillStatusEnum } -const RequestActions = ({ skillId, endorseId }: RequestActionsProps) => { +const RequestActions = ({ skillId, endorseId, skillStatus }: RequestActionsProps) => { const queryClient = useQueryClient() const approveRequestsMutation = useMutation({ @@ -87,6 +93,10 @@ const RequestActions = ({ skillId, endorseId }: RequestActionsProps) => { }, }) + if (skillStatus !== UserSkillStatusEnum.PENDING) { + return
--
+ } + return (