Added modal for input link
This commit is contained in:
parent
f16e356555
commit
bf7f8ebbf7
|
|
@ -3,7 +3,7 @@ import React from 'react'
|
|||
export default async function Dashboard() {
|
||||
return (
|
||||
<div>
|
||||
<h1>Dashboard</h1>
|
||||
<h1 className='font-bold bg-red-500'>Dashboard</h1>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
39
src/app/dashboard/reseller-office-365/list/page.tsx
Normal file
39
src/app/dashboard/reseller-office-365/list/page.tsx
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
import getUserRoles from "@/modules/auth/utils/getUserRoles";
|
||||
import checkMultiplePermissions from "@/modules/dashboard/services/checkMultiplePermissions";
|
||||
import checkPermission from "@/modules/dashboard/services/checkPermission";
|
||||
import getAllLinkRequests from "@/modules/resellerOffice365/actions/getAllLinkRequests";
|
||||
import getLinkRequests from "@/modules/resellerOffice365/actions/getLinkRequests";
|
||||
import ListOfRequestTable from "@/modules/resellerOffice365/tables/ListOfRequestTable/ListOfRequestTable";
|
||||
import RequestTable from "@/modules/resellerOffice365/tables/RequestTable/RequestTable";
|
||||
import { Card, Stack, Title } from "@mantine/core";
|
||||
import { notFound } from "next/navigation";
|
||||
import React from "react";
|
||||
|
||||
export default async function RequestLinkPage() {
|
||||
const permissions = await checkMultiplePermissions({
|
||||
create: "office-365-link.create",
|
||||
readAll: "office-365-link.readAll",
|
||||
read: "office-365-link.read",
|
||||
update: "office-365-link.update",
|
||||
delete: "office-365-link.delete",
|
||||
});
|
||||
|
||||
if (!permissions.readAll) notFound();
|
||||
|
||||
const data = await getAllLinkRequests();
|
||||
if (!data.success) {
|
||||
//todo: handle error
|
||||
console.error(data.error);
|
||||
throw new Error("Error while fetch data");
|
||||
}
|
||||
const tableData = data.data;
|
||||
|
||||
return (
|
||||
<Stack>
|
||||
<Title order={1}>List Link Office 365</Title>
|
||||
<Card>
|
||||
<ListOfRequestTable permissions={permissions} tableData={tableData} />
|
||||
</Card>
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
|
|
@ -22,7 +22,7 @@ export default async function RequestLinkPage() {
|
|||
if (!data.success){
|
||||
//todo: handle error
|
||||
console.error(data.error)
|
||||
throw new Error("Error while fetch permission")
|
||||
throw new Error("Error while fetch data")
|
||||
}
|
||||
const tableData = data.data
|
||||
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ declare global {
|
|||
var prisma: undefined | ReturnType<typeof prismaClientSingleton>;
|
||||
}
|
||||
|
||||
const prisma = globalThis.prisma ?? prismaClientSingleton();
|
||||
const db = globalThis.prisma ?? prismaClientSingleton();
|
||||
|
||||
export default prisma;
|
||||
export default db;
|
||||
|
||||
if (process.env.NODE_ENV !== "production") globalThis.prisma = prisma;
|
||||
if (process.env.NODE_ENV !== "production") globalThis.prisma = db;
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ declare global {
|
|||
var prisma: undefined | ReturnType<typeof prismaClientSingleton>
|
||||
}
|
||||
|
||||
const prisma = globalThis.prisma ?? prismaClientSingleton()
|
||||
const db = globalThis.prisma ?? prismaClientSingleton()
|
||||
|
||||
export default prisma
|
||||
|
||||
|
|
|
|||
|
|
@ -31,13 +31,13 @@ const sidebarMenus: SidebarMenu[] = [
|
|||
allowedPermissions: ["*"],
|
||||
children: [
|
||||
{
|
||||
label: "Request Link",
|
||||
label: "My Request Links",
|
||||
link: "/reseller-office-365/request",
|
||||
allowedRoles: ["*"]
|
||||
},
|
||||
{
|
||||
label: "Respond Request Link",
|
||||
link: "#",
|
||||
label: "Process Request Link",
|
||||
link: "/reseller-office-365/list",
|
||||
allowedRoles: ["*"]
|
||||
}
|
||||
]
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ import mapObjectToFirstValue from "@/utils/mapObjectToFirstValue";
|
|||
import db from "@/core/db";
|
||||
import getCurrentUser from "@/modules/auth/utils/getCurrentUser";
|
||||
import { revalidatePath } from "next/cache";
|
||||
import {server} from "../../../../server/socket";
|
||||
|
||||
export default async function createLinkRequest(
|
||||
formData: RequestLinkForm
|
||||
|
|
@ -55,8 +54,6 @@ export default async function createLinkRequest(
|
|||
|
||||
revalidatePath(".")
|
||||
|
||||
server.publish(`mwrl-${currentUser.id}`, "update")
|
||||
|
||||
return {
|
||||
success: true,
|
||||
message:
|
||||
|
|
|
|||
55
src/modules/resellerOffice365/actions/getAllLinkRequests.ts
Normal file
55
src/modules/resellerOffice365/actions/getAllLinkRequests.ts
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
import checkPermission from "@/modules/dashboard/services/checkPermission";
|
||||
import ServerResponseAction from "@/modules/dashboard/types/ServerResponseAction";
|
||||
import handleCatch from "@/modules/dashboard/utils/handleCatch";
|
||||
import unauthorized from "@/modules/dashboard/utils/unauthorized";
|
||||
import db from "@/core/db";
|
||||
import RequestLinkWithIssuerData from "../types/RequestLinkWithIssuerData";
|
||||
|
||||
export default async function getAllLinkRequests(): Promise<
|
||||
ServerResponseAction<RequestLinkWithIssuerData[]>
|
||||
> {
|
||||
try {
|
||||
//TODO: Fix permission check
|
||||
if (!(await checkPermission("authenticated-only")))
|
||||
return unauthorized();
|
||||
|
||||
const requestLinks = await db.office365LinkRequest.findMany({
|
||||
orderBy: [
|
||||
{
|
||||
status: "desc"
|
||||
},
|
||||
{
|
||||
requestedAt: "desc"
|
||||
}
|
||||
],
|
||||
select: {
|
||||
id: true,
|
||||
creator: {
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
photoProfile: true,
|
||||
email: true,
|
||||
},
|
||||
},
|
||||
status: true,
|
||||
requestedAt: true,
|
||||
_count: {
|
||||
select: {
|
||||
links: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
return {
|
||||
success: true,
|
||||
data: requestLinks.map((item) => ({
|
||||
...item,
|
||||
userCount: item._count.links,
|
||||
})),
|
||||
};
|
||||
} catch (e) {
|
||||
return handleCatch(e);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
"use server"
|
||||
import checkPermission from "@/modules/dashboard/services/checkPermission";
|
||||
import ServerResponseAction from "@/modules/dashboard/types/ServerResponseAction";
|
||||
import handleCatch from "@/modules/dashboard/utils/handleCatch";
|
||||
import unauthorized from "@/modules/dashboard/utils/unauthorized";
|
||||
import RequestLinkWithIssuerData from "../types/RequestLinkWithIssuerData";
|
||||
import db from "@/core/db";
|
||||
import { string } from "zod";
|
||||
import notFound from "@/modules/dashboard/utils/notFound";
|
||||
|
||||
async function getOffice365LinkRequestData(id: string) {
|
||||
const data = await db.office365LinkRequest.findFirst({
|
||||
where: { id },
|
||||
select: {
|
||||
acceptedAt: true,
|
||||
cancelledAt: true,
|
||||
creator: {
|
||||
select: {
|
||||
name: true,
|
||||
id: true,
|
||||
email: true,
|
||||
},
|
||||
},
|
||||
id: true,
|
||||
links: {
|
||||
select: {
|
||||
activePeriod: true,
|
||||
email: true,
|
||||
id: true,
|
||||
link: true,
|
||||
numberOfUsers: true,
|
||||
},
|
||||
},
|
||||
rejectedAt: true,
|
||||
requestedAt: true,
|
||||
status: true,
|
||||
},
|
||||
});
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
export default async function getLinkRequestDataById(
|
||||
id: string
|
||||
): Promise<
|
||||
ServerResponseAction<
|
||||
NonNullable<Awaited<ReturnType<typeof getOffice365LinkRequestData>>>
|
||||
>
|
||||
> {
|
||||
try {
|
||||
//TODO: Adjust permission
|
||||
if (!(await checkPermission("authenticated-only")))
|
||||
return unauthorized();
|
||||
|
||||
const data = await getOffice365LinkRequestData(id);
|
||||
|
||||
if (!data) {
|
||||
return notFound({
|
||||
message: "The requested link request item is not found",
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
data,
|
||||
};
|
||||
} catch (e) {
|
||||
return handleCatch(e);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
import {
|
||||
Alert,
|
||||
Button,
|
||||
|
|
@ -13,9 +14,10 @@ import {
|
|||
TextInput,
|
||||
Loader,
|
||||
Text,
|
||||
Skeleton,
|
||||
} from "@mantine/core";
|
||||
import { useForm, zodResolver } from "@mantine/form";
|
||||
import React, { useState } from "react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import {
|
||||
TbAt,
|
||||
TbCalendarTime,
|
||||
|
|
@ -30,27 +32,82 @@ import withServerAction from "@/modules/dashboard/utils/withServerAction";
|
|||
import createLinkRequest from "../actions/createLinkRequest";
|
||||
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";
|
||||
|
||||
export interface ModalProps {
|
||||
title: string;
|
||||
opened: boolean;
|
||||
readonly: boolean;
|
||||
onClose?: () => void;
|
||||
type: "create" | "detail" | "waiting" | "input link";
|
||||
detailId: string | null;
|
||||
}
|
||||
|
||||
export default function RequestModal(props: ModalProps) {
|
||||
const [formState, setFormState] = useState<
|
||||
"idle" | "submitting" | "waiting"
|
||||
"idle" | "submitting" | "waiting" | "fetching" | "error"
|
||||
>("idle");
|
||||
|
||||
const [errorMessage, setErrorMessage] = useState("");
|
||||
|
||||
const closeModal = () => {
|
||||
if (formState === "submitting") return; //prevents closing
|
||||
//reset state
|
||||
setErrorMessage("");
|
||||
setFormState("idle");
|
||||
form.reset();
|
||||
props.onClose ? props.onClose() : "";
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const fetchDataById = async (id: string) => {
|
||||
const { data } = await withServerAction(getLinkRequestDataById, id);
|
||||
if (!props.opened) return;
|
||||
return data;
|
||||
};
|
||||
|
||||
switch (props.type) {
|
||||
case "input link": {
|
||||
if (!props.detailId || !props.opened) return;
|
||||
setFormState("fetching");
|
||||
fetchDataById(props.detailId)
|
||||
.then((data) => {
|
||||
if (!data) {
|
||||
closeModal();
|
||||
notifications.show({
|
||||
message:
|
||||
"The returned data from server is empty. Please try again",
|
||||
color: "red",
|
||||
});
|
||||
return;
|
||||
}
|
||||
form.setValues({
|
||||
numberOfLinks: data.links.length,
|
||||
id: data.id,
|
||||
details: data.links.map((item) => ({
|
||||
activePeriod: item.activePeriod,
|
||||
email: item.email,
|
||||
endUserQty: item.numberOfUsers,
|
||||
})),
|
||||
});
|
||||
})
|
||||
.catch((e) => {
|
||||
if (e instanceof Error) {
|
||||
setErrorMessage(e.message);
|
||||
} else {
|
||||
setErrorMessage("Unkown error occured");
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
setFormState("idle");
|
||||
});
|
||||
}
|
||||
}
|
||||
}, [props]);
|
||||
|
||||
const form = useForm<RequestLinkForm>({
|
||||
initialValues: {
|
||||
id: undefined,
|
||||
numberOfLinks: 1,
|
||||
details: [
|
||||
{
|
||||
|
|
@ -90,51 +147,67 @@ export default function RequestModal(props: ModalProps) {
|
|||
},
|
||||
});
|
||||
|
||||
const disableChange = formState !== "idle";
|
||||
|
||||
const handleSubmit = (values: RequestLinkForm) => {
|
||||
const submitableState = ["idle"];
|
||||
const submitableState: (typeof formState)[] = ["idle"];
|
||||
|
||||
if (!submitableState.includes(formState)) return; //prevent submit
|
||||
if (!submitableState.includes(formState)) return; //prevent submit when not in subitable state
|
||||
|
||||
setFormState("submitting");
|
||||
|
||||
withServerAction(createLinkRequest, values)
|
||||
.then((response) => {
|
||||
notifications.show({
|
||||
message: response.message,
|
||||
color: "green",
|
||||
});
|
||||
setFormState("waiting");
|
||||
})
|
||||
.catch((e) => {
|
||||
if (e instanceof DashboardError) {
|
||||
if (e.errorCode === "INVALID_FORM_DATA") {
|
||||
if (e.formErrors) {
|
||||
form.setErrors(e.formErrors);
|
||||
switch (props.type) {
|
||||
case "create": {
|
||||
withServerAction(createLinkRequest, values)
|
||||
.then((response) => {
|
||||
notifications.show({
|
||||
message: response.message,
|
||||
color: "green",
|
||||
});
|
||||
setFormState("waiting");
|
||||
})
|
||||
.catch((e) => {
|
||||
if (e instanceof DashboardError) {
|
||||
if (e.errorCode === "INVALID_FORM_DATA") {
|
||||
if (e.formErrors) {
|
||||
form.setErrors(e.formErrors);
|
||||
} else {
|
||||
setErrorMessage(e.message);
|
||||
}
|
||||
} else {
|
||||
setErrorMessage(
|
||||
`ERROR: ${e.message} (${e.errorCode})`
|
||||
);
|
||||
}
|
||||
} else if (e instanceof Error) {
|
||||
setErrorMessage(`ERROR: ${e.message}`);
|
||||
} else {
|
||||
setErrorMessage(e.message);
|
||||
setErrorMessage(
|
||||
`Unkown error is occured. Please contact administrator`
|
||||
);
|
||||
}
|
||||
} else {
|
||||
setErrorMessage(`ERROR: ${e.message} (${e.errorCode})`);
|
||||
}
|
||||
} else if (e instanceof Error) {
|
||||
setErrorMessage(`ERROR: ${e.message}`);
|
||||
} else {
|
||||
setErrorMessage(
|
||||
`Unkown error is occured. Please contact administrator`
|
||||
);
|
||||
}
|
||||
|
||||
setFormState("idle");
|
||||
});
|
||||
setFormState("idle");
|
||||
});
|
||||
break;
|
||||
}
|
||||
case "input link": {
|
||||
//TODO: Handle add link
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const disableChange = formState !== "idle";
|
||||
const readonly = props.type === "input link";
|
||||
const showSkeleton = formState === "fetching";
|
||||
|
||||
return (
|
||||
<Modal
|
||||
size="sm"
|
||||
opened={props.opened}
|
||||
title={formState === "waiting" ? "Link Request Detail" : "Create New Request"}
|
||||
title={
|
||||
formState === "waiting"
|
||||
? "Link Request Detail"
|
||||
: "Create New Request"
|
||||
}
|
||||
onClose={closeModal}
|
||||
scrollAreaComponent={ScrollArea.Autosize}
|
||||
>
|
||||
|
|
@ -146,16 +219,21 @@ export default function RequestModal(props: ModalProps) {
|
|||
</Alert>
|
||||
)}
|
||||
|
||||
<NumberInput
|
||||
label="Please input the number of links you request"
|
||||
min={1}
|
||||
max={3}
|
||||
allowDecimal={false}
|
||||
clampBehavior="strict"
|
||||
leftSection={<TbLink />}
|
||||
disabled={disableChange}
|
||||
{...form.getInputProps("numberOfLinks")}
|
||||
/>
|
||||
{errorMessage && <Alert color="red">{errorMessage}</Alert>}
|
||||
|
||||
<Skeleton visible={showSkeleton}>
|
||||
<NumberInput
|
||||
label="Please input the number of links you request"
|
||||
min={1}
|
||||
max={3}
|
||||
allowDecimal={false}
|
||||
clampBehavior="strict"
|
||||
leftSection={<TbLink />}
|
||||
disabled={disableChange}
|
||||
readOnly={readonly}
|
||||
{...form.getInputProps("numberOfLinks")}
|
||||
/>
|
||||
</Skeleton>
|
||||
|
||||
<Divider
|
||||
label="End User Information"
|
||||
|
|
@ -165,39 +243,60 @@ export default function RequestModal(props: ModalProps) {
|
|||
<Stack>
|
||||
{form.values.details.map((item, i) => (
|
||||
<Fieldset key={i} legend={`Information ${i + 1}`}>
|
||||
<TextInput
|
||||
leftSection={<TbAt />}
|
||||
label="Email"
|
||||
disabled={disableChange}
|
||||
{...form.getInputProps(
|
||||
`details.${i}.email`
|
||||
<Stack gap="xs">
|
||||
<Skeleton visible={showSkeleton}>
|
||||
<TextInput
|
||||
leftSection={<TbAt />}
|
||||
label="Email"
|
||||
readOnly={readonly}
|
||||
disabled={disableChange}
|
||||
{...form.getInputProps(
|
||||
`details.${i}.email`
|
||||
)}
|
||||
/>
|
||||
</Skeleton>
|
||||
<Flex gap="md">
|
||||
<Skeleton visible={showSkeleton}>
|
||||
<Select
|
||||
data={
|
||||
resellerOffice365Config.activePeriods
|
||||
}
|
||||
label="Active Period"
|
||||
disabled={disableChange}
|
||||
readOnly={readonly}
|
||||
leftSection={<TbCalendarTime />}
|
||||
{...form.getInputProps(
|
||||
`details.${i}.activePeriod`
|
||||
)}
|
||||
/>
|
||||
</Skeleton>
|
||||
<Skeleton visible={showSkeleton}>
|
||||
<NumberInput
|
||||
label="End User Quantity"
|
||||
leftSection={<TbUsers />}
|
||||
min={1}
|
||||
max={5}
|
||||
disabled={disableChange}
|
||||
allowDecimal={false}
|
||||
readOnly={readonly}
|
||||
clampBehavior="strict"
|
||||
{...form.getInputProps(
|
||||
`details.${i}.endUserQty`
|
||||
)}
|
||||
/>
|
||||
</Skeleton>
|
||||
</Flex>
|
||||
{["input link", "detail"].includes(
|
||||
props.type
|
||||
) && (
|
||||
<Skeleton visible={showSkeleton}>
|
||||
<TextInput
|
||||
label="Activation Link"
|
||||
required
|
||||
/>
|
||||
</Skeleton>
|
||||
)}
|
||||
/>
|
||||
<Flex gap="md">
|
||||
<Select
|
||||
data={
|
||||
resellerOffice365Config.activePeriods
|
||||
}
|
||||
label="Active Period"
|
||||
disabled={disableChange}
|
||||
leftSection={<TbCalendarTime />}
|
||||
{...form.getInputProps(
|
||||
`details.${i}.activePeriod`
|
||||
)}
|
||||
/>
|
||||
<NumberInput
|
||||
label="End User Quantity"
|
||||
leftSection={<TbUsers />}
|
||||
min={1}
|
||||
max={5}
|
||||
disabled={disableChange}
|
||||
allowDecimal={false}
|
||||
clampBehavior="strict"
|
||||
{...form.getInputProps(
|
||||
`details.${i}.endUserQty`
|
||||
)}
|
||||
/>
|
||||
</Flex>
|
||||
</Stack>
|
||||
</Fieldset>
|
||||
))}
|
||||
</Stack>
|
||||
|
|
@ -211,7 +310,7 @@ export default function RequestModal(props: ModalProps) {
|
|||
>
|
||||
Close
|
||||
</Button>
|
||||
{(!props.readonly || formState === "waiting") && (
|
||||
{formState === "waiting" && (
|
||||
<Button
|
||||
variant="filled"
|
||||
leftSection={<TbDeviceFloppy size={20} />}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,66 @@
|
|||
"use client";
|
||||
import DashboardTable from "@/modules/dashboard/components/DashboardTable";
|
||||
import { Button, Flex, Text } from "@mantine/core";
|
||||
import { getCoreRowModel, useReactTable } from "@tanstack/react-table";
|
||||
import React, { ReactNode, useState } from "react";
|
||||
import { TbPlus } from "react-icons/tb";
|
||||
import createColumns from "./columns";
|
||||
import CrudPermissions from "@/modules/dashboard/types/CrudPermissions";
|
||||
import RequestLink from "../../types/RequestLink";
|
||||
import RequestModal, { ModalProps } from "../../modals/RequestModal";
|
||||
import RequestLinkWithIssuerData from "../../types/RequestLinkWithIssuerData";
|
||||
|
||||
interface Props {
|
||||
permissions: Partial<CrudPermissions>;
|
||||
tableData: RequestLinkWithIssuerData[];
|
||||
}
|
||||
|
||||
const defaultModalProps: ModalProps = {
|
||||
opened: false,
|
||||
title: "Create new Link",
|
||||
type: "create",
|
||||
detailId: null,
|
||||
};
|
||||
|
||||
export default function ListOfRequestTable(props: Props) {
|
||||
const [modalProps, setModalProps] = useState<ModalProps>(defaultModalProps);
|
||||
// const [openModal, setOpenModal] = useState(false);
|
||||
|
||||
const table = useReactTable({
|
||||
data: props.tableData,
|
||||
columns: createColumns({
|
||||
permissions: props.permissions,
|
||||
actions: {
|
||||
detail: (id) => {
|
||||
openFormModal(id);
|
||||
},
|
||||
},
|
||||
}),
|
||||
|
||||
getCoreRowModel: getCoreRowModel(),
|
||||
defaultColumn: {
|
||||
cell: (props) => <Text>{props.getValue() as ReactNode}</Text>,
|
||||
},
|
||||
});
|
||||
|
||||
const openFormModal = (id: string) => {
|
||||
setModalProps({
|
||||
opened: true,
|
||||
title: "Request Detail",
|
||||
type: "input link",
|
||||
detailId: id,
|
||||
});
|
||||
};
|
||||
|
||||
const closeModal = () => {
|
||||
setModalProps(defaultModalProps);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<DashboardTable table={table} />
|
||||
|
||||
<RequestModal {...modalProps} onClose={closeModal} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
import { createColumnHelper } from "@tanstack/react-table";
|
||||
import { Avatar, Badge, Flex, Stack, Text } from "@mantine/core";
|
||||
import { TbEye, TbPencil, TbTrash } from "react-icons/tb";
|
||||
import CrudPermissions from "@/modules/dashboard/types/CrudPermissions";
|
||||
import createActionButtons from "@/modules/dashboard/utils/createActionButton";
|
||||
import RequestLinkWithIssuerData from "../../types/RequestLinkWithIssuerData";
|
||||
|
||||
interface ColumnOptions {
|
||||
permissions: Partial<CrudPermissions>;
|
||||
actions: {
|
||||
detail: (id: string) => void;
|
||||
// edit: (id: string) => void;
|
||||
// delete: (id: string) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const createColumns = (options: ColumnOptions) => {
|
||||
const columnHelper = createColumnHelper<RequestLinkWithIssuerData>();
|
||||
|
||||
const columns = [
|
||||
columnHelper.accessor("id", {
|
||||
id: "sequence",
|
||||
header: "#",
|
||||
cell: (props) => props.row.index + 1,
|
||||
}),
|
||||
|
||||
columnHelper.accessor("requestedAt", {
|
||||
header: "Request Date",
|
||||
cell: (props) => {
|
||||
const date = new Date(props.row.original.requestedAt);
|
||||
return `${date.toDateString()}; ${date.toLocaleTimeString()}`;
|
||||
},
|
||||
}),
|
||||
|
||||
columnHelper.accessor("creator", {
|
||||
header: "Issuer",
|
||||
cell: (props) => {
|
||||
return (<Flex gap="sm" align="center">
|
||||
<Avatar src={props.cell.getValue().photoProfile} />
|
||||
<div>
|
||||
<Text>{props.cell.getValue().name}</Text>
|
||||
<Text size="xs" c="gray">{props.cell.getValue().email}</Text>
|
||||
</div>
|
||||
</Flex>)
|
||||
}
|
||||
}),
|
||||
|
||||
columnHelper.accessor("userCount", {
|
||||
header: "User Count",
|
||||
}),
|
||||
|
||||
columnHelper.accessor("status", {
|
||||
header: "Status",
|
||||
cell: (props) => {
|
||||
switch (props.row.original.status) {
|
||||
case "WAITING":
|
||||
return <Badge color="cyan">WAITING</Badge>;
|
||||
break;
|
||||
case "ACCEPTED":
|
||||
return <Badge color="green">ACCEPTED</Badge>;
|
||||
break;
|
||||
case "CANCELLED":
|
||||
return <Badge color="gray">CANCELLED</Badge>;
|
||||
break;
|
||||
case "REJECTED":
|
||||
return <Badge color="red">REJECTED</Badge>;
|
||||
break;
|
||||
}
|
||||
},
|
||||
}),
|
||||
|
||||
columnHelper.display({
|
||||
id: "Actions",
|
||||
header: "Actions",
|
||||
cell: (props) => (
|
||||
<Flex gap="xs">
|
||||
{createActionButtons([
|
||||
{
|
||||
label: "Detail",
|
||||
permission: options.permissions.read,
|
||||
action: () =>
|
||||
options.actions.detail(props.row.original.id),
|
||||
color: "green",
|
||||
icon: <TbEye />,
|
||||
},
|
||||
])}
|
||||
</Flex>
|
||||
),
|
||||
}),
|
||||
];
|
||||
|
||||
return columns;
|
||||
};
|
||||
|
||||
export default createColumns;
|
||||
|
|
@ -14,21 +14,25 @@ interface Props {
|
|||
tableData: RequestLink[];
|
||||
}
|
||||
|
||||
const defaultModalProps: ModalProps = {
|
||||
opened: false,
|
||||
title: "",
|
||||
type: "create",
|
||||
detailId: null,
|
||||
};
|
||||
|
||||
export default function RequestTable(props: Props) {
|
||||
// const [modalProps, setModalProps] = useState<ModalProps>({
|
||||
// opened: false,
|
||||
// title: "",
|
||||
// readonly: false,
|
||||
// });
|
||||
const [openModal, setOpenModal] = useState(false);
|
||||
const [modalProps, setModalProps] = useState<ModalProps>(defaultModalProps);
|
||||
|
||||
const table = useReactTable({
|
||||
data: props.tableData,
|
||||
columns: createColumns({
|
||||
permissions: props.permissions,
|
||||
actions: {
|
||||
detail: (id) => {console.log(id)}
|
||||
}
|
||||
detail: (id) => {
|
||||
console.log(id);
|
||||
},
|
||||
},
|
||||
}),
|
||||
getCoreRowModel: getCoreRowModel(),
|
||||
defaultColumn: {
|
||||
|
|
@ -36,33 +40,24 @@ export default function RequestTable(props: Props) {
|
|||
},
|
||||
});
|
||||
|
||||
const openFormModall = () => {
|
||||
// setModalProps({
|
||||
// opened: true,
|
||||
// title: "Request new link",
|
||||
// readonly: false,
|
||||
// });
|
||||
// console.log('hai')
|
||||
setOpenModal(true);
|
||||
const openCreateModal = () => {
|
||||
setModalProps({
|
||||
opened: true,
|
||||
title: "Create New Office 365 Link Request",
|
||||
detailId: null,
|
||||
type: "create",
|
||||
});
|
||||
};
|
||||
|
||||
const closeModal = () => {
|
||||
// setModalProps({
|
||||
// opened: false,
|
||||
// title: "",
|
||||
// readonly: false,
|
||||
// });
|
||||
setOpenModal(false)
|
||||
setModalProps(defaultModalProps);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex justify="flex-end">
|
||||
{
|
||||
<Button
|
||||
leftSection={<TbPlus />}
|
||||
onClick={() => openFormModall()}
|
||||
>
|
||||
<Button leftSection={<TbPlus />} onClick={openCreateModal}>
|
||||
New Link Request
|
||||
</Button>
|
||||
}
|
||||
|
|
@ -70,7 +65,7 @@ export default function RequestTable(props: Props) {
|
|||
|
||||
<DashboardTable table={table} />
|
||||
|
||||
<RequestModal opened={openModal} readonly={false} title="Create new Link Request" onClose={closeModal} />
|
||||
<RequestModal {...modalProps} onClose={closeModal} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,9 +6,9 @@ import createActionButtons from "@/modules/dashboard/utils/createActionButton";
|
|||
|
||||
export interface RequestLinkRow {
|
||||
id: string;
|
||||
requestDate: string,
|
||||
userCount: number,
|
||||
status: string
|
||||
requestDate: string;
|
||||
userCount: number;
|
||||
status: string;
|
||||
}
|
||||
|
||||
interface ColumnOptions {
|
||||
|
|
@ -34,8 +34,8 @@ const createColumns = (options: ColumnOptions) => {
|
|||
header: "Request Date",
|
||||
cell: (props) => {
|
||||
const date = new Date(props.row.original.requestDate);
|
||||
return `${date.toDateString()}; ${date.toLocaleTimeString()}`
|
||||
}
|
||||
return `${date.toDateString()}; ${date.toLocaleTimeString()}`;
|
||||
},
|
||||
}),
|
||||
|
||||
columnHelper.accessor("userCount", {
|
||||
|
|
@ -44,6 +44,22 @@ const createColumns = (options: ColumnOptions) => {
|
|||
|
||||
columnHelper.accessor("status", {
|
||||
header: "Status",
|
||||
cell: (props) => {
|
||||
switch (props.row.original.status) {
|
||||
case "WAITING":
|
||||
return <Badge color="cyan">WAITING</Badge>;
|
||||
break;
|
||||
case "ACCEPTED":
|
||||
return <Badge color="green">ACCEPTED</Badge>;
|
||||
break;
|
||||
case "CANCELLED":
|
||||
return <Badge color="gray">CANCELLED</Badge>;
|
||||
break;
|
||||
case "REJECTED":
|
||||
return <Badge color="red">REJECTED</Badge>;
|
||||
break;
|
||||
}
|
||||
},
|
||||
}),
|
||||
|
||||
columnHelper.display({
|
||||
|
|
@ -68,23 +84,13 @@ const createColumns = (options: ColumnOptions) => {
|
|||
color: "yellow",
|
||||
icon: <TbPencil />,
|
||||
},
|
||||
{
|
||||
label: "Delete",
|
||||
permission: options.permissions.delete,
|
||||
// action: () =>
|
||||
// options.actions.delete(
|
||||
// props.row.original.id
|
||||
// ),
|
||||
color: "red",
|
||||
icon: <TbTrash />,
|
||||
},
|
||||
])}
|
||||
</Flex>
|
||||
),
|
||||
}),
|
||||
];
|
||||
|
||||
return columns;
|
||||
return columns;
|
||||
};
|
||||
|
||||
export default createColumns;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
interface RequestLinkForm {
|
||||
id: string | undefined;
|
||||
numberOfLinks: number;
|
||||
details: {
|
||||
email: string;
|
||||
|
|
|
|||
14
src/modules/resellerOffice365/types/RequestLinkWithIssuerData.d.ts
vendored
Normal file
14
src/modules/resellerOffice365/types/RequestLinkWithIssuerData.d.ts
vendored
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
import { Office365LinkRequestStatus, Prisma } from "@prisma/client";
|
||||
|
||||
export default interface RequestLinkWithIssuerData {
|
||||
id: string;
|
||||
status: Office365LinkRequestStatus;
|
||||
requestedAt: Date;
|
||||
creator: {
|
||||
id: string;
|
||||
name: string | null;
|
||||
email: string | null;
|
||||
photoProfile: string | null;
|
||||
};
|
||||
userCount: number
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user