mirror of
https://github.com/formbricks/formbricks.git
synced 2025-12-27 08:50:38 -06:00
add posthog integration (#7)
* add possibility to track events with posthog by setting environment variables POSTHOG_API_KEY and POSTHOG_API_HOST
This commit is contained in:
@@ -6,6 +6,7 @@ import { Fragment, useState } from "react";
|
||||
import { BsPlus } from "react-icons/bs";
|
||||
import { createForm } from "../../lib/forms";
|
||||
import { createNoCodeForm } from "../../lib/noCodeForm";
|
||||
import { trackPosthogEvent } from "../../lib/posthog";
|
||||
import { classNames } from "../../lib/utils";
|
||||
import StandardButton from "../StandardButton";
|
||||
|
||||
@@ -47,6 +48,7 @@ export default function NewFormModal({
|
||||
if (form.formType === "NOCODE") {
|
||||
await createNoCodeForm(form.id);
|
||||
}
|
||||
trackPosthogEvent("newForm", { formType: form.formType });
|
||||
router.push(`/forms/${form.id}/form`);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { SnoopElement, SnoopForm, SnoopPage } from "@snoopforms/react";
|
||||
import { useMemo } from "react";
|
||||
import { trackPosthogEvent } from "../../lib/posthog";
|
||||
import Loading from "../Loading";
|
||||
|
||||
export default function App({ id = "", formId, blocks, localOnly = false }) {
|
||||
@@ -41,6 +42,9 @@ export default function App({ id = "", formId, blocks, localOnly = false }) {
|
||||
formId={formId}
|
||||
localOnly={localOnly}
|
||||
className="w-full max-w-3xl mx-auto space-y-6"
|
||||
onSubmit={() => {
|
||||
trackPosthogEvent("submitForm", { formId });
|
||||
}}
|
||||
>
|
||||
{pages.map((page) => (
|
||||
<SnoopPage key={page.id} name={page.id}>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { signIn, useSession } from "next-auth/react";
|
||||
import Head from "next/head";
|
||||
import { useEffect, useState } from "react";
|
||||
import { usePosthog } from "../../lib/posthog";
|
||||
import { classNames } from "../../lib/utils";
|
||||
import Loading from "../Loading";
|
||||
import MenuBreadcrumbs from "./MenuBreadcrumbs";
|
||||
@@ -40,6 +41,8 @@ export default function BaseLayoutAuthorized({
|
||||
}
|
||||
}, [session, status]);
|
||||
|
||||
usePosthog(session?.user?.email);
|
||||
|
||||
if (status === "loading" || loading) {
|
||||
return <Loading />;
|
||||
}
|
||||
|
||||
14
components/layout/BaseLayoutUnauthorized.tsx
Normal file
14
components/layout/BaseLayoutUnauthorized.tsx
Normal file
@@ -0,0 +1,14 @@
|
||||
import Head from "next/head";
|
||||
import { usePosthog } from "../../lib/posthog";
|
||||
|
||||
export default function BaseLayoutUnauthorized({ title, children }) {
|
||||
usePosthog(null, true);
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>{title}</title>
|
||||
</Head>
|
||||
{children}
|
||||
</>
|
||||
);
|
||||
}
|
||||
51
lib/posthog.ts
Normal file
51
lib/posthog.ts
Normal file
@@ -0,0 +1,51 @@
|
||||
import { useRouter } from "next/router";
|
||||
import getConfig from "next/config";
|
||||
import posthog from "posthog-js";
|
||||
import { useEffect } from "react";
|
||||
|
||||
const { publicRuntimeConfig } = getConfig();
|
||||
const enabled =
|
||||
publicRuntimeConfig.posthogApiKey && publicRuntimeConfig.posthogApiHost;
|
||||
|
||||
export const usePosthog = (userId?: string, anonymous = false) => {
|
||||
const router = useRouter();
|
||||
|
||||
useEffect(() => {
|
||||
if (enabled && (userId || anonymous)) {
|
||||
// Init PostHog
|
||||
posthog.init(publicRuntimeConfig.posthogApiKey, {
|
||||
api_host: publicRuntimeConfig.posthogApiHost,
|
||||
loaded: function (posthog) {
|
||||
if (process.env.NODE_ENV === "development")
|
||||
posthog.opt_out_capturing();
|
||||
if (userId && !anonymous) {
|
||||
posthog.identify(userId);
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
// Track page views
|
||||
const handleRouteChange = () => {
|
||||
if (enabled && (userId || anonymous)) {
|
||||
posthog.capture("$pageview");
|
||||
}
|
||||
};
|
||||
router.events.on("routeChangeComplete", handleRouteChange);
|
||||
|
||||
return () => {
|
||||
router.events.off("routeChangeComplete", handleRouteChange);
|
||||
};
|
||||
}, [router.events, userId, anonymous]);
|
||||
};
|
||||
|
||||
export const trackPosthogEvent = (eventName: string, attributes: object) => {
|
||||
if (enabled) {
|
||||
posthog.capture(eventName, attributes);
|
||||
}
|
||||
};
|
||||
|
||||
export const identifyPoshogUser = (userId: string) => {
|
||||
if (enabled) {
|
||||
posthog.identify(userId);
|
||||
}
|
||||
};
|
||||
@@ -16,6 +16,8 @@ const nextConfig = {
|
||||
},
|
||||
publicRuntimeConfig: {
|
||||
// Will be available on both server and client
|
||||
posthogApiHost: process.env.POSTHOG_API_HOST,
|
||||
posthogApiKey: process.env.POSTHOG_API_KEY,
|
||||
},
|
||||
async redirects() {
|
||||
return [
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
"next-auth": "^4.10.1",
|
||||
"nextjs-cors": "^2.1.1",
|
||||
"nodemailer": "^6.7.7",
|
||||
"posthog-js": "^1.26.0",
|
||||
"react": "17.0.2",
|
||||
"react-dom": "17.0.2",
|
||||
"react-icons": "^4.4.0",
|
||||
|
||||
@@ -3,6 +3,7 @@ import { signIn } from "next-auth/react";
|
||||
import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
import { useRouter } from "next/router";
|
||||
import BaseLayoutUnauthorized from "../../components/layout/BaseLayoutUnauthorized";
|
||||
|
||||
export default function SignInPage() {
|
||||
const router = useRouter();
|
||||
@@ -22,107 +23,109 @@ export default function SignInPage() {
|
||||
);
|
||||
};
|
||||
return (
|
||||
<div className="flex min-h-screen bg-ui-gray-light">
|
||||
<div className="flex flex-col justify-center flex-1 px-4 py-12 mx-auto sm:px-6 lg:flex-none lg:px-20 xl:px-24">
|
||||
{error && (
|
||||
<div className="absolute p-4 rounded-md top-10 bg-red-50">
|
||||
<div className="flex">
|
||||
<div className="flex-shrink-0">
|
||||
<XCircleIcon
|
||||
className="w-5 h-5 text-red-400"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</div>
|
||||
<div className="ml-3">
|
||||
<h3 className="text-sm font-medium text-red-800">
|
||||
An error occurred when logging you in
|
||||
</h3>
|
||||
<div className="mt-2 text-sm text-red-700">
|
||||
<p className="space-y-1 whitespace-pre-wrap">{error}</p>
|
||||
<BaseLayoutUnauthorized title="Sign in">
|
||||
<div className="flex min-h-screen bg-ui-gray-light">
|
||||
<div className="flex flex-col justify-center flex-1 px-4 py-12 mx-auto sm:px-6 lg:flex-none lg:px-20 xl:px-24">
|
||||
{error && (
|
||||
<div className="absolute p-4 rounded-md top-10 bg-red-50">
|
||||
<div className="flex">
|
||||
<div className="flex-shrink-0">
|
||||
<XCircleIcon
|
||||
className="w-5 h-5 text-red-400"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</div>
|
||||
<div className="ml-3">
|
||||
<h3 className="text-sm font-medium text-red-800">
|
||||
An error occurred when logging you in
|
||||
</h3>
|
||||
<div className="mt-2 text-sm text-red-700">
|
||||
<p className="space-y-1 whitespace-pre-wrap">{error}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
)}
|
||||
|
||||
<div className="w-full max-w-sm p-8 mx-auto bg-white rounded-xl shadow-cont lg:w-96">
|
||||
<div>
|
||||
<Image
|
||||
src="/img/snoopforms-logo.svg"
|
||||
alt="snoopForms logo"
|
||||
width={500}
|
||||
height={89}
|
||||
/>
|
||||
</div>
|
||||
<div className="w-full max-w-sm p-8 mx-auto bg-white rounded-xl shadow-cont lg:w-96">
|
||||
<div>
|
||||
<Image
|
||||
src="/img/snoopforms-logo.svg"
|
||||
alt="snoopForms logo"
|
||||
width={500}
|
||||
height={89}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="mt-8">
|
||||
<div className="mt-6">
|
||||
<form
|
||||
onSubmit={handleSubmit}
|
||||
method="post"
|
||||
action="/api/auth/callback/credentials"
|
||||
className="space-y-6"
|
||||
>
|
||||
<div>
|
||||
<label
|
||||
htmlFor="email"
|
||||
className="block text-sm font-medium text-ui-gray-dark"
|
||||
>
|
||||
Email address
|
||||
</label>
|
||||
<div className="mt-1">
|
||||
<input
|
||||
id="email"
|
||||
name="email"
|
||||
type="email"
|
||||
autoComplete="email"
|
||||
required
|
||||
className="block w-full px-3 py-2 border rounded-md shadow-sm appearance-none placeholder-ui-gray-medium border-ui-gray-medium focus:outline-none focus:ring-red-500 focus:border-red-500 sm:text-sm"
|
||||
/>
|
||||
<div className="mt-8">
|
||||
<div className="mt-6">
|
||||
<form
|
||||
onSubmit={handleSubmit}
|
||||
method="post"
|
||||
action="/api/auth/callback/credentials"
|
||||
className="space-y-6"
|
||||
>
|
||||
<div>
|
||||
<label
|
||||
htmlFor="email"
|
||||
className="block text-sm font-medium text-ui-gray-dark"
|
||||
>
|
||||
Email address
|
||||
</label>
|
||||
<div className="mt-1">
|
||||
<input
|
||||
id="email"
|
||||
name="email"
|
||||
type="email"
|
||||
autoComplete="email"
|
||||
required
|
||||
className="block w-full px-3 py-2 border rounded-md shadow-sm appearance-none placeholder-ui-gray-medium border-ui-gray-medium focus:outline-none focus:ring-red-500 focus:border-red-500 sm:text-sm ph-no-capture"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<label
|
||||
htmlFor="email"
|
||||
className="block text-sm font-medium text-ui-gray-dark"
|
||||
>
|
||||
Password
|
||||
</label>
|
||||
<div className="mt-1">
|
||||
<input
|
||||
id="password"
|
||||
name="password"
|
||||
type="password"
|
||||
autoComplete="current-password"
|
||||
required
|
||||
className="block w-full px-3 py-2 border rounded-md shadow-sm appearance-none placeholder-ui-gray-medium border-ui-gray-medium focus:outline-none focus:ring-red-500 focus:border-red-500 sm:text-sm"
|
||||
/>
|
||||
<div>
|
||||
<label
|
||||
htmlFor="email"
|
||||
className="block text-sm font-medium text-ui-gray-dark"
|
||||
>
|
||||
Password
|
||||
</label>
|
||||
<div className="mt-1">
|
||||
<input
|
||||
id="password"
|
||||
name="password"
|
||||
type="password"
|
||||
autoComplete="current-password"
|
||||
required
|
||||
className="block w-full px-3 py-2 border rounded-md shadow-sm appearance-none placeholder-ui-gray-medium border-ui-gray-medium focus:outline-none focus:ring-red-500 focus:border-red-500 sm:text-sm ph-no-capture"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<button
|
||||
type="submit"
|
||||
className="flex justify-center w-full px-4 py-2 text-sm font-medium text-white border border-transparent rounded-md shadow-sm bg-red hover:bg-red-600 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500"
|
||||
>
|
||||
Sign in
|
||||
</button>
|
||||
<div className="mt-3 text-center">
|
||||
<Link href="/auth/signup">
|
||||
<a
|
||||
href=""
|
||||
className="text-xs text-red hover:text-red-600"
|
||||
>
|
||||
Create an account
|
||||
</a>
|
||||
</Link>
|
||||
<div>
|
||||
<button
|
||||
type="submit"
|
||||
className="flex justify-center w-full px-4 py-2 text-sm font-medium text-white border border-transparent rounded-md shadow-sm bg-red hover:bg-red-600 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500"
|
||||
>
|
||||
Sign in
|
||||
</button>
|
||||
<div className="mt-3 text-center">
|
||||
<Link href="/auth/signup">
|
||||
<a
|
||||
href=""
|
||||
className="text-xs text-red hover:text-red-600"
|
||||
>
|
||||
Create an account
|
||||
</a>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</BaseLayoutUnauthorized>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
import { useRouter } from "next/router";
|
||||
import { useState } from "react";
|
||||
import BaseLayoutUnauthorized from "../../components/layout/BaseLayoutUnauthorized";
|
||||
import { createUser } from "../../lib/users";
|
||||
|
||||
export default function SignUpPage() {
|
||||
@@ -28,137 +29,139 @@ export default function SignUpPage() {
|
||||
}
|
||||
};
|
||||
return (
|
||||
<div className="flex min-h-screen bg-ui-gray-light">
|
||||
<div className="flex flex-col justify-center flex-1 px-4 py-12 mx-auto sm:px-6 lg:flex-none lg:px-20 xl:px-24">
|
||||
{error && (
|
||||
<div className="absolute p-4 rounded-md top-10 bg-red-50">
|
||||
<div className="flex">
|
||||
<div className="flex-shrink-0">
|
||||
<XCircleIcon
|
||||
className="w-5 h-5 text-red-400"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</div>
|
||||
<div className="ml-3">
|
||||
<h3 className="text-sm font-medium text-red-800">
|
||||
An error occurred when logging you in
|
||||
</h3>
|
||||
<div className="mt-2 text-sm text-red-700">
|
||||
<p className="space-y-1 whitespace-pre-wrap">{error}</p>
|
||||
<BaseLayoutUnauthorized title="Sign up">
|
||||
<div className="flex min-h-screen bg-ui-gray-light">
|
||||
<div className="flex flex-col justify-center flex-1 px-4 py-12 mx-auto sm:px-6 lg:flex-none lg:px-20 xl:px-24">
|
||||
{error && (
|
||||
<div className="absolute p-4 rounded-md top-10 bg-red-50">
|
||||
<div className="flex">
|
||||
<div className="flex-shrink-0">
|
||||
<XCircleIcon
|
||||
className="w-5 h-5 text-red-400"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</div>
|
||||
<div className="ml-3">
|
||||
<h3 className="text-sm font-medium text-red-800">
|
||||
An error occurred when logging you in
|
||||
</h3>
|
||||
<div className="mt-2 text-sm text-red-700">
|
||||
<p className="space-y-1 whitespace-pre-wrap">{error}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
)}
|
||||
|
||||
<div className="w-full max-w-sm p-8 mx-auto bg-white rounded-xl shadow-cont lg:w-96">
|
||||
<div>
|
||||
<Image
|
||||
src="/img/snoopforms-logo.svg"
|
||||
alt="snoopForms logo"
|
||||
width={500}
|
||||
height={89}
|
||||
/>
|
||||
</div>
|
||||
<div className="w-full max-w-sm p-8 mx-auto bg-white rounded-xl shadow-cont lg:w-96">
|
||||
<div>
|
||||
<Image
|
||||
src="/img/snoopforms-logo.svg"
|
||||
alt="snoopForms logo"
|
||||
width={500}
|
||||
height={89}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="mt-8">
|
||||
<p className="text-sm text-center text-gray-600">
|
||||
Create your own forms and collect submissions by creating a
|
||||
snoopForms account.
|
||||
</p>
|
||||
<div className="mt-6">
|
||||
<form onSubmit={handleSubmit} className="space-y-6">
|
||||
<div>
|
||||
<label
|
||||
htmlFor="firstname"
|
||||
className="block text-sm font-medium text-ui-gray-dark"
|
||||
>
|
||||
First name
|
||||
</label>
|
||||
<div className="mt-1">
|
||||
<input
|
||||
id="firstname"
|
||||
name="firstname"
|
||||
type="text"
|
||||
autoComplete="given-name"
|
||||
required
|
||||
className="block w-full px-3 py-2 border rounded-md shadow-sm appearance-none placeholder-ui-gray-medium border-ui-gray-medium focus:outline-none focus:ring-red-500 focus:border-red-500 sm:text-sm"
|
||||
/>
|
||||
<div className="mt-8">
|
||||
<p className="text-sm text-center text-gray-600">
|
||||
Create your own forms and collect submissions by creating a
|
||||
snoopForms account.
|
||||
</p>
|
||||
<div className="mt-6">
|
||||
<form onSubmit={handleSubmit} className="space-y-6">
|
||||
<div>
|
||||
<label
|
||||
htmlFor="firstname"
|
||||
className="block text-sm font-medium text-ui-gray-dark"
|
||||
>
|
||||
First name
|
||||
</label>
|
||||
<div className="mt-1">
|
||||
<input
|
||||
id="firstname"
|
||||
name="firstname"
|
||||
type="text"
|
||||
autoComplete="given-name"
|
||||
required
|
||||
className="block w-full px-3 py-2 border rounded-md shadow-sm appearance-none placeholder-ui-gray-medium border-ui-gray-medium focus:outline-none focus:ring-red-500 focus:border-red-500 sm:text-sm ph-no-capture"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<label
|
||||
htmlFor="lastname"
|
||||
className="block text-sm font-medium text-ui-gray-dark"
|
||||
>
|
||||
Last name
|
||||
</label>
|
||||
<div className="mt-1">
|
||||
<input
|
||||
id="lastname"
|
||||
name="lastname"
|
||||
type="text"
|
||||
autoComplete="family-name"
|
||||
required
|
||||
className="block w-full px-3 py-2 border rounded-md shadow-sm appearance-none placeholder-ui-gray-medium border-ui-gray-medium focus:outline-none focus:ring-red-500 focus:border-red-500 sm:text-sm"
|
||||
/>
|
||||
<div>
|
||||
<label
|
||||
htmlFor="lastname"
|
||||
className="block text-sm font-medium text-ui-gray-dark"
|
||||
>
|
||||
Last name
|
||||
</label>
|
||||
<div className="mt-1">
|
||||
<input
|
||||
id="lastname"
|
||||
name="lastname"
|
||||
type="text"
|
||||
autoComplete="family-name"
|
||||
required
|
||||
className="block w-full px-3 py-2 border rounded-md shadow-sm appearance-none placeholder-ui-gray-medium border-ui-gray-medium focus:outline-none focus:ring-red-500 focus:border-red-500 sm:text-sm ph-no-capture"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<label
|
||||
htmlFor="email"
|
||||
className="block text-sm font-medium text-ui-gray-dark"
|
||||
>
|
||||
Email address
|
||||
</label>
|
||||
<div className="mt-1">
|
||||
<input
|
||||
id="email"
|
||||
name="email"
|
||||
type="email"
|
||||
autoComplete="email"
|
||||
required
|
||||
className="block w-full px-3 py-2 border rounded-md shadow-sm appearance-none placeholder-ui-gray-medium border-ui-gray-medium focus:outline-none focus:ring-red-500 focus:border-red-500 sm:text-sm"
|
||||
/>
|
||||
<div>
|
||||
<label
|
||||
htmlFor="email"
|
||||
className="block text-sm font-medium text-ui-gray-dark"
|
||||
>
|
||||
Email address
|
||||
</label>
|
||||
<div className="mt-1">
|
||||
<input
|
||||
id="email"
|
||||
name="email"
|
||||
type="email"
|
||||
autoComplete="email"
|
||||
required
|
||||
className="block w-full px-3 py-2 border rounded-md shadow-sm appearance-none placeholder-ui-gray-medium border-ui-gray-medium focus:outline-none focus:ring-red-500 focus:border-red-500 sm:text-sm ph-no-capture"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<label
|
||||
htmlFor="email"
|
||||
className="block text-sm font-medium text-ui-gray-dark"
|
||||
>
|
||||
Password
|
||||
</label>
|
||||
<div className="mt-1">
|
||||
<input
|
||||
id="password"
|
||||
name="password"
|
||||
type="password"
|
||||
required
|
||||
className="block w-full px-3 py-2 border rounded-md shadow-sm appearance-none placeholder-ui-gray-medium border-ui-gray-medium focus:outline-none focus:ring-red-500 focus:border-red-500 sm:text-sm"
|
||||
/>
|
||||
<div>
|
||||
<label
|
||||
htmlFor="email"
|
||||
className="block text-sm font-medium text-ui-gray-dark"
|
||||
>
|
||||
Password
|
||||
</label>
|
||||
<div className="mt-1">
|
||||
<input
|
||||
id="password"
|
||||
name="password"
|
||||
type="password"
|
||||
required
|
||||
className="block w-full px-3 py-2 border rounded-md shadow-sm appearance-none placeholder-ui-gray-medium border-ui-gray-medium focus:outline-none focus:ring-red-500 focus:border-red-500 sm:text-sm ph-no-capture"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<button
|
||||
type="submit"
|
||||
className="flex justify-center w-full px-4 py-2 text-sm font-medium text-white border border-transparent rounded-md shadow-sm bg-red hover:bg-red-600 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500"
|
||||
>
|
||||
Sign up
|
||||
</button>
|
||||
<div className="mt-3 text-xs text-center text-gray-600">
|
||||
Already have an account?{" "}
|
||||
<Link href="/auth/signin">
|
||||
<a className="text-red hover:text-red-600">Log in.</a>
|
||||
</Link>
|
||||
<div>
|
||||
<button
|
||||
type="submit"
|
||||
className="flex justify-center w-full px-4 py-2 text-sm font-medium text-white border border-transparent rounded-md shadow-sm bg-red hover:bg-red-600 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500"
|
||||
>
|
||||
Sign up
|
||||
</button>
|
||||
<div className="mt-3 text-xs text-center text-gray-600">
|
||||
Already have an account?{" "}
|
||||
<Link href="/auth/signin">
|
||||
<a className="text-red hover:text-red-600">Log in.</a>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</BaseLayoutUnauthorized>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import Image from "next/image";
|
||||
import { useRouter } from "next/router";
|
||||
import { toast } from "react-toastify";
|
||||
import BaseLayoutUnauthorized from "../../components/layout/BaseLayoutUnauthorized";
|
||||
import { resendVerificationEmail } from "../../lib/users";
|
||||
|
||||
interface props {
|
||||
@@ -20,49 +21,51 @@ export default function SignIn({}: props) {
|
||||
}
|
||||
};
|
||||
return (
|
||||
<div className="flex min-h-screen bg-ui-gray-light">
|
||||
<div className="flex flex-col justify-center flex-1 px-4 py-12 mx-auto sm:px-6 lg:flex-none lg:px-20 xl:px-24">
|
||||
<div className="w-full max-w-sm p-8 mx-auto bg-white rounded-xl shadow-cont lg:w-96">
|
||||
<div>
|
||||
<Image
|
||||
src="/img/snoopforms-logo.svg"
|
||||
alt="snoopForms logo"
|
||||
width={500}
|
||||
height={89}
|
||||
/>
|
||||
</div>
|
||||
<BaseLayoutUnauthorized title="Verify your email">
|
||||
<div className="flex min-h-screen bg-ui-gray-light">
|
||||
<div className="flex flex-col justify-center flex-1 px-4 py-12 mx-auto sm:px-6 lg:flex-none lg:px-20 xl:px-24">
|
||||
<div className="w-full max-w-sm p-8 mx-auto bg-white rounded-xl shadow-cont lg:w-96">
|
||||
<div>
|
||||
<Image
|
||||
src="/img/snoopforms-logo.svg"
|
||||
alt="snoopForms logo"
|
||||
width={500}
|
||||
height={89}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="mt-8">
|
||||
{email ? (
|
||||
<>
|
||||
<h1 className="mb-4 font-bold text-center leading-2">
|
||||
Please verify your email address
|
||||
</h1>
|
||||
<p className="text-center">
|
||||
We have sent you an email to the address{" "}
|
||||
<span className="italic">{router.query.email}</span>. Please
|
||||
click the link in the email to activate your account.
|
||||
</p>
|
||||
<hr className="my-4" />
|
||||
<p className="text-xs text-center">
|
||||
You didn't receive an email or your link expired?
|
||||
<br />
|
||||
Click the button below to request a new email.
|
||||
</p>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => requestVerificationEmail()}
|
||||
className="flex justify-center w-full px-4 py-2 mt-5 text-sm font-medium text-gray-600 bg-white border border-gray-400 rounded-md shadow-sm hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500"
|
||||
>
|
||||
Request a new verification mail
|
||||
</button>{" "}
|
||||
</>
|
||||
) : (
|
||||
<p className="text-center">No E-Mail Address provided</p>
|
||||
)}
|
||||
<div className="mt-8">
|
||||
{email ? (
|
||||
<>
|
||||
<h1 className="mb-4 font-bold text-center leading-2">
|
||||
Please verify your email address
|
||||
</h1>
|
||||
<p className="text-center">
|
||||
We have sent you an email to the address{" "}
|
||||
<span className="italic">{router.query.email}</span>. Please
|
||||
click the link in the email to activate your account.
|
||||
</p>
|
||||
<hr className="my-4" />
|
||||
<p className="text-xs text-center">
|
||||
You didn't receive an email or your link expired?
|
||||
<br />
|
||||
Click the button below to request a new email.
|
||||
</p>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => requestVerificationEmail()}
|
||||
className="flex justify-center w-full px-4 py-2 mt-5 text-sm font-medium text-gray-600 bg-white border border-gray-400 rounded-md shadow-sm hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500"
|
||||
>
|
||||
Request a new verification mail
|
||||
</button>{" "}
|
||||
</>
|
||||
) : (
|
||||
<p className="text-center">No E-Mail Address provided</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</BaseLayoutUnauthorized>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { signIn } from "next-auth/react";
|
||||
import { useRouter } from "next/router";
|
||||
import { useEffect } from "react";
|
||||
import BaseLayoutUnauthorized from "../../components/layout/BaseLayoutUnauthorized";
|
||||
|
||||
export default function Verify() {
|
||||
const router = useRouter();
|
||||
@@ -14,14 +15,16 @@ export default function Verify() {
|
||||
}
|
||||
}, [token]);
|
||||
return (
|
||||
<div className="flex min-h-screen bg-ui-gray-light">
|
||||
<div className="flex flex-col justify-center flex-1 px-4 py-12 mx-auto sm:px-6 lg:flex-none lg:px-20 xl:px-24">
|
||||
<div className="w-full max-w-sm p-8 mx-auto bg-white rounded-xl shadow-cont lg:w-96">
|
||||
<p className="text-center">
|
||||
{!token ? "No Token provided" : "Verifying..."}
|
||||
</p>
|
||||
<BaseLayoutUnauthorized title="Verifying your email">
|
||||
<div className="flex min-h-screen bg-ui-gray-light">
|
||||
<div className="flex flex-col justify-center flex-1 px-4 py-12 mx-auto sm:px-6 lg:flex-none lg:px-20 xl:px-24">
|
||||
<div className="w-full max-w-sm p-8 mx-auto bg-white rounded-xl shadow-cont lg:w-96">
|
||||
<p className="text-center">
|
||||
{!token ? "No Token provided" : "Verifying..."}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</BaseLayoutUnauthorized>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { GetServerSideProps } from "next";
|
||||
import { getSession } from "next-auth/react";
|
||||
import Head from "next/head";
|
||||
import { useRouter } from "next/router";
|
||||
import App from "../../components/frontend/App";
|
||||
import BaseLayoutUnauthorized from "../../components/layout/BaseLayoutUnauthorized";
|
||||
import Loading from "../../components/Loading";
|
||||
import { useNoCodeFormPublic } from "../../lib/noCodeForm";
|
||||
import { usePosthog } from "../../lib/posthog";
|
||||
|
||||
export default function Share({}) {
|
||||
const router = useRouter();
|
||||
@@ -12,6 +13,8 @@ export default function Share({}) {
|
||||
const { noCodeForm, isLoadingNoCodeForm, isErrorNoCodeForm } =
|
||||
useNoCodeFormPublic(formId);
|
||||
|
||||
usePosthog(null, true);
|
||||
|
||||
if (isErrorNoCodeForm) {
|
||||
return <p>Not found</p>;
|
||||
}
|
||||
@@ -21,12 +24,9 @@ export default function Share({}) {
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>SnoopForms</title>
|
||||
</Head>
|
||||
<BaseLayoutUnauthorized title="snoopForms">
|
||||
<App formId={formId} blocks={noCodeForm.blocks} />
|
||||
</>
|
||||
</BaseLayoutUnauthorized>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
24
yarn.lock
24
yarn.lock
@@ -257,6 +257,11 @@
|
||||
resolved "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.1.3.tgz"
|
||||
integrity sha512-WiBSI6JBIhC6LRIsB2Kwh8DsGTlbBU+mLRxJmAe3LjHTdkDpwIbEOZgoXBbZilk/vlfjK8i6nKRAvIRn1XaIMw==
|
||||
|
||||
"@sentry/types@^7.2.0":
|
||||
version "7.7.0"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/types/-/types-7.7.0.tgz#dd6bd3d119d7efea0e85dbaa4b17de1c22b63c7a"
|
||||
integrity sha512-4x8O7uerSGLnYC10krHl9t8h7xXHn5FextqKYbTCXCnx2hC8D+9lz8wcbQAFo0d97wiUYqI8opmEgFVGx7c5hQ==
|
||||
|
||||
"@snoopforms/react@^0.0.4":
|
||||
version "0.0.4"
|
||||
resolved "https://registry.yarnpkg.com/@snoopforms/react/-/react-0.0.4.tgz#256c2285d0ef540c6ba4bde8d9a096d02e576fff"
|
||||
@@ -1209,6 +1214,11 @@ fastq@^1.6.0:
|
||||
dependencies:
|
||||
reusify "^1.0.4"
|
||||
|
||||
fflate@^0.4.1:
|
||||
version "0.4.8"
|
||||
resolved "https://registry.yarnpkg.com/fflate/-/fflate-0.4.8.tgz#f90b82aefbd8ac174213abb338bd7ef848f0f5ae"
|
||||
integrity sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA==
|
||||
|
||||
file-entry-cache@^6.0.1:
|
||||
version "6.0.1"
|
||||
resolved "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz"
|
||||
@@ -2159,6 +2169,15 @@ postcss@^8.4.13, postcss@^8.4.14:
|
||||
picocolors "^1.0.0"
|
||||
source-map-js "^1.0.2"
|
||||
|
||||
posthog-js@^1.26.0:
|
||||
version "1.26.0"
|
||||
resolved "https://registry.yarnpkg.com/posthog-js/-/posthog-js-1.26.0.tgz#8fd2becfbdf8f165244043d109f140ea0d02a99b"
|
||||
integrity sha512-Fjc5REUJxrVTQ0WzfChn+CW/UrparZGwINPOtO9FoB25U2IrXnvnTUpkYhSPucZPWUwUMRdXBCo9838COn464Q==
|
||||
dependencies:
|
||||
"@sentry/types" "^7.2.0"
|
||||
fflate "^0.4.1"
|
||||
rrweb-snapshot "^1.1.14"
|
||||
|
||||
preact-render-to-string@^5.1.19:
|
||||
version "5.2.0"
|
||||
resolved "https://registry.npmjs.org/preact-render-to-string/-/preact-render-to-string-5.2.0.tgz"
|
||||
@@ -2363,6 +2382,11 @@ rimraf@^3.0.2:
|
||||
dependencies:
|
||||
glob "^7.1.3"
|
||||
|
||||
rrweb-snapshot@^1.1.14:
|
||||
version "1.1.14"
|
||||
resolved "https://registry.yarnpkg.com/rrweb-snapshot/-/rrweb-snapshot-1.1.14.tgz#9d4d9be54a28a893373428ee4393ec7e5bd83fcc"
|
||||
integrity sha512-eP5pirNjP5+GewQfcOQY4uBiDnpqxNRc65yKPW0eSoU1XamDfc4M8oqpXGMyUyvLyxFDB0q0+DChuxxiU2FXBQ==
|
||||
|
||||
run-parallel@^1.1.9:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz"
|
||||
|
||||
Reference in New Issue
Block a user