mirror of
https://github.com/formbricks/formbricks.git
synced 2026-02-04 10:30:00 -06:00
Feature/fix authentication issues (#15)
* fix errors when not authenticated * update syntax highlighting and react code sample
This commit is contained in:
13
components/MessagePage.tsx
Normal file
13
components/MessagePage.tsx
Normal file
@@ -0,0 +1,13 @@
|
||||
export default function MessagePage({ text }) {
|
||||
return (
|
||||
<div className="min-h-screen px-4 py-16 bg-white sm:px-6 sm:py-24 md:grid md:place-items-center lg:px-8">
|
||||
<div className="mx-auto max-w-max">
|
||||
<main>
|
||||
<div className="flex justify-center text-sm text-ui-gray-dark">
|
||||
{text}
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,15 +1,11 @@
|
||||
import { signIn, useSession } from "next-auth/react";
|
||||
import Head from "next/head";
|
||||
import { useEffect, useState } from "react";
|
||||
import { identifyPoshogUser } from "../../lib/posthog";
|
||||
import { classNames } from "../../lib/utils";
|
||||
import Loading from "../Loading";
|
||||
import MenuBreadcrumbs from "./MenuBreadcrumbs";
|
||||
import MenuProfile from "./MenuProfile";
|
||||
import MenuSteps from "./MenuSteps";
|
||||
import NewFormNavButton from "./NewFormNavButton";
|
||||
|
||||
interface BaseLayoutAuthorizedProps {
|
||||
interface BaseLayoutManagementProps {
|
||||
title: string;
|
||||
breadcrumbs: any;
|
||||
steps?: any;
|
||||
@@ -19,7 +15,7 @@ interface BaseLayoutAuthorizedProps {
|
||||
limitHeightScreen?: boolean;
|
||||
}
|
||||
|
||||
export default function BaseLayoutAuthorized({
|
||||
export default function BaseLayoutManagement({
|
||||
title,
|
||||
breadcrumbs,
|
||||
steps,
|
||||
@@ -27,25 +23,7 @@ export default function BaseLayoutAuthorized({
|
||||
children,
|
||||
bgClass = "bg-ui-gray-lighter",
|
||||
limitHeightScreen = false,
|
||||
}: BaseLayoutAuthorizedProps) {
|
||||
const { data: session, status } = useSession();
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
if (status !== "loading") {
|
||||
if (!session) {
|
||||
signIn();
|
||||
} else {
|
||||
setLoading(false);
|
||||
identifyPoshogUser(session.user.email);
|
||||
}
|
||||
}
|
||||
}, [session, status]);
|
||||
|
||||
if (status === "loading" || loading) {
|
||||
return <Loading />;
|
||||
}
|
||||
|
||||
}: BaseLayoutManagementProps) {
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
21
components/layout/WithAuthentication.tsx
Normal file
21
components/layout/WithAuthentication.tsx
Normal file
@@ -0,0 +1,21 @@
|
||||
import { signIn, useSession } from "next-auth/react";
|
||||
import Loading from "../Loading";
|
||||
|
||||
const withAuthentication = (Component) =>
|
||||
function WithAuth(props) {
|
||||
const { status } = useSession({
|
||||
required: true,
|
||||
onUnauthenticated() {
|
||||
// The user is not authenticated, handle it here.
|
||||
return signIn();
|
||||
},
|
||||
});
|
||||
|
||||
if (status === "loading") {
|
||||
return <Loading />;
|
||||
}
|
||||
|
||||
return <Component {...props} />;
|
||||
};
|
||||
|
||||
export default withAuthentication;
|
||||
19
lib/auth.ts
19
lib/auth.ts
@@ -9,3 +9,22 @@ export async function verifyPassword(password: string, hashedPassword: string) {
|
||||
const isValid = await compare(password, hashedPassword);
|
||||
return isValid;
|
||||
}
|
||||
export function requireAuthentication(gssp) {
|
||||
return async (context) => {
|
||||
const { req, resolvedUrl } = context;
|
||||
const token = req.cookies.userToken;
|
||||
|
||||
if (!token) {
|
||||
return {
|
||||
redirect: {
|
||||
destination: `/auth/signin?callbackUrl=${encodeURIComponent(
|
||||
resolvedUrl
|
||||
)}`,
|
||||
statusCode: 302,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return await gssp(context); // Continue on to call `getServerSideProps` logic
|
||||
};
|
||||
}
|
||||
|
||||
@@ -12,15 +12,15 @@ export default function SignInPage() {
|
||||
const handleSubmit = async (e) => {
|
||||
e.preventDefault();
|
||||
await signIn("credentials", {
|
||||
callbackUrl: router.query.callbackUrl?.toString(),
|
||||
callbackUrl: router.query.callbackUrl?.toString() || "/forms",
|
||||
email: e.target.elements.email.value,
|
||||
password: e.target.elements.password.value,
|
||||
});
|
||||
router.push(
|
||||
/* router.push(
|
||||
`/auth/verification-requested?email=${encodeURIComponent(
|
||||
e.target.elements.email.value
|
||||
)}`
|
||||
);
|
||||
); */
|
||||
};
|
||||
return (
|
||||
<BaseLayoutUnauthorized title="Sign in">
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import { GetServerSideProps } from "next";
|
||||
import { getSession } from "next-auth/react";
|
||||
import { useRouter } from "next/router";
|
||||
import App from "../../components/frontend/App";
|
||||
import BaseLayoutUnauthorized from "../../components/layout/BaseLayoutUnauthorized";
|
||||
import Loading from "../../components/Loading";
|
||||
import MessagePage from "../../components/MessagePage";
|
||||
import { useNoCodeFormPublic } from "../../lib/noCodeForm";
|
||||
import { useRouter } from "next/router";
|
||||
|
||||
export default function Share({}) {
|
||||
const router = useRouter();
|
||||
@@ -13,7 +12,9 @@ export default function Share({}) {
|
||||
useNoCodeFormPublic(formId);
|
||||
|
||||
if (isErrorNoCodeForm) {
|
||||
return <p>Not found</p>;
|
||||
return (
|
||||
<MessagePage text="Form not found. Are you sure this is the right URL?" />
|
||||
);
|
||||
}
|
||||
|
||||
if (isLoadingNoCodeForm) {
|
||||
@@ -26,11 +27,3 @@ export default function Share({}) {
|
||||
</BaseLayoutUnauthorized>
|
||||
);
|
||||
}
|
||||
|
||||
export const getServerSideProps: GetServerSideProps = async ({ req, res }) => {
|
||||
const session = await getSession({ req });
|
||||
if (!session) {
|
||||
res.statusCode = 403;
|
||||
}
|
||||
return { props: {} };
|
||||
};
|
||||
|
||||
@@ -1,34 +1,45 @@
|
||||
import { GetServerSideProps } from "next";
|
||||
import { getSession } from "next-auth/react";
|
||||
import { useRouter } from "next/router";
|
||||
import BaseLayoutManagement from "../../../../components/layout/BaseLayoutManagement";
|
||||
import Builder from "../../../../components/builder/Builder";
|
||||
import FormCode from "../../../../components/form/FormCode";
|
||||
import BaseLayoutAuthorized from "../../../../components/layout/BaseLayoutAuthorized";
|
||||
import FullWidth from "../../../../components/layout/FullWidth";
|
||||
import LimitedWidth from "../../../../components/layout/LimitedWidth";
|
||||
import SecondNavBar from "../../../../components/layout/SecondNavBar";
|
||||
import Loading from "../../../../components/Loading";
|
||||
import { useForm } from "../../../../lib/forms";
|
||||
import MessagePage from "../../../../components/MessagePage";
|
||||
import SecondNavBar from "../../../../components/layout/SecondNavBar";
|
||||
import { useCodeSecondNavigation } from "../../../../lib/navigation/formCodeSecondNavigation";
|
||||
import { useForm } from "../../../../lib/forms";
|
||||
import { useFormMenuSteps } from "../../../../lib/navigation/formMenuSteps";
|
||||
import { useMemo } from "react";
|
||||
import { useRouter } from "next/router";
|
||||
import withAuthentication from "../../../../components/layout/WithAuthentication";
|
||||
|
||||
export default function FormPage() {
|
||||
function FormPage() {
|
||||
const router = useRouter();
|
||||
const formId = router.query.id.toString();
|
||||
const { form, isLoadingForm } = useForm(router.query.id);
|
||||
const { form, isLoadingForm, isErrorForm } = useForm(router.query.id);
|
||||
const codeSecondNavigation = useCodeSecondNavigation(formId);
|
||||
const formMenuSteps = useFormMenuSteps(formId);
|
||||
|
||||
const breadcrumbs = useMemo(() => {
|
||||
if (form) {
|
||||
return [{ name: form.name, href: "#", current: true }];
|
||||
}
|
||||
}, [form]);
|
||||
|
||||
if (isLoadingForm) {
|
||||
return <Loading />;
|
||||
}
|
||||
|
||||
const breadcrumbs = [{ name: form.name, href: "#", current: true }];
|
||||
|
||||
if (form.formType === "NOCODE") {
|
||||
if (isErrorForm) {
|
||||
return (
|
||||
<>
|
||||
<BaseLayoutAuthorized
|
||||
<MessagePage text="Unable to load this page. Maybe you don't have enough rights." />
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{form.formType === "NOCODE" ? (
|
||||
<BaseLayoutManagement
|
||||
title={`${form.name} - snoopForms`}
|
||||
breadcrumbs={breadcrumbs}
|
||||
steps={formMenuSteps}
|
||||
@@ -39,31 +50,26 @@ export default function FormPage() {
|
||||
<FullWidth>
|
||||
<Builder formId={formId} />
|
||||
</FullWidth>
|
||||
</BaseLayoutAuthorized>
|
||||
</>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<BaseLayoutAuthorized
|
||||
title={`${form.name} - snoopForms`}
|
||||
breadcrumbs={breadcrumbs}
|
||||
steps={formMenuSteps}
|
||||
currentStep="form"
|
||||
>
|
||||
<SecondNavBar navItems={codeSecondNavigation} currentItemId="formId" />
|
||||
</BaseLayoutManagement>
|
||||
) : (
|
||||
<BaseLayoutManagement
|
||||
title={`${form.name} - snoopForms`}
|
||||
breadcrumbs={breadcrumbs}
|
||||
steps={formMenuSteps}
|
||||
currentStep="form"
|
||||
>
|
||||
<SecondNavBar
|
||||
navItems={codeSecondNavigation}
|
||||
currentItemId="formId"
|
||||
/>
|
||||
|
||||
<LimitedWidth>
|
||||
<FormCode formId={formId} />
|
||||
</LimitedWidth>
|
||||
</BaseLayoutAuthorized>
|
||||
);
|
||||
}
|
||||
<LimitedWidth>
|
||||
<FormCode formId={formId} />
|
||||
</LimitedWidth>
|
||||
</BaseLayoutManagement>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export const getServerSideProps: GetServerSideProps = async ({ req, res }) => {
|
||||
const session = await getSession({ req });
|
||||
if (!session) {
|
||||
res.statusCode = 403;
|
||||
}
|
||||
return { props: {} };
|
||||
};
|
||||
export default withAuthentication(FormPage);
|
||||
|
||||
@@ -1,30 +1,30 @@
|
||||
import { GetServerSideProps } from "next";
|
||||
import { getSession } from "next-auth/react";
|
||||
import { useRouter } from "next/router";
|
||||
import { FaDiscord } from "react-icons/fa";
|
||||
import hljs from "highlight.js";
|
||||
import bash from "highlight.js/lib/languages/bash";
|
||||
import javascript from "highlight.js/lib/languages/javascript";
|
||||
import { useRouter } from "next/router";
|
||||
import { useEffect } from "react";
|
||||
import BaseLayoutAuthorized from "../../../../components/layout/BaseLayoutAuthorized";
|
||||
import { FaDiscord } from "react-icons/fa";
|
||||
import BaseLayoutManagement from "../../../../components/layout/BaseLayoutManagement";
|
||||
import LimitedWidth from "../../../../components/layout/LimitedWidth";
|
||||
import SecondNavBar from "../../../../components/layout/SecondNavBar";
|
||||
import withAuthentication from "../../../../components/layout/WithAuthentication";
|
||||
import Loading from "../../../../components/Loading";
|
||||
import MessagePage from "../../../../components/MessagePage";
|
||||
import { useForm } from "../../../../lib/forms";
|
||||
import { useCodeSecondNavigation } from "../../../../lib/navigation/formCodeSecondNavigation";
|
||||
import { useFormMenuSteps } from "../../../../lib/navigation/formMenuSteps";
|
||||
import javascript from "highlight.js/lib/languages/javascript";
|
||||
import bash from "highlight.js/lib/languages/bash";
|
||||
|
||||
hljs.registerLanguage("javascript", javascript);
|
||||
hljs.registerLanguage("bash", bash);
|
||||
|
||||
export default function ReactPage() {
|
||||
function ReactPage() {
|
||||
useEffect(() => {
|
||||
hljs.initHighlighting();
|
||||
}, []);
|
||||
|
||||
const router = useRouter();
|
||||
const formId = router.query.id.toString();
|
||||
const { form, isLoadingForm } = useForm(router.query.id);
|
||||
const { form, isLoadingForm, isErrorForm } = useForm(router.query.id);
|
||||
const codeSecondNavigation = useCodeSecondNavigation(formId);
|
||||
const formMenuSteps = useFormMenuSteps(formId);
|
||||
|
||||
@@ -32,9 +32,15 @@ export default function ReactPage() {
|
||||
return <Loading />;
|
||||
}
|
||||
|
||||
if (isErrorForm) {
|
||||
return (
|
||||
<MessagePage text="Unable to load this page. Maybe you don't have enough rights." />
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<BaseLayoutAuthorized
|
||||
<BaseLayoutManagement
|
||||
title={form.name}
|
||||
breadcrumbs={[{ name: form.name, href: "#", current: true }]}
|
||||
steps={formMenuSteps}
|
||||
@@ -87,8 +93,8 @@ export default function ReactPage() {
|
||||
<pre>
|
||||
<code className="javascript">
|
||||
{`<SnoopForm
|
||||
domain="app.snoopforms.com"
|
||||
protocol="https">
|
||||
domain="${window?.location.host}"
|
||||
protocol="${window?.location.protocol.replace(":", "")}">
|
||||
|
||||
<SnoopPage name="first">
|
||||
<SnoopElement
|
||||
@@ -147,15 +153,9 @@ export default function ReactPage() {
|
||||
</div>
|
||||
</div>
|
||||
</LimitedWidth>
|
||||
</BaseLayoutAuthorized>
|
||||
</BaseLayoutManagement>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export const getServerSideProps: GetServerSideProps = async ({ req, res }) => {
|
||||
const session = await getSession({ req });
|
||||
if (!session) {
|
||||
res.statusCode = 403;
|
||||
}
|
||||
return { props: {} };
|
||||
};
|
||||
export default withAuthentication(ReactPage);
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { GetServerSideProps } from "next";
|
||||
import { getSession } from "next-auth/react";
|
||||
import Loading from "../../../components/Loading";
|
||||
import { formHasOwnership } from "../../../lib/api";
|
||||
@@ -8,21 +7,27 @@ export default function FormIndex() {
|
||||
return <Loading />;
|
||||
}
|
||||
|
||||
export const getServerSideProps: GetServerSideProps = async ({
|
||||
req,
|
||||
res,
|
||||
params,
|
||||
}) => {
|
||||
export async function getServerSideProps({ req, params, resolvedUrl }) {
|
||||
const session = await getSession({ req });
|
||||
if (!session) {
|
||||
res.statusCode = 403;
|
||||
return { props: {} };
|
||||
return {
|
||||
redirect: {
|
||||
destination: `/auth/signin?callbackUrl=${encodeURIComponent(
|
||||
resolvedUrl
|
||||
)}`,
|
||||
statusCode: 302,
|
||||
},
|
||||
};
|
||||
}
|
||||
const formId = params.id.toString();
|
||||
const ownership = await formHasOwnership(session, formId);
|
||||
if (!ownership) {
|
||||
res.statusCode = 403;
|
||||
return { props: {} };
|
||||
return {
|
||||
redirect: {
|
||||
destination: resolvedUrl,
|
||||
statusCode: 404,
|
||||
},
|
||||
};
|
||||
}
|
||||
// redirect based on number of submissionSession
|
||||
const submissionSessionsData = await prisma.submissionSession.findMany({
|
||||
@@ -36,7 +41,6 @@ export const getServerSideProps: GetServerSideProps = async ({
|
||||
permanent: false,
|
||||
destination: `/forms/${formId}/results/summary`,
|
||||
},
|
||||
props: {},
|
||||
};
|
||||
} else {
|
||||
// redirect to /form if there isn't one submissionSession
|
||||
@@ -45,7 +49,6 @@ export const getServerSideProps: GetServerSideProps = async ({
|
||||
permanent: false,
|
||||
destination: `/forms/${formId}/form`,
|
||||
},
|
||||
props: {},
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
import { CodeIcon, PuzzleIcon } from "@heroicons/react/outline";
|
||||
import { GetServerSideProps } from "next";
|
||||
import { getSession } from "next-auth/react";
|
||||
import { useRouter } from "next/router";
|
||||
import {
|
||||
SiAirtable,
|
||||
@@ -9,10 +7,12 @@ import {
|
||||
SiSlack,
|
||||
SiZapier,
|
||||
} from "react-icons/si";
|
||||
import BaseLayoutAuthorized from "../../../components/layout/BaseLayoutAuthorized";
|
||||
import BaseLayoutManagement from "../../../components/layout/BaseLayoutManagement";
|
||||
import EmptyPageFiller from "../../../components/layout/EmptyPageFiller";
|
||||
import LimitedWidth from "../../../components/layout/LimitedWidth";
|
||||
import withAuthentication from "../../../components/layout/WithAuthentication";
|
||||
import Loading from "../../../components/Loading";
|
||||
import MessagePage from "../../../components/MessagePage";
|
||||
import { useForm } from "../../../lib/forms";
|
||||
import { useFormMenuSteps } from "../../../lib/navigation/formMenuSteps";
|
||||
import { classNames } from "../../../lib/utils";
|
||||
@@ -68,117 +68,113 @@ const libs = [
|
||||
},
|
||||
];
|
||||
|
||||
export default function PipelinesPage() {
|
||||
function PipelinesPage() {
|
||||
const router = useRouter();
|
||||
const formId = router.query.id.toString();
|
||||
const { form, isLoadingForm } = useForm(router.query.id);
|
||||
const { form, isLoadingForm, isErrorForm } = useForm(router.query.id);
|
||||
const formMenuSteps = useFormMenuSteps(formId);
|
||||
|
||||
if (isLoadingForm) {
|
||||
return <Loading />;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<BaseLayoutAuthorized
|
||||
title={`${form.name} - snoopForms`}
|
||||
breadcrumbs={[{ name: form.name, href: "#", current: true }]}
|
||||
steps={formMenuSteps}
|
||||
currentStep="pipelines"
|
||||
>
|
||||
<LimitedWidth>
|
||||
<header>
|
||||
<div className="mx-auto mt-8 max-w-7xl">
|
||||
<h1 className="text-3xl font-bold leading-tight text-ui-gray-dark">
|
||||
Data Pipelines
|
||||
</h1>
|
||||
</div>
|
||||
</header>
|
||||
<div className="my-4">
|
||||
<p className="text-ui-gray-dark">
|
||||
Pipe your data exactly where you need it. Add conditions for
|
||||
variable data piping.
|
||||
</p>
|
||||
</div>
|
||||
<EmptyPageFiller
|
||||
alertText={`No active pipelines for '${form.name}'`}
|
||||
hintText="Setup a data pipeline below."
|
||||
>
|
||||
<PuzzleIcon className="w-24 h-24 mx-auto text-ui-gray-medium stroke-thin" />
|
||||
</EmptyPageFiller>
|
||||
<div>
|
||||
<div className="my-16">
|
||||
<div>
|
||||
<h2 className="text-xl font-bold text-ui-gray-dark">
|
||||
Integrations
|
||||
</h2>
|
||||
if (isErrorForm) {
|
||||
return (
|
||||
<MessagePage text="Unable to load this page. Maybe you don't have enough rights." />
|
||||
);
|
||||
}
|
||||
|
||||
<ul
|
||||
role="list"
|
||||
className="grid grid-cols-1 gap-5 mt-3 sm:gap-6 sm:grid-cols-3 lg:grid-cols-3"
|
||||
>
|
||||
{libs.map((lib) => (
|
||||
<a
|
||||
className="flex col-span-1 rounded-md shadow-sm"
|
||||
key={lib.id}
|
||||
return (
|
||||
<BaseLayoutManagement
|
||||
title={`${form.name} - snoopForms`}
|
||||
breadcrumbs={[{ name: form.name, href: "#", current: true }]}
|
||||
steps={formMenuSteps}
|
||||
currentStep="pipelines"
|
||||
>
|
||||
<LimitedWidth>
|
||||
<header>
|
||||
<div className="mx-auto mt-8 max-w-7xl">
|
||||
<h1 className="text-3xl font-bold leading-tight text-ui-gray-dark">
|
||||
Data Pipelines
|
||||
</h1>
|
||||
</div>
|
||||
</header>
|
||||
<div className="my-4">
|
||||
<p className="text-ui-gray-dark">
|
||||
Pipe your data exactly where you need it. Add conditions for
|
||||
variable data piping.
|
||||
</p>
|
||||
</div>
|
||||
<EmptyPageFiller
|
||||
alertText={`No active pipelines for '${form.name}'`}
|
||||
hintText="Setup a data pipeline below."
|
||||
>
|
||||
<PuzzleIcon className="w-24 h-24 mx-auto text-ui-gray-medium stroke-thin" />
|
||||
</EmptyPageFiller>
|
||||
<div>
|
||||
<div className="my-16">
|
||||
<div>
|
||||
<h2 className="text-xl font-bold text-ui-gray-dark">
|
||||
Integrations
|
||||
</h2>
|
||||
|
||||
<ul
|
||||
role="list"
|
||||
className="grid grid-cols-1 gap-5 mt-3 sm:gap-6 sm:grid-cols-3 lg:grid-cols-3"
|
||||
>
|
||||
{libs.map((lib) => (
|
||||
<a
|
||||
className="flex col-span-1 rounded-md shadow-sm"
|
||||
key={lib.id}
|
||||
>
|
||||
<li
|
||||
className={classNames(
|
||||
lib.comingSoon
|
||||
? "text-ui-gray-medium"
|
||||
: "shadow-sm text-ui-gray-dark hover:text-black",
|
||||
"flex col-span-1 rounded-md w-full"
|
||||
)}
|
||||
>
|
||||
<li
|
||||
<div
|
||||
className={classNames(
|
||||
lib.comingSoon
|
||||
? "text-ui-gray-medium"
|
||||
: "shadow-sm text-ui-gray-dark hover:text-black",
|
||||
"flex col-span-1 rounded-md w-full"
|
||||
lib.bgColor,
|
||||
"flex-shrink-0 flex items-center justify-center w-20 text-white text-sm font-medium rounded-md"
|
||||
)}
|
||||
>
|
||||
<div
|
||||
<lib.icon
|
||||
className={classNames(
|
||||
lib.bgColor,
|
||||
"flex-shrink-0 flex items-center justify-center w-20 text-white text-sm font-medium rounded-md"
|
||||
lib.comingSoon
|
||||
? "text-ui-gray-medium w-8 h-8"
|
||||
: "text-white stroke-1 w-10 h-10",
|
||||
""
|
||||
)}
|
||||
>
|
||||
<lib.icon
|
||||
className={classNames(
|
||||
lib.comingSoon
|
||||
? "text-ui-gray-medium w-8 h-8"
|
||||
: "text-white stroke-1 w-10 h-10",
|
||||
""
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className={classNames(
|
||||
lib.comingSoon ? "border-dashed" : "",
|
||||
"flex items-center justify-between flex-1 truncate bg-white rounded-r-md"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className={classNames(
|
||||
lib.comingSoon ? "border-dashed" : "",
|
||||
"flex items-center justify-between flex-1 truncate bg-white rounded-r-md"
|
||||
)}
|
||||
>
|
||||
<div className="inline-flex px-4 py-8 text-sm truncate">
|
||||
<p className="">{lib.name}</p>
|
||||
{lib.comingSoon && (
|
||||
<div className="p-1 px-3 ml-3 bg-green-100 rounded-sm">
|
||||
<p className="text-xs text-black">coming soon</p>
|
||||
</div>
|
||||
)}
|
||||
>
|
||||
<div className="inline-flex px-4 py-8 text-sm truncate">
|
||||
<p className="">{lib.name}</p>
|
||||
{lib.comingSoon && (
|
||||
<div className="p-1 px-3 ml-3 bg-green-100 rounded-sm">
|
||||
<p className="text-xs text-black">
|
||||
coming soon
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</a>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</a>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</LimitedWidth>
|
||||
</BaseLayoutAuthorized>
|
||||
</>
|
||||
</div>
|
||||
</LimitedWidth>
|
||||
</BaseLayoutManagement>
|
||||
);
|
||||
}
|
||||
|
||||
export const getServerSideProps: GetServerSideProps = async ({ req, res }) => {
|
||||
const session = await getSession({ req });
|
||||
if (!session) {
|
||||
res.statusCode = 403;
|
||||
}
|
||||
return { props: {} };
|
||||
};
|
||||
export default withAuthentication(PipelinesPage);
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { GetServerSideProps } from "next";
|
||||
import { getSession } from "next-auth/react";
|
||||
import { useRouter } from "next/router";
|
||||
import { useState } from "react";
|
||||
import { toast } from "react-toastify";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import App from "../../../components/frontend/App";
|
||||
import LayoutPreview from "../../../components/layout/LayoutPreview";
|
||||
import Loading from "../../../components/Loading";
|
||||
import MessagePage from "../../../components/MessagePage";
|
||||
import { toast } from "react-toastify";
|
||||
import { useForm } from "../../../lib/forms";
|
||||
import { useNoCodeForm } from "../../../lib/noCodeForm";
|
||||
import { useRouter } from "next/router";
|
||||
import { useState } from "react";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import withAuthentication from "../../../components/layout/WithAuthentication";
|
||||
|
||||
export default function Share({}) {
|
||||
function SharePage({}) {
|
||||
const router = useRouter();
|
||||
const formId = router.query.id.toString();
|
||||
const { form, isLoadingForm } = useForm(formId);
|
||||
const { form, isLoadingForm, isErrorForm } = useForm(formId);
|
||||
const [appId, setAppId] = useState(uuidv4());
|
||||
|
||||
const { noCodeForm, isLoadingNoCodeForm } = useNoCodeForm(formId);
|
||||
@@ -27,6 +27,12 @@ export default function Share({}) {
|
||||
return <Loading />;
|
||||
}
|
||||
|
||||
if (isErrorForm) {
|
||||
return (
|
||||
<MessagePage text="Unable to load this page. Maybe you don't have enough rights." />
|
||||
);
|
||||
}
|
||||
|
||||
if (form.formType !== "NOCODE") {
|
||||
return (
|
||||
<div>Preview is only avaiblable for Forms built with No-Code-Editor</div>
|
||||
@@ -45,10 +51,4 @@ export default function Share({}) {
|
||||
);
|
||||
}
|
||||
|
||||
export const getServerSideProps: GetServerSideProps = async ({ req, res }) => {
|
||||
const session = await getSession({ req });
|
||||
if (!session) {
|
||||
res.statusCode = 403;
|
||||
}
|
||||
return { props: {} };
|
||||
};
|
||||
export default withAuthentication(SharePage);
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { GetServerSideProps } from "next";
|
||||
import { getSession } from "next-auth/react";
|
||||
import { useRouter } from "next/router";
|
||||
import BaseLayoutAuthorized from "../../../../components/layout/BaseLayoutAuthorized";
|
||||
import BaseLayoutManagement from "../../../../components/layout/BaseLayoutManagement";
|
||||
import LimitedWidth from "../../../../components/layout/LimitedWidth";
|
||||
import SecondNavBar from "../../../../components/layout/SecondNavBar";
|
||||
import Loading from "../../../../components/Loading";
|
||||
import MessagePage from "../../../../components/MessagePage";
|
||||
import ResultsInsights from "../../../../components/results/ResultsInsights";
|
||||
import SecondNavBar from "../../../../components/layout/SecondNavBar";
|
||||
import { useForm } from "../../../../lib/forms";
|
||||
import { useFormMenuSteps } from "../../../../lib/navigation/formMenuSteps";
|
||||
import { useFormResultsSecondNavigation } from "../../../../lib/navigation/formResultsSecondNavigation";
|
||||
import { useRouter } from "next/router";
|
||||
import withAuthentication from "../../../../components/layout/WithAuthentication";
|
||||
|
||||
export default function ResultsInsightsPage() {
|
||||
function ResultsInsightsPage() {
|
||||
const router = useRouter();
|
||||
const formId = router.query.id.toString();
|
||||
const { form, isLoadingForm } = useForm(router.query.id);
|
||||
const { form, isLoadingForm, isErrorForm } = useForm(router.query.id);
|
||||
const formMenuSteps = useFormMenuSteps(formId);
|
||||
const formResultsSecondNavigation = useFormResultsSecondNavigation(formId);
|
||||
|
||||
@@ -21,10 +21,16 @@ export default function ResultsInsightsPage() {
|
||||
return <Loading />;
|
||||
}
|
||||
|
||||
if (isErrorForm) {
|
||||
return (
|
||||
<MessagePage text="Unable to load this page. Maybe you don't have enough rights." />
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<BaseLayoutAuthorized
|
||||
title={`${form.name} - snoopForms`}
|
||||
breadcrumbs={[{ name: form.name, href: "#", current: true }]}
|
||||
<BaseLayoutManagement
|
||||
title={`${form?.name} - snoopForms`}
|
||||
breadcrumbs={[{ name: form?.name, href: "#", current: true }]}
|
||||
steps={formMenuSteps}
|
||||
currentStep="results"
|
||||
limitHeightScreen={true}
|
||||
@@ -37,14 +43,8 @@ export default function ResultsInsightsPage() {
|
||||
<LimitedWidth>
|
||||
<ResultsInsights formId={formId} />
|
||||
</LimitedWidth>
|
||||
</BaseLayoutAuthorized>
|
||||
</BaseLayoutManagement>
|
||||
);
|
||||
}
|
||||
|
||||
export const getServerSideProps: GetServerSideProps = async ({ req, res }) => {
|
||||
const session = await getSession({ req });
|
||||
if (!session) {
|
||||
res.statusCode = 403;
|
||||
}
|
||||
return { props: {} };
|
||||
};
|
||||
export default withAuthentication(ResultsInsightsPage);
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { GetServerSideProps } from "next";
|
||||
import { getSession } from "next-auth/react";
|
||||
import { useRouter } from "next/router";
|
||||
import BaseLayoutAuthorized from "../../../../components/layout/BaseLayoutAuthorized";
|
||||
import BaseLayoutManagement from "../../../../components/layout/BaseLayoutManagement";
|
||||
import FullWidth from "../../../../components/layout/FullWidth";
|
||||
import SecondNavBar from "../../../../components/layout/SecondNavBar";
|
||||
import Loading from "../../../../components/Loading";
|
||||
import MessagePage from "../../../../components/MessagePage";
|
||||
import ResultsResponses from "../../../../components/results/ResultsResponses";
|
||||
import SecondNavBar from "../../../../components/layout/SecondNavBar";
|
||||
import { useForm } from "../../../../lib/forms";
|
||||
import { useFormMenuSteps } from "../../../../lib/navigation/formMenuSteps";
|
||||
import { useFormResultsSecondNavigation } from "../../../../lib/navigation/formResultsSecondNavigation";
|
||||
import { useRouter } from "next/router";
|
||||
import withAuthentication from "../../../../components/layout/WithAuthentication";
|
||||
|
||||
export default function ResultsResponsesPage() {
|
||||
function ResultsResponsesPage() {
|
||||
const router = useRouter();
|
||||
const formId = router.query.id.toString();
|
||||
const { form, isLoadingForm } = useForm(router.query.id);
|
||||
const { form, isLoadingForm, isErrorForm } = useForm(router.query.id);
|
||||
const formMenuSteps = useFormMenuSteps(formId);
|
||||
const formResultsSecondNavigation = useFormResultsSecondNavigation(formId);
|
||||
|
||||
@@ -21,8 +21,14 @@ export default function ResultsResponsesPage() {
|
||||
return <Loading />;
|
||||
}
|
||||
|
||||
if (isErrorForm) {
|
||||
return (
|
||||
<MessagePage text="Unable to load this page. Maybe you don't have enough rights." />
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<BaseLayoutAuthorized
|
||||
<BaseLayoutManagement
|
||||
title={`${form.name} - snoopForms`}
|
||||
breadcrumbs={[{ name: form.name, href: "#", current: true }]}
|
||||
steps={formMenuSteps}
|
||||
@@ -37,14 +43,8 @@ export default function ResultsResponsesPage() {
|
||||
<FullWidth>
|
||||
<ResultsResponses formId={formId} />
|
||||
</FullWidth>
|
||||
</BaseLayoutAuthorized>
|
||||
</BaseLayoutManagement>
|
||||
);
|
||||
}
|
||||
|
||||
export const getServerSideProps: GetServerSideProps = async ({ req, res }) => {
|
||||
const session = await getSession({ req });
|
||||
if (!session) {
|
||||
res.statusCode = 403;
|
||||
}
|
||||
return { props: {} };
|
||||
};
|
||||
export default withAuthentication(ResultsResponsesPage);
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { GetServerSideProps } from "next";
|
||||
import { getSession } from "next-auth/react";
|
||||
import { useRouter } from "next/router";
|
||||
import BaseLayoutAuthorized from "../../../../components/layout/BaseLayoutAuthorized";
|
||||
import BaseLayoutManagement from "../../../../components/layout/BaseLayoutManagement";
|
||||
import LimitedWidth from "../../../../components/layout/LimitedWidth";
|
||||
import SecondNavBar from "../../../../components/layout/SecondNavBar";
|
||||
import Loading from "../../../../components/Loading";
|
||||
import MessagePage from "../../../../components/MessagePage";
|
||||
import ResultsSummary from "../../../../components/results/ResultsSummary";
|
||||
import SecondNavBar from "../../../../components/layout/SecondNavBar";
|
||||
import { useForm } from "../../../../lib/forms";
|
||||
import { useFormMenuSteps } from "../../../../lib/navigation/formMenuSteps";
|
||||
import { useFormResultsSecondNavigation } from "../../../../lib/navigation/formResultsSecondNavigation";
|
||||
import { useRouter } from "next/router";
|
||||
import withAuthentication from "../../../../components/layout/WithAuthentication";
|
||||
|
||||
export default function ResultsSummaryPage() {
|
||||
function ResultsSummaryPage() {
|
||||
const router = useRouter();
|
||||
const formId = router.query.id.toString();
|
||||
const { form, isLoadingForm } = useForm(router.query.id);
|
||||
const { form, isLoadingForm, isErrorForm } = useForm(router.query.id);
|
||||
const formMenuSteps = useFormMenuSteps(formId);
|
||||
const formResultsSecondNavigation = useFormResultsSecondNavigation(formId);
|
||||
|
||||
@@ -21,8 +21,14 @@ export default function ResultsSummaryPage() {
|
||||
return <Loading />;
|
||||
}
|
||||
|
||||
if (isErrorForm) {
|
||||
return (
|
||||
<MessagePage text="Unable to load this page. Maybe you don't have enough rights." />
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<BaseLayoutAuthorized
|
||||
<BaseLayoutManagement
|
||||
title={`${form.name} - snoopForms`}
|
||||
breadcrumbs={[{ name: form.name, href: "#", current: true }]}
|
||||
steps={formMenuSteps}
|
||||
@@ -36,14 +42,8 @@ export default function ResultsSummaryPage() {
|
||||
<LimitedWidth>
|
||||
<ResultsSummary formId={formId} />
|
||||
</LimitedWidth>
|
||||
</BaseLayoutAuthorized>
|
||||
</BaseLayoutManagement>
|
||||
);
|
||||
}
|
||||
|
||||
export const getServerSideProps: GetServerSideProps = async ({ req, res }) => {
|
||||
const session = await getSession({ req });
|
||||
if (!session) {
|
||||
res.statusCode = 403;
|
||||
}
|
||||
return { props: {} };
|
||||
};
|
||||
export default withAuthentication(ResultsSummaryPage);
|
||||
|
||||
@@ -1,25 +1,26 @@
|
||||
import FormList from "../../components/FormList";
|
||||
import BaseLayoutAuthorized from "../../components/layout/BaseLayoutAuthorized";
|
||||
import BaseLayoutManagement from "../../components/layout/BaseLayoutManagement";
|
||||
import LimitedWidth from "../../components/layout/LimitedWidth";
|
||||
import withAuthentication from "../../components/layout/WithAuthentication";
|
||||
import Loading from "../../components/Loading";
|
||||
import { useForms } from "../../lib/forms";
|
||||
|
||||
export default function Forms({}) {
|
||||
function FormsPage({}) {
|
||||
const { isLoadingForms } = useForms();
|
||||
|
||||
if (isLoadingForms) {
|
||||
<Loading />;
|
||||
}
|
||||
return (
|
||||
<>
|
||||
<BaseLayoutAuthorized
|
||||
title={"Forms - snoopForms"}
|
||||
breadcrumbs={[{ name: "My Forms", href: "#", current: true }]}
|
||||
>
|
||||
<LimitedWidth>
|
||||
<FormList />
|
||||
</LimitedWidth>
|
||||
</BaseLayoutAuthorized>
|
||||
</>
|
||||
<BaseLayoutManagement
|
||||
title={"Forms - snoopForms"}
|
||||
breadcrumbs={[{ name: "My Forms", href: "#", current: true }]}
|
||||
>
|
||||
<LimitedWidth>
|
||||
<FormList />
|
||||
</LimitedWidth>
|
||||
</BaseLayoutManagement>
|
||||
);
|
||||
}
|
||||
|
||||
export default withAuthentication(FormsPage);
|
||||
|
||||
Reference in New Issue
Block a user