Hi everyone, I am a rookie developer learning Nextjs from Mosh.
It is such a great course that not only allows me to follow and practice but also encourages me to challenge myself continuously.
So I challenged myself to implement the Issue Status switching by creating a reusable issueStatusBadge component using the “Badge” component from Radix UI along with implementing the tooltip when hovered.
It changes the Issue’s status both on the frontend and backend at an amazing speed whenever the user clicks on the status badge.
I would appreciate it if anyone could correct my code or improve it in any form of way!!!
"use client";
import { Spinner } from "@/app/components";
import { Issue, Status } from "@prisma/client";
import { Badge, Tooltip } from "@radix-ui/themes";
import axios from "axios";
import { useState } from "react";
const statusMap: Record<
Status,
{
label: string;
nextLabel: string;
color: "red" | "violet" | "cyan" | "orange" | "green";
variant: "soft" | "solid";
}
> = {
OPEN: {
label: "Open",
nextLabel: "In Progress",
color: "red",
variant: "soft",
},
CLOSED: {
label: "Closed",
nextLabel: "Open",
color: "green",
variant: "soft",
},
IN_PROGRESS: {
label: "In Progress",
nextLabel: "Closed",
color: "violet",
variant: "soft",
},
};
type Props = {
title?: Issue["title"];
description?: Issue["description"];
issueId?: Issue["id"];
status: Issue["status"];
};
const IssueStatusBadge = ({ status, issueId, title, description }: Props) => {
const [currentStatus, setCurrentStatus] = useState(status);
const [isSettingStatus, setIsSettingStatus] = useState(false);
const handleClick = async () => {
let newStatus: Status;
switch (currentStatus) {
case "OPEN":
newStatus = "IN_PROGRESS";
break;
case "IN_PROGRESS":
newStatus = "CLOSED";
break;
case "CLOSED":
newStatus = "OPEN";
break;
default:
newStatus = currentStatus;
break;
}
try {
setIsSettingStatus(true);
await axios.patch("/api/issues/" + issueId, {
title: title,
description: description,
status: newStatus,
});
setCurrentStatus(newStatus);
} catch (error) {
setIsSettingStatus(false);
console.error(error);
}
setIsSettingStatus(false);
};
return (
<>
<Tooltip
className="!opacity-50"
delayDuration={0}
content={`Switch Status to: ${statusMap[currentStatus].nextLabel}`}
disableHoverableContent={true}
>
<Badge
className="transition-all duration-300 hover:cursor-pointer hover:shadow"
variant={statusMap[currentStatus].variant}
onClick={handleClick}
radius="large"
color={statusMap[currentStatus].color}
>
{statusMap[currentStatus].label}{" "}
{isSettingStatus ? <Spinner /> : null}
</Badge>
</Tooltip>
</>
);
};
export default IssueStatusBadge;