Added update lnk

This commit is contained in:
sianida26 2024-02-18 05:01:45 +07:00
parent 0a848d9458
commit 27fdced0c9
4 changed files with 163 additions and 11 deletions

View File

@ -0,0 +1,81 @@
"use server";
import db from "@/core/db";
import checkPermission from "@/modules/dashboard/services/checkPermission";
import ServerResponseAction from "@/modules/dashboard/types/ServerResponseAction";
import handleCatch from "@/modules/dashboard/utils/handleCatch";
import notFound from "@/modules/dashboard/utils/notFound";
import unauthorized from "@/modules/dashboard/utils/unauthorized";
import "server-only";
import ResellerOffice365Error from "../errors/ResellerOffice365Error";
import { revalidatePath } from "next/cache";
interface Args {
id: string;
data: {
linkId: string;
link: string;
}[];
}
export default async function inputLink(
args: Args
): Promise<ServerResponseAction> {
try {
//TODO: Implement permission
if (!(await checkPermission("authenticated-only")))
return unauthorized();
const data = await db.office365LinkRequest.findFirst({
where: {
id: args.id,
},
include: {
links: true,
},
});
if (!data)
return notFound({
message:
"The requested link is not found. It might seems has been deleted. Please contact administrator",
});
if (data.status !== "WAITING")
throw new ResellerOffice365Error({
errorCode: "REQUEST_IS_NOT_IN_WAITING_STATE",
message: `This request has been ${
data.acceptedAt
? "completed"
: data.rejectedAt
? "rejected"
: "cancelled"
} thus cannot be updated. Please contact administrator`,
});
await db.office365LinkRequest.update({
where: {
id: args.id,
},
data: {
acceptedAt: new Date(),
status: "ACCEPTED",
links: {
updateMany: args.data.map((linkItem) => ({
where: { id: linkItem.linkId },
data: {
link: linkItem.link,
},
})),
},
},
});
revalidatePath(".")
return {
success: true,
};
} catch (e) {
return handleCatch(e);
}
}

View File

@ -0,0 +1,25 @@
import DashboardError from "@/modules/dashboard/errors/DashboardError";
export const ResellerOffice365ErrorCodes = [
"REQUEST_IS_NOT_IN_WAITING_STATE"
] as const;
interface ResellerOffice365ErrorOptions {
message?: string;
errorCode: (typeof ResellerOffice365ErrorCodes)[number] | (string & {});
formErrors?: Record<string, string>
}
export default class ResellerOffice365Error extends DashboardError {
public readonly errorCode: ResellerOffice365ErrorOptions['errorCode'];
public readonly formErrors?: ResellerOffice365ErrorOptions['formErrors']
constructor(options: ResellerOffice365ErrorOptions) {
super({
errorCode: options.errorCode,
message: options.message,
});
this.errorCode = options.errorCode;
}
}

View File

@ -34,6 +34,7 @@ import { notifications } from "@mantine/notifications";
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";
export interface ModalProps {
title: string;
@ -89,6 +90,8 @@ export default function RequestModal(props: ModalProps) {
activePeriod: item.activePeriod,
email: item.email,
endUserQty: item.numberOfUsers,
id: item.id,
link: item.link ?? "",
})),
});
})
@ -116,6 +119,7 @@ export default function RequestModal(props: ModalProps) {
email: "",
activePeriod: "2 Years",
endUserQty: 1,
link: "",
},
],
},
@ -132,6 +136,7 @@ export default function RequestModal(props: ModalProps) {
email: "",
activePeriod: "2 Years",
endUserQty: 1,
link: "",
});
}
@ -154,10 +159,9 @@ export default function RequestModal(props: ModalProps) {
if (!submitableState.includes(formState)) return; //prevent submit when not in subitable state
setFormState("submitting");
switch (props.type) {
case "create": {
setFormState("submitting");
withServerAction(createLinkRequest, values)
.then((response) => {
notifications.show({
@ -192,16 +196,43 @@ export default function RequestModal(props: ModalProps) {
break;
}
case "input link": {
//TODO: Handle add link
if (!props.detailId) return;
setFormState("submitting");
withServerAction(inputLink, {
id: props.detailId,
data: form.values.details.map((item) => ({
link: item.link,
linkId: item.id ?? "",
})),
})
.then(() => {
setFormState("idle");
notifications.show({
message: "Data has been updated",
color: "green",
});
closeModal();
})
.catch((e) => {
if (e instanceof Error) {
setErrorMessage(e.message);
} else {
setErrorMessage("An unkown error occured");
}
})
.finally(() => {
setFormState("idle");
});
}
}
};
const disableChange = formState !== "idle";
const readonly = ["input link", "detail"].includes(props.type)
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 showActivationLink = ["input link", "detail"].includes(props.type);
const enableInputActivationLink = props.type === "input link";
const showSubmitButton = ["create", "input link"].includes(props.type);
return (
<Modal
@ -294,10 +325,21 @@ export default function RequestModal(props: ModalProps) {
<Skeleton visible={showSkeleton}>
<TextInput
label="Activation Link"
required
required={
enableInputActivationLink
}
disabled={disableChange}
readOnly={!enableInputActivationLink}
placeholder={enableInputActivationLink ? "Enter link here" : "No link provided"}
readOnly={
!enableInputActivationLink
}
{...form.getInputProps(
`details.${i}.link`
)}
placeholder={
enableInputActivationLink
? "Enter link here"
: "No link provided"
}
/>
</Skeleton>
)}
@ -315,7 +357,7 @@ export default function RequestModal(props: ModalProps) {
>
Close
</Button>
{formState === "waiting" && (
{showSubmitButton && (
<Button
variant="filled"
leftSection={<TbDeviceFloppy size={20} />}
@ -325,7 +367,9 @@ export default function RequestModal(props: ModalProps) {
)}
loading={["submitting"].includes(formState)}
>
Make Request
{props.type === "create"
? "Make Request"
: "Save"}
</Button>
)}
</Flex>

View File

@ -2,8 +2,10 @@ interface RequestLinkForm {
id: string | undefined;
numberOfLinks: number;
details: {
id?: string;
email: string;
activePeriod: (typeof resellerOffice365Config.activePeriods)[number];
endUserQty: number;
link: string
}[];
}