Add cancellation
This commit is contained in:
parent
9810126b09
commit
31cb674565
48
src/modules/resellerOffice365/actions/cancelRequest.ts
Normal file
48
src/modules/resellerOffice365/actions/cancelRequest.ts
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
"use server";
|
||||
|
||||
import db from "@/core/db";
|
||||
import checkPermission from "@/modules/dashboard/services/checkPermission";
|
||||
import handleCatch from "@/modules/dashboard/utils/handleCatch";
|
||||
import notFound from "@/modules/dashboard/utils/notFound";
|
||||
import unauthorized from "@/modules/dashboard/utils/unauthorized";
|
||||
import ResellerOffice365Error from "../errors/ResellerOffice365Error";
|
||||
import getCurrentUser from "@/modules/auth/utils/getCurrentUser";
|
||||
import ServerResponseAction from "@/modules/dashboard/types/ServerResponseAction";
|
||||
import { revalidatePath } from "next/cache";
|
||||
import "server-only"
|
||||
|
||||
export default async function cancelRequest(id: string): Promise<ServerResponseAction> {
|
||||
try {
|
||||
//TODO: Fix permission
|
||||
if (!(await checkPermission("authenticated-only"))) return unauthorized();
|
||||
|
||||
const data = await db.office365LinkRequest.findFirst({
|
||||
where: { id },
|
||||
});
|
||||
|
||||
if (!data) return notFound({message: "The Provided ID does not match any"})
|
||||
|
||||
if (data.status !== "WAITING") throw new ResellerOffice365Error({
|
||||
errorCode: "REQUEST_IS_NOT_IN_WAITING_STATE",
|
||||
message: "This item is not in \"waiting\" state to perform cancellation. This might be due to the request has been accepted"
|
||||
});
|
||||
|
||||
if (data.createdBy !== (await getCurrentUser())?.id) return unauthorized();
|
||||
|
||||
await db.office365LinkRequest.update({
|
||||
where: {id},
|
||||
data: {
|
||||
status: "CANCELLED",
|
||||
cancelledAt: new Date()
|
||||
}
|
||||
})
|
||||
|
||||
revalidatePath(".")
|
||||
|
||||
return {
|
||||
success: true
|
||||
}
|
||||
} catch (e) {
|
||||
return handleCatch(e);
|
||||
}
|
||||
}
|
||||
|
|
@ -35,6 +35,8 @@ import DashboardError from "@/modules/dashboard/errors/DashboardError";
|
|||
import getLinkRequestDataById from "../actions/getLinkRequestDataById";
|
||||
import { isPagesAPIRouteMatch } from "next/dist/server/future/route-matches/pages-api-route-match";
|
||||
import inputLink from "../actions/inputLinks";
|
||||
import { Office365LinkRequestStatus } from "@prisma/client";
|
||||
import cancelRequest from "../actions/cancelRequest";
|
||||
|
||||
export interface ModalProps {
|
||||
title: string;
|
||||
|
|
@ -46,15 +48,27 @@ export interface ModalProps {
|
|||
|
||||
export default function RequestModal(props: ModalProps) {
|
||||
const [formState, setFormState] = useState<
|
||||
"idle" | "submitting" | "waiting" | "fetching" | "error"
|
||||
| "idle"
|
||||
| "submitting"
|
||||
| "waiting"
|
||||
| "fetching"
|
||||
| "error"
|
||||
| "confirming cancel"
|
||||
| "cancelling"
|
||||
>("idle");
|
||||
|
||||
const [errorMessage, setErrorMessage] = useState("");
|
||||
const [requestStatus, setRequestStatus] = useState<
|
||||
Office365LinkRequestStatus | "CREATING"
|
||||
>("CREATING");
|
||||
|
||||
const closeModal = () => {
|
||||
if (formState === "submitting") return; //prevents closing
|
||||
const closeModal = (force?: boolean) => {
|
||||
if (!force){
|
||||
if (["submitting, cancelling"].includes(formState)) return; //prevents closing
|
||||
}
|
||||
//reset state
|
||||
setErrorMessage("");
|
||||
setRequestStatus("CREATING");
|
||||
setFormState("idle");
|
||||
form.reset();
|
||||
props.onClose ? props.onClose() : "";
|
||||
|
|
@ -94,6 +108,15 @@ export default function RequestModal(props: ModalProps) {
|
|||
link: item.link ?? "",
|
||||
})),
|
||||
});
|
||||
setRequestStatus(data.status);
|
||||
if (
|
||||
data.status === "WAITING" &&
|
||||
props.type === "detail"
|
||||
) {
|
||||
setFormState("waiting");
|
||||
} else {
|
||||
setFormState("idle");
|
||||
}
|
||||
})
|
||||
.catch((e) => {
|
||||
if (e instanceof Error) {
|
||||
|
|
@ -101,8 +124,6 @@ export default function RequestModal(props: ModalProps) {
|
|||
} else {
|
||||
setErrorMessage("Unkown error occured");
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
setFormState("idle");
|
||||
});
|
||||
break;
|
||||
|
|
@ -227,12 +248,81 @@ export default function RequestModal(props: ModalProps) {
|
|||
}
|
||||
};
|
||||
|
||||
const handleCancel = () => {
|
||||
if (!props.detailId) return setErrorMessage("Cannot request cancellation. Cause: the ID is empty. Please contact your administrator")
|
||||
setFormState("cancelling")
|
||||
withServerAction(cancelRequest, props.detailId)
|
||||
.then(() => {
|
||||
notifications.show({
|
||||
message: "The request has been cancelled",
|
||||
color: "green"
|
||||
})
|
||||
setFormState("idle")
|
||||
closeModal(true)
|
||||
})
|
||||
.catch(e => {
|
||||
if (e instanceof Error){
|
||||
setErrorMessage(e.message)
|
||||
}
|
||||
setFormState("idle")
|
||||
})
|
||||
}
|
||||
|
||||
const renderActionButtons = () => (
|
||||
<Flex justify="flex-end" align="center" gap="lg" mt="lg">
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={() => closeModal()}
|
||||
disabled={["submitting"].includes(formState)}
|
||||
>
|
||||
Close
|
||||
</Button>
|
||||
{showCancelButton && (
|
||||
<Button variant="outline" color="red" type="button" onClick={() => setFormState("confirming cancel")}>
|
||||
Cancel Request
|
||||
</Button>
|
||||
)}
|
||||
{showSubmitButton && (
|
||||
<Button
|
||||
variant="filled"
|
||||
leftSection={<TbDeviceFloppy size={20} />}
|
||||
type="submit"
|
||||
disabled={["submitting", "waiting"].includes(formState)}
|
||||
loading={["submitting"].includes(formState)}
|
||||
>
|
||||
{props.type === "create" ? "Make Request" : "Save"}
|
||||
</Button>
|
||||
)}
|
||||
</Flex>
|
||||
);
|
||||
|
||||
const renderCancelConfirmation = () => (
|
||||
<Stack mt="lg" gap={0}>
|
||||
<Text>Are you sure to cancel this link request?</Text>
|
||||
<Flex justify="flex-end" align="center" gap="lg" mt="lg">
|
||||
<Button type="button" variant="outline" onClick={() => setFormState("waiting")}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button type="button" variant="transparent" color="red" onClick={handleCancel}>
|
||||
Yes, I am sure
|
||||
</Button>
|
||||
</Flex>
|
||||
</Stack>
|
||||
);
|
||||
|
||||
const disableChange = formState !== "idle";
|
||||
const readonly = ["input link", "detail"].includes(props.type);
|
||||
const showSkeleton = formState === "fetching";
|
||||
const showActivationLink = ["input link", "detail"].includes(props.type);
|
||||
const enableInputActivationLink = props.type === "input link";
|
||||
const showSubmitButton = ["create", "input link"].includes(props.type);
|
||||
const showCancelButton =
|
||||
["detail"].includes(props.type) && formState === "waiting";
|
||||
const showCancelRequestConfirmation = [
|
||||
"confirming cancel",
|
||||
"cancelling",
|
||||
].includes(formState);
|
||||
const showWaitingAlert = (["waiting", "confirming cancel"] as typeof formState[]).includes(formState)
|
||||
|
||||
return (
|
||||
<Modal
|
||||
|
|
@ -248,7 +338,7 @@ export default function RequestModal(props: ModalProps) {
|
|||
>
|
||||
<form onSubmit={form.onSubmit(handleSubmit)}>
|
||||
<Stack gap="md">
|
||||
{formState === "waiting" && (
|
||||
{showWaitingAlert && (
|
||||
<Alert color="orange">
|
||||
Your request is being processed by administrator
|
||||
</Alert>
|
||||
|
|
@ -349,30 +439,9 @@ export default function RequestModal(props: ModalProps) {
|
|||
</Stack>
|
||||
|
||||
{/* Buttons */}
|
||||
<Flex justify="flex-end" align="center" gap="lg" mt="lg">
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={closeModal}
|
||||
disabled={["submitting"].includes(formState)}
|
||||
>
|
||||
Close
|
||||
</Button>
|
||||
{showSubmitButton && (
|
||||
<Button
|
||||
variant="filled"
|
||||
leftSection={<TbDeviceFloppy size={20} />}
|
||||
type="submit"
|
||||
disabled={["submitting", "waiting"].includes(
|
||||
formState
|
||||
)}
|
||||
loading={["submitting"].includes(formState)}
|
||||
>
|
||||
{props.type === "create"
|
||||
? "Make Request"
|
||||
: "Save"}
|
||||
</Button>
|
||||
)}
|
||||
</Flex>
|
||||
{showCancelRequestConfirmation
|
||||
? renderCancelConfirmation()
|
||||
: renderActionButtons()}
|
||||
</Stack>
|
||||
</form>
|
||||
</Modal>
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user