diff --git a/apps/api/src/controllers/ticket.ts b/apps/api/src/controllers/ticket.ts
index 066ff7ed2..5494d3b57 100644
--- a/apps/api/src/controllers/ticket.ts
+++ b/apps/api/src/controllers/ticket.ts
@@ -14,6 +14,8 @@ export function ticketRoutes(fastify: FastifyInstance) {
const { name, company, detail, title, priority, email, engineer }: any =
request.body;
+ console.log(request.body);
+
const ticket: any = await prisma.ticket.create({
data: {
name,
@@ -24,7 +26,7 @@ export function ticketRoutes(fastify: FastifyInstance) {
client:
company !== undefined
? {
- connect: { id: company.id },
+ connect: { id: company.id || company },
}
: undefined,
fromImap: false,
@@ -62,6 +64,7 @@ export function ticketRoutes(fastify: FastifyInstance) {
reply.status(200).send({
message: "Ticket created correctly",
success: true,
+ id: ticket.id,
});
}
);
diff --git a/apps/api/src/main.ts b/apps/api/src/main.ts
index 68fc431b6..4510242af 100644
--- a/apps/api/src/main.ts
+++ b/apps/api/src/main.ts
@@ -122,7 +122,7 @@ const start = async () => {
client.capture({
event: "server_started",
- distinctId: "api_server",
+ distinctId: "uuid",
});
await client.shutdownAsync();
diff --git a/apps/client/pages/_app.tsx b/apps/client/pages/_app.tsx
index b5451473c..cf6e3a1d5 100644
--- a/apps/client/pages/_app.tsx
+++ b/apps/client/pages/_app.tsx
@@ -26,6 +26,8 @@ const queryClient = new QueryClient();
function Auth({ children }: any) {
const { loading, user } = useUser();
+ const router = useRouter();
+
React.useEffect(() => {
if (loading) return; // Do nothing while loading
}, [user, loading]);
@@ -34,9 +36,6 @@ function Auth({ children }: any) {
return children;
}
- // Session is being fetched, or no user.
- // If no user, useEffect() will redirect.
-
return (
{/* */}
@@ -148,6 +147,15 @@ function MyApp({ Component, pageProps: { session, ...pageProps } }: any) {
);
}
+ if (router.pathname.includes("/portal")) {
+ return (
+ <>
+
+
+ >
+ );
+ }
+
return (
diff --git a/apps/client/pages/admin/clients/index.tsx b/apps/client/pages/admin/clients/index.tsx
index e2acfef51..b560f971f 100644
--- a/apps/client/pages/admin/clients/index.tsx
+++ b/apps/client/pages/admin/clients/index.tsx
@@ -1,4 +1,5 @@
import Link from "next/link";
+import { useRouter } from "next/router";
import React from "react";
import { useQuery } from "react-query";
import {
@@ -207,6 +208,8 @@ export default function Clients() {
fetchAllClients
);
+ const router = useRouter();
+
async function deleteClient(id: any) {
await fetch(
`${process.env.NEXT_PUBLIC_API_URL}/api/v1/clients/${id}/delete-client`,
@@ -247,11 +250,18 @@ export default function Clients() {
*/}
deleteClient(row.original.id)}
>
Delete
+
+ Portal Url
+
);
},
diff --git a/apps/client/pages/new.tsx b/apps/client/pages/new.tsx
index 81cba2753..54c3244ed 100644
--- a/apps/client/pages/new.tsx
+++ b/apps/client/pages/new.tsx
@@ -25,7 +25,6 @@ export default function CreateTicket() {
const token = getCookie("session");
- const [open, setOpen] = useState(false);
const [name, setName] = useState("");
const [company, setCompany] = useState();
const [engineer, setEngineer] = useState();
diff --git a/apps/client/pages/portal/[id]/ticket/[id].tsx b/apps/client/pages/portal/[id]/ticket/[id].tsx
new file mode 100644
index 000000000..e69de29bb
diff --git a/apps/client/pages/portal/[id]/ticket/new.tsx b/apps/client/pages/portal/[id]/ticket/new.tsx
new file mode 100644
index 000000000..5bbe6033d
--- /dev/null
+++ b/apps/client/pages/portal/[id]/ticket/new.tsx
@@ -0,0 +1,374 @@
+// Check if the ID matches the id of the company
+// If true then show ticket creation htmlForm else show access denied htmlForm
+// API post request to creating a ticket with relevant client info
+// Default to unassigned engineer
+// Send Email to customer with ticket creation
+// Send Email to Engineers with ticket creation if email notifications are turned on
+
+import { Listbox, Transition } from "@headlessui/react";
+import {
+ CheckCircleIcon,
+ CheckIcon,
+ ChevronUpDownIcon,
+} from "@heroicons/react/20/solid";
+import { notifications } from "@mantine/notifications";
+import { useRouter } from "next/router";
+import { Fragment, useState } from "react";
+
+const type = [
+ { id: 1, name: "Bug" },
+ { id: 2, name: "Feature Request" },
+ { id: 3, name: "Support" },
+ { id: 4, name: "Billing" },
+ { id: 5, name: "Hardware" },
+ { id: 6, name: "Software" },
+];
+
+const pri = [
+ { id: 7, name: "Low" },
+ { id: 8, name: "Medium" },
+ { id: 9, name: "High" },
+];
+
+export default function ClientTicketNew() {
+ function classNames(...classes) {
+ return classes.filter(Boolean).join(" ");
+ }
+
+ const router = useRouter();
+ const [isLoading, setIsLoading] = useState(false);
+ const [view, setView] = useState("success");
+ const [ticketID, setTicketID] = useState("");
+
+ const [selected, setSelected] = useState(type[2]);
+ const [name, setName] = useState("");
+ const [email, setEmail] = useState("");
+ const [subject, setSubject] = useState("");
+ const [description, setDescription] = useState("");
+ const [priority, setPriority] = useState(pri[0]);
+
+ async function submitTicket() {
+ setIsLoading(true);
+ await fetch(`${process.env.NEXT_PUBLIC_API_URL}/api/v1/ticket/create`, {
+ method: "POST",
+ headers: {
+ "content-type": "application/json",
+ },
+ body: JSON.stringify({
+ name,
+ title: subject,
+ company: router.query.id,
+ email,
+ detail: description,
+ priority: priority.name,
+ }),
+ })
+ .then((res) => res.json())
+ .then((res) => {
+ if (res.success === true) {
+ notifications.show({
+ title: "Ticket Created",
+ message: "Ticket created succesfully",
+ color: "green",
+ autoClose: 5000,
+ });
+ setView("success");
+ setTicketID(res.id);
+ } else {
+ notifications.show({
+ title: "Error",
+ message: `Please fill out all information and try again`,
+ color: "red",
+ autoClose: 5000,
+ });
+ }
+ });
+ setIsLoading(false);
+ }
+
+ return (
+
+ {view === "new" ? (
+
+
Submit a Ticket
+
+ Need help? Submit a ticket and our support team will get back to you
+ as soon as possible.
+
+
+
+
+
+ Name
+
+
+ setName(e.target.value)}
+ value={name}
+ autoComplete="off"
+ />
+
+
+
+
+ Email
+
+
+ setEmail(e.target.value)}
+ value={email}
+ autoComplete="off"
+ />
+
+
+
+
+ Subject
+
+
+ setSubject(e.target.value)}
+ value={subject}
+ />
+
+
+
+
+ {({ open }) => (
+ <>
+
+ Issue Type
+
+
+
+ {selected.name}
+
+
+
+
+
+
+
+ {type.map((person) => (
+
+ classNames(
+ active
+ ? "bg-gray-400 text-white"
+ : "text-gray-900",
+ "relative cursor-default select-none py-2 pl-3 pr-9"
+ )
+ }
+ value={person}
+ >
+ {({ selected, active }) => (
+ <>
+
+ {person.name}
+
+
+ {selected ? (
+
+
+
+ ) : null}
+ >
+ )}
+
+ ))}
+
+
+
+ >
+ )}
+
+
+
+ {({ open }) => (
+ <>
+
+ Priority
+
+
+
+ {priority.name}
+
+
+
+
+
+
+
+ {pri.map((person) => (
+
+ classNames(
+ active
+ ? "bg-gray-400 text-white"
+ : "text-gray-900",
+ "relative cursor-default select-none py-2 pl-3 pr-9"
+ )
+ }
+ value={person}
+ >
+ {({ selected, active }) => (
+ <>
+
+ {person.name}
+
+
+ {selected ? (
+
+
+
+ ) : null}
+ >
+ )}
+
+ ))}
+
+
+
+ >
+ )}
+
+
+
+
+ Description of Issue
+
+
+
+
+
+
+ Submit Ticket
+
+
+
+ ) : (
+ <>
+
+
+
+
+
+
+
+ Ticket Submitted
+
+
+
+ A member of our team has been notified and will be in touch
+ shortly.
+
+
+ {/*
*/}
+
+
+
+ >
+ )}
+
+ );
+}
diff --git a/apps/client/pages/public/[id]/new-ticket.js b/apps/client/pages/public/[id]/new-ticket.js
deleted file mode 100644
index b907cf089..000000000
--- a/apps/client/pages/public/[id]/new-ticket.js
+++ /dev/null
@@ -1,17 +0,0 @@
-// Check if the ID matches the id of the company
-// If true then show ticket creation form else show access denied form
-// API post request to creating a ticket with relevant client info
-// Default to unassigned engineer
-// Send Email to customer with ticket creation
-// Send Email to Engineers with ticket creation if email notifications are turned on
-
-
-
-export default function NewPublicTicket() {
-
- return (
-
-
-
- )
-}
\ No newline at end of file