mirror of
https://github.com/formbricks/formbricks.git
synced 2026-01-26 02:58:48 -06:00
fix broken settings + UX improvements (#176)
Co-authored-by: knugget <johannes@knugget.de>
This commit is contained in:
@@ -23,7 +23,7 @@ export default function FormsPage() {
|
||||
}
|
||||
|
||||
if (isErrorCustomers || isErrorTeam) {
|
||||
return <div>Error loading ressources. Maybe you don‘t have enough access rights</div>;
|
||||
return <div>Error loading ressources. Maybe you don‘t have enough access rights.</div>;
|
||||
}
|
||||
return (
|
||||
<div className="mx-auto py-8 sm:px-6 lg:px-8">
|
||||
@@ -34,6 +34,9 @@ export default function FormsPage() {
|
||||
{team.name}
|
||||
</span>
|
||||
</h1>
|
||||
<p className="mt-4 text-slate-600">
|
||||
Pass a customerID with each submission and get an overview of all submissions per customer.
|
||||
</p>
|
||||
</header>
|
||||
{customers.length === 0 ? (
|
||||
<EmptyPageFiller
|
||||
|
||||
@@ -109,129 +109,137 @@ export default function FormOverviewPage() {
|
||||
|
||||
{activeTab.id === "overview" ? (
|
||||
<div>
|
||||
<div>
|
||||
<div className="mt-4 mb-12 text-sm text-gray-600">
|
||||
<p className="text-slate-700">
|
||||
To get started post your submission to the Formbricks HQ capture endpoint. All submissions
|
||||
are stored in Formbricks HQ and can be viewed here.
|
||||
<br /> <br />
|
||||
If you want to get notified when a submission is made you can also set up a webhook or email
|
||||
notifications in{" "}
|
||||
<Link
|
||||
href={`/app/teams/${router.query.teamId}/forms/${router.query.formId}/pipelines`}
|
||||
className="underline">
|
||||
Pipelines
|
||||
</Link>
|
||||
.<br />
|
||||
<br />
|
||||
Optionally you can set a schema for your form. This schema tells Formbricks HQ more about
|
||||
the structure of your form and enables better form evaluation, e.g. displays the correct
|
||||
labels for your form fields in the Formbricks HQ UI insted of the fieldName or filters data
|
||||
that doesn't match the schema. The easiest way to get started with a schema is to used
|
||||
our react library because it handles schema creation and sending to Formbricks HQ
|
||||
automatically.
|
||||
<br /> To learn more about the schema please check out our{" "}
|
||||
<Link href="https://formbricks.com/docs/formbricks-hq/schema">docs</Link>.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label htmlFor="formId" className="block text-base text-slate-800">
|
||||
Your form ID
|
||||
</label>
|
||||
<div className="mt-3 w-96">
|
||||
<input
|
||||
id="formId"
|
||||
type="text"
|
||||
className="focus:border-brand focus:ring-brand block w-full rounded-md border-gray-300 shadow-sm disabled:bg-gray-100 sm:text-sm"
|
||||
value={form.id}
|
||||
disabled
|
||||
/>
|
||||
|
||||
<Button
|
||||
variant="secondary"
|
||||
className="mt-2 w-full justify-center"
|
||||
onClick={() => {
|
||||
navigator.clipboard.writeText(form.id);
|
||||
toast("Copied form ID to clipboard");
|
||||
}}>
|
||||
copy
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<hr className="my-6" />
|
||||
<div className="max-w-2xl">
|
||||
<label htmlFor="formId" className="block text-base text-slate-800">
|
||||
Capture POST Url:
|
||||
</label>
|
||||
<div className="mt-3">
|
||||
<div className="mt-1 flex rounded-md shadow-sm">
|
||||
<span className="inline-flex items-center rounded-l-md border border-r-0 border-gray-300 bg-gray-200 px-3 text-gray-500 sm:text-sm">
|
||||
POST
|
||||
</span>
|
||||
<div className="grid grid-cols-5 gap-8 py-4">
|
||||
<div className="col-span-3">
|
||||
<div>
|
||||
<label htmlFor="formId" className="block text-lg font-semibold text-slate-800">
|
||||
Your form ID
|
||||
</label>
|
||||
<div className="mt-3 w-96">
|
||||
<input
|
||||
id="captureUrl"
|
||||
id="formId"
|
||||
type="text"
|
||||
className="focus:border-brand focus:ring-brand block w-full rounded-r-md border-gray-300 bg-gray-100 shadow-sm sm:text-sm"
|
||||
value={`${window.location.protocol}//${window.location.host}/capture/forms/${form.id}/submissions`}
|
||||
className="focus:border-brand focus:ring-brand block w-full rounded-md border-gray-300 shadow-sm disabled:bg-gray-100 sm:text-sm"
|
||||
value={form.id}
|
||||
disabled
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Button
|
||||
variant="secondary"
|
||||
className="mt-2 w-full justify-center"
|
||||
onClick={() => {
|
||||
navigator.clipboard.writeText(form.id);
|
||||
toast("Copied form url to clipboard");
|
||||
}}>
|
||||
copy
|
||||
</Button>
|
||||
<Button
|
||||
variant="secondary"
|
||||
className="mt-2 w-full justify-center"
|
||||
onClick={() => {
|
||||
navigator.clipboard.writeText(form.id);
|
||||
toast("Copied form ID to clipboard");
|
||||
}}>
|
||||
copy
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="max-w-2xl py-6">
|
||||
<label htmlFor="formId" className="block text-lg font-semibold text-slate-800">
|
||||
Capture POST Url:
|
||||
</label>
|
||||
<div className="mt-3">
|
||||
<div className="mt-1 flex rounded-md shadow-sm">
|
||||
<span className="inline-flex items-center rounded-l-md border border-r-0 border-gray-300 bg-gray-200 px-3 text-gray-500 sm:text-sm">
|
||||
POST
|
||||
</span>
|
||||
<input
|
||||
id="captureUrl"
|
||||
type="text"
|
||||
className="focus:border-brand focus:ring-brand block w-full rounded-r-md border-gray-300 bg-gray-100 shadow-sm sm:text-sm"
|
||||
value={`${window.location.protocol}//${window.location.host}/capture/forms/${form.id}/submissions`}
|
||||
disabled
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Button
|
||||
variant="secondary"
|
||||
className="mt-2 w-full justify-center"
|
||||
onClick={() => {
|
||||
navigator.clipboard.writeText(form.id);
|
||||
toast("Copied form url to clipboard");
|
||||
}}>
|
||||
copy
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="col-span-2 text-sm text-gray-600">
|
||||
<h3 className="block text-lg font-semibold text-slate-800">How to get started</h3>
|
||||
<ol className="list-decimal leading-8 text-slate-700">
|
||||
<li>POST a submission to the capture endpoint.</li>
|
||||
<li>
|
||||
View submission under{" "}
|
||||
<Link
|
||||
href={`/app/teams/${router.query.teamId}/forms/${router.query.formId}/submissions`}
|
||||
className="underline">
|
||||
Submissions
|
||||
</Link>{" "}
|
||||
tab.
|
||||
</li>
|
||||
<li>
|
||||
Get notified or pipe submission data to a different tool in the{" "}
|
||||
<Link
|
||||
href={`/app/teams/${router.query.teamId}/forms/${router.query.formId}/pipelines`}
|
||||
className="underline">
|
||||
Pipelines
|
||||
</Link>{" "}
|
||||
tab.
|
||||
</li>
|
||||
<li>
|
||||
For a summary of form data a schema is required. Learn all about schemas in our{" "}
|
||||
<Link
|
||||
target="_blank"
|
||||
href="https://formbricks.com/docs/formbricks-hq/schema"
|
||||
className="underline">
|
||||
docs
|
||||
</Link>
|
||||
.
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
) : activeTab.id === "api" ? (
|
||||
<div className="mt-5">
|
||||
<p className="my-3 text-sm text-gray-600">
|
||||
You can send submissions directly to Formbricks HQ via our API. The API doesn't need any
|
||||
authentication and can also called in the users browser.
|
||||
</p>
|
||||
<hr className="my-8" />
|
||||
<div className="max-w-2xl">
|
||||
<label htmlFor="formId" className="block text-base text-slate-800">
|
||||
Capture POST Url:
|
||||
</label>
|
||||
<div className="mt-3">
|
||||
<div className="mt-1 flex rounded-md shadow-sm">
|
||||
<span className="inline-flex items-center rounded-l-md border border-r-0 border-gray-300 bg-gray-200 px-3 text-gray-500 sm:text-sm">
|
||||
POST
|
||||
</span>
|
||||
<input
|
||||
id="captureUrl"
|
||||
type="text"
|
||||
className="focus:border-brand focus:ring-brand block w-full rounded-r-md border-gray-300 bg-gray-100 shadow-sm sm:text-sm"
|
||||
value={`${window.location.protocol}//${window.location.host}/capture/forms/${form.id}/submissions`}
|
||||
disabled
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<div className="grid grid-cols-5 gap-8 py-4">
|
||||
<div className="col-span-3">
|
||||
<div>
|
||||
<label htmlFor="formId" className="block text-lg font-semibold text-slate-800">
|
||||
Capture POST Url:
|
||||
</label>
|
||||
<div className="mt-3">
|
||||
<div className="mt-1 flex rounded-md shadow-sm">
|
||||
<span className="inline-flex items-center rounded-l-md border border-r-0 border-gray-300 bg-gray-200 px-3 text-gray-500 sm:text-sm">
|
||||
POST
|
||||
</span>
|
||||
<input
|
||||
id="captureUrl"
|
||||
type="text"
|
||||
className="focus:border-brand focus:ring-brand block w-full rounded-r-md border-gray-300 bg-gray-100 shadow-sm sm:text-sm"
|
||||
value={`${window.location.protocol}//${window.location.host}/capture/forms/${form.id}/submissions`}
|
||||
disabled
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Button
|
||||
variant="secondary"
|
||||
className="mt-2 w-full justify-center"
|
||||
onClick={() => {
|
||||
navigator.clipboard.writeText(form.id);
|
||||
toast("Copied form url to clipboard");
|
||||
}}>
|
||||
copy
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<hr className="my-8" />
|
||||
<div className="rounded-md bg-black p-8 text-sm font-light text-gray-200">
|
||||
<pre>
|
||||
<code className="language-js whitespace-pre-wrap">
|
||||
{`{
|
||||
<Button
|
||||
variant="secondary"
|
||||
className="mt-2 w-full justify-center"
|
||||
onClick={() => {
|
||||
navigator.clipboard.writeText(form.id);
|
||||
toast("Copied form url to clipboard");
|
||||
}}>
|
||||
copy
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-4 rounded-md bg-black p-4 font-light text-gray-200 first-letter:text-sm">
|
||||
<pre>
|
||||
<code className="language-js whitespace-pre-wrap">
|
||||
{`{
|
||||
"customerId": "user@example.com", /* optional */
|
||||
"data": {
|
||||
"firstname": "John",
|
||||
@@ -239,23 +247,32 @@ export default function FormOverviewPage() {
|
||||
"feedback": "I like the app very much"
|
||||
}
|
||||
}`}
|
||||
</code>
|
||||
</pre>
|
||||
</code>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-span-2 text-sm text-gray-600">
|
||||
<h3 className="block pb-4 text-lg font-semibold text-slate-800">Quick Tips</h3>
|
||||
<p className="font-bold">Authentication</p>
|
||||
<p className="my-3 text-sm text-gray-600">
|
||||
Via the API you can send submissions directly to Formbricks HQ. The API doesn't need
|
||||
any authentication and can also be called in the users browser.
|
||||
</p>
|
||||
<p className="pt-3 font-bold">CustomerId</p>
|
||||
<p className="my-3 text-sm text-gray-600">
|
||||
You can pass along a customer ID to identify the respondent. This allows you to attribute
|
||||
submissions of several surveys to the same respondent.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
) : activeTab.id === "react" ? (
|
||||
<div className="mt-5">
|
||||
<p className="my-3 text-sm text-gray-600">
|
||||
The best way to send submissions to Formbricks HQ in React is our simple to use{" "}
|
||||
<Link target="_blank" href="https://www.npmjs.com/package/@formbricks/react">
|
||||
React Library
|
||||
</Link>
|
||||
because it also creates and sends a schema to Formbricks HQ.
|
||||
</p>
|
||||
<div className="rounded-md bg-black p-8 text-sm font-light text-gray-200">
|
||||
<pre>
|
||||
<code className="language-js whitespace-pre-wrap">
|
||||
{`import { Form, Text, Email, Checkbox, Submit, sendToHq } from "@formbricks/react";
|
||||
<div>
|
||||
<div className="mt-5 grid grid-cols-5 gap-8">
|
||||
<div className="col-span-3 rounded-md bg-black p-4 text-sm font-light text-gray-200">
|
||||
<pre>
|
||||
<code className="language-js whitespace-pre-wrap">
|
||||
{`import { Form, Text, Email, Checkbox, Submit, sendToHq } from "@formbricks/react";
|
||||
import "@formbricks/react/styles.css";
|
||||
|
||||
export default function WaitlistForm() {
|
||||
@@ -278,17 +295,29 @@ return (
|
||||
</Form>
|
||||
);
|
||||
}`}
|
||||
</code>
|
||||
</pre>
|
||||
</code>
|
||||
</pre>
|
||||
</div>
|
||||
<div className="col-span-2">
|
||||
<h3 className="block text-lg font-semibold text-slate-800">Formbricks React</h3>
|
||||
<p className="my-3 text-sm text-gray-600">
|
||||
The best way to send submissions to Formbricks HQ in React is{" "}
|
||||
<Link
|
||||
target="_blank"
|
||||
className="underline"
|
||||
href="https://www.npmjs.com/package/@formbricks/react">
|
||||
Formbricks React.
|
||||
</Link>{" "}
|
||||
It makes form creation easy and automatically creates a schema to get a full picture of your
|
||||
data in the Summary tab.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<p className="my-3 text-sm text-gray-600">
|
||||
But you can also use the default React Form functionality (or another form library) to send the
|
||||
submissions to Formbricks HQ.
|
||||
</p>
|
||||
<div className="rounded-md bg-black p-8 text-sm font-light text-gray-200">
|
||||
<pre>
|
||||
<code className="language-js whitespace-pre-wrap">
|
||||
{`<form
|
||||
<div className="mt-5 grid grid-cols-5 gap-8">
|
||||
<div className="col-span-3 rounded-md bg-black p-4 text-sm font-light text-gray-200">
|
||||
<pre>
|
||||
<code className="language-js whitespace-pre-wrap">
|
||||
{`<form
|
||||
onSubmit={({ data }) => {
|
||||
fetch("${window.location.protocol}//${window.location.host}/capture/forms/${form.id}/submissions", {
|
||||
method: "POST",
|
||||
@@ -300,20 +329,25 @@ onSubmit={({ data }) => {
|
||||
}}>
|
||||
{/* YOUR FORM */}
|
||||
</form>`}
|
||||
</code>
|
||||
</pre>
|
||||
</code>
|
||||
</pre>
|
||||
</div>
|
||||
<div className="col-span-2">
|
||||
<h3 className="block text-lg font-semibold text-slate-800">Standard React Forms</h3>
|
||||
<p className="my-3 text-sm text-gray-600">
|
||||
You can also use the default React Form functionality (or another form library) to send the
|
||||
submissions to Formbricks HQ.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
) : activeTab.id === "vue" ? (
|
||||
<div className="mt-5">
|
||||
{" "}
|
||||
<p className="my-3 text-sm text-gray-600">
|
||||
To send a submission in Vue.Js you can use the default form functionality.
|
||||
</p>
|
||||
<div className="rounded-md bg-black p-8 text-sm font-light text-gray-200">
|
||||
<pre>
|
||||
<code className="language-js whitespace-pre-wrap">
|
||||
{`<template>
|
||||
<div>
|
||||
<div className="mt-5 grid grid-cols-5 gap-8">
|
||||
<div className="col-span-3 rounded-md bg-black p-4 text-sm font-light text-gray-200">
|
||||
<pre>
|
||||
<code className="language-js whitespace-pre-wrap">
|
||||
{`<template>
|
||||
<form @submit.prevent="submitForm">
|
||||
<label>
|
||||
<span>Email</span>
|
||||
@@ -347,15 +381,22 @@ export default {
|
||||
},
|
||||
}
|
||||
</script>`}
|
||||
</code>
|
||||
</pre>
|
||||
</code>
|
||||
</pre>
|
||||
</div>
|
||||
<div className="col-span-2">
|
||||
<h3 className="block text-lg font-semibold text-slate-800">Standard Vue Forms</h3>
|
||||
<p className="my-3 text-sm text-gray-600">
|
||||
You can also use the default Vue form functionality to send submissions to Formbricks HQ.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
{/* <div className="mt-16">
|
||||
<h2 className="text-xl font-bold text-slate-800">Code your form</h2>
|
||||
<div className="mt-4 mb-12">
|
||||
<div className="">
|
||||
<p className="text-slate-800">
|
||||
Build your form with the code library of your choice. Manage your data in this dashboard.
|
||||
</p>
|
||||
|
||||
@@ -152,7 +152,7 @@ export default function PipelinesPage({}) {
|
||||
</header>
|
||||
<div className="my-4">
|
||||
<p className="text-slate-800">
|
||||
Pipe your data exactly where you need it. Add conditions for variable data piping.
|
||||
Pipe your data to third party tools. Setup email notifications for new submissions.
|
||||
</p>
|
||||
</div>
|
||||
{pipelines.length > 0 ? (
|
||||
|
||||
@@ -61,20 +61,17 @@ export default function SummaryPage() {
|
||||
<ExclamationTriangleIcon className="h-5 w-5 text-yellow-400" aria-hidden="true" />
|
||||
</div>
|
||||
<div className="ml-3">
|
||||
<h3 className="text-sm font-medium text-yellow-800">This form doesn't have a schema </h3>
|
||||
<h3 className="text-sm font-medium text-yellow-800">No schema detected for this form.</h3>
|
||||
<div className="mt-2 text-sm text-yellow-700">
|
||||
<p>
|
||||
Formbricks HQ needs a schema of your form to display a summary. Learn more about the schema
|
||||
and how you can add one in our docs.
|
||||
</p>
|
||||
<p>To summarize your data Formbricks HQ needs a schema of your form.</p>
|
||||
</div>
|
||||
<div className="mt-4">
|
||||
<div className="-mx-2 -my-1.5 flex">
|
||||
<Link
|
||||
target="_blank"
|
||||
href="https://formbricks.com/docs/formbricks-hq/schema"
|
||||
className="rounded-md bg-yellow-50 px-2 py-1.5 text-sm font-medium text-yellow-800 hover:bg-yellow-100 focus:outline-none focus:ring-2 focus:ring-yellow-600 focus:ring-offset-2 focus:ring-offset-yellow-50">
|
||||
View docs
|
||||
className="rounded-md bg-yellow-100 px-2 py-1.5 text-sm font-medium text-yellow-800 hover:bg-yellow-200 focus:outline-none focus:ring-2 focus:ring-yellow-600 focus:ring-offset-2 focus:ring-offset-yellow-50">
|
||||
Setup schema
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -27,12 +27,12 @@ export default function LayoutWrapperTeam({ children }) {
|
||||
icon: UsersIcon,
|
||||
current: pathname.includes("/customers"),
|
||||
},
|
||||
{
|
||||
/* {
|
||||
name: "Settings",
|
||||
href: `/app/teams/${router.query.teamId}/<settings>`,
|
||||
href: `/app/teams/${router.query.teamId}/settings`,
|
||||
icon: Cog8ToothIcon,
|
||||
current: pathname.includes("/settings"),
|
||||
},
|
||||
}, */
|
||||
],
|
||||
[router.query, pathname]
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user