mirror of
https://github.com/formbricks/formbricks.git
synced 2026-01-26 02:58:48 -06:00
add js integration
This commit is contained in:
@@ -29,6 +29,7 @@ import { useTeam } from "@/lib/teams/teams";
|
||||
import { capitalizeFirstLetter, truncate } from "@/lib/utils";
|
||||
import {
|
||||
CustomersIcon,
|
||||
DashboardIcon,
|
||||
ErrorComponent,
|
||||
FilterIcon,
|
||||
FormIcon,
|
||||
@@ -117,12 +118,12 @@ export default function EnvironmentsNavbar({ environmentId, session }: Environme
|
||||
icon: FilterIcon,
|
||||
current: pathname?.includes("/events") || pathname?.includes("/attributes"),
|
||||
},
|
||||
/* {
|
||||
{
|
||||
name: "Integrations",
|
||||
href: `/environments/${environmentId}/integrations/installation`,
|
||||
icon: DashboardIcon,
|
||||
current: pathname?.includes("/integrations"),
|
||||
}, */
|
||||
},
|
||||
{
|
||||
name: "Settings",
|
||||
href: `/environments/${environmentId}/settings/profile`,
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Button } from "@formbricks/ui";
|
||||
|
||||
export default function DocsSidebar() {
|
||||
return (
|
||||
<div className="w-fit rounded-lg border border-slate-300 bg-slate-200 p-8 pr-16">
|
||||
<div className="w-20 min-w-max rounded-lg border border-slate-200 bg-slate-100 p-8">
|
||||
<p className="font-bold text-slate-700">Documentation</p>
|
||||
<p className="text-xs text-slate-500">Get detailed instructions</p>
|
||||
<Button className="my-2" href="https://formbricks.com/docs" target="_blank">
|
||||
@@ -0,0 +1,31 @@
|
||||
import { BackIcon } from "@formbricks/ui";
|
||||
import Link from "next/link";
|
||||
|
||||
interface IntegrationPageTitleProps {
|
||||
title: string;
|
||||
icon?: React.ReactNode;
|
||||
environmentId: string;
|
||||
}
|
||||
|
||||
const IntegrationPageTitle: React.FC<IntegrationPageTitleProps> = ({ title, icon, environmentId }) => {
|
||||
return (
|
||||
<div className="flex justify-between">
|
||||
<div className="mb-8">
|
||||
<Link className="inline-block" href={`/environments/${environmentId}/integrations/`}>
|
||||
<BackIcon className="mb-2 h-6 w-6" />
|
||||
</Link>
|
||||
|
||||
<div className="my-4 flex items-baseline">
|
||||
{icon && <div className="h-6 w-6">{icon}</div>}
|
||||
<h1 className="ml-3 text-2xl font-bold text-slate-600">{title}</h1>
|
||||
</div>
|
||||
</div>
|
||||
{/* <div className="flex items-center space-x-2">
|
||||
<Switch id="integration-enabled" />
|
||||
<Label htmlFor="integration-enabled">Enabled</Label>
|
||||
</div> */}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default IntegrationPageTitle;
|
||||
@@ -1,11 +0,0 @@
|
||||
import ContentWrapper from "@/components/shared/ContentWrapper";
|
||||
import IntegrationsTabs from "@/components/integrations/IntegrationsTabs";
|
||||
|
||||
export default function SettingsLayout({ children, params }) {
|
||||
return (
|
||||
<>
|
||||
<IntegrationsTabs activeId="alerts" environmentId={params.environmentId} />
|
||||
<ContentWrapper>{children}</ContentWrapper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
import SlackLogo from "@/images/slacklogo.png";
|
||||
import { Card, EmailIcon, PageTitle } from "@formbricks/ui";
|
||||
import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
|
||||
export default function EventsAttributesPage({ params }) {
|
||||
return (
|
||||
<div>
|
||||
<PageTitle>Team Alerts</PageTitle>
|
||||
<div className="grid grid-cols-3 gap-6">
|
||||
{/* <Card
|
||||
href={`/environments/${params.environmentId}/integrations/alerts/email`}
|
||||
title="Email Notifications"
|
||||
description="Keep your team in the loop with email notifications."
|
||||
icon={<EmailIcon />}
|
||||
/> */}
|
||||
<Card
|
||||
href={`/environments/${params.environmentId}/integrations/alerts/slack`}
|
||||
title="Slack"
|
||||
description="Surface insights in dedicated Slack channels."
|
||||
icon={<Image src={SlackLogo} alt="Slack Logo" />}
|
||||
/>
|
||||
<Link
|
||||
href={`/environments/${params.environmentId}/settings/notifications`}
|
||||
className="hover:ring-brand-dark cursor-pointer rounded-lg bg-slate-100 p-8 text-left shadow-sm transition-all duration-150 ease-in-out hover:ring-1">
|
||||
<div className="mb-6 h-8 w-8">
|
||||
<EmailIcon />
|
||||
</div>
|
||||
<h3 className="text-lg font-bold text-slate-800">Looking for email?</h3>
|
||||
<p className="text-xs text-slate-500">Change your notification settings.</p>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
"use client";
|
||||
|
||||
import Modal from "@/components/shared/Modal";
|
||||
import { Button, Checkbox, Input, Label } from "@formbricks/ui";
|
||||
|
||||
type AddEmailAlertModalProps = {
|
||||
open: boolean;
|
||||
setOpen: (v: boolean) => void;
|
||||
};
|
||||
|
||||
const AddEmailAlertModal: React.FC<AddEmailAlertModalProps> = ({ open, setOpen }) => {
|
||||
const surveys = [
|
||||
{ label: "Survey 1", id: "1" },
|
||||
{ label: "Survey 2", id: "2" },
|
||||
{ label: "Survey 3", id: "3" },
|
||||
];
|
||||
|
||||
const onTest = () => {
|
||||
throw Error("not implemented");
|
||||
};
|
||||
const onSave = () => {
|
||||
throw Error("not implemented");
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Modal open={open} setOpen={setOpen} title="Add Slack Alert">
|
||||
<form className="space-y-6">
|
||||
<div>
|
||||
<Label>Alert name</Label>
|
||||
<Input type="text" placeholder="e.g. Product Team Info" />
|
||||
</div>
|
||||
<div>
|
||||
<Label>End Point URL</Label>
|
||||
<Input type="URL" placeholder="https://hooks.slack.com/service/ABC123/ASD213ADS" />
|
||||
</div>
|
||||
<div>
|
||||
<Label className="block">Trigger Event</Label>
|
||||
<Label className="font-normal text-slate-400">
|
||||
Send message every time one of the surveys receives a response:
|
||||
</Label>
|
||||
<div className="mt-2 rounded bg-slate-50 p-6 ">
|
||||
<div className="flex items-center space-x-2">
|
||||
<Checkbox id="all" />
|
||||
<label
|
||||
htmlFor="all"
|
||||
className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70">
|
||||
All surveys
|
||||
</label>
|
||||
</div>
|
||||
<hr className="my-2" />
|
||||
{surveys.map((survey) => (
|
||||
<div key={survey.id} className="flex items-center space-x-2">
|
||||
<Checkbox className="my-1" id={survey.id} />
|
||||
<label
|
||||
htmlFor="all"
|
||||
className="text-sm font-medium leading-none text-slate-700 peer-disabled:cursor-not-allowed peer-disabled:opacity-70">
|
||||
{survey.label}
|
||||
</label>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex justify-end space-x-2">
|
||||
<Button variant="minimal" onClick={() => setOpen(false)}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button variant="secondary" onClick={onTest}>
|
||||
Send Test
|
||||
</Button>
|
||||
<Button variant="darkCTA" onClick={onSave}>
|
||||
Save
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
</Modal>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default AddEmailAlertModal;
|
||||
@@ -1,56 +0,0 @@
|
||||
"use client";
|
||||
|
||||
import { AddAlertButton } from "@/components/integrations/AddAlertButton";
|
||||
import AlertCard from "@/components/integrations/AlertCard";
|
||||
import IntegrationPageTitle from "@/components/integrations/IntegrationsPageTitle";
|
||||
import SlackLogo from "@/images/slacklogo.png";
|
||||
import Image from "next/image";
|
||||
import AddSlackAlertModal from "./AddSlackAlertModal";
|
||||
import DeleteDialog from "@/components/shared/DeleteDialog";
|
||||
import { useState } from "react";
|
||||
|
||||
export default function SlackAlertPage({ params }) {
|
||||
const exampleAlert = {
|
||||
href: "/",
|
||||
title: "Example Alert",
|
||||
description: "This is an example alert",
|
||||
};
|
||||
|
||||
const [isAlertModalOpen, setAlertModalOpen] = useState(false);
|
||||
const [isDeleteDialogOpen, setDeleteDialogOpen] = useState(false);
|
||||
|
||||
const handleAddAlertClick = async () => {
|
||||
setAlertModalOpen(true);
|
||||
};
|
||||
|
||||
const handleDeleteAlertClick = async () => {
|
||||
setDeleteDialogOpen(true);
|
||||
};
|
||||
|
||||
const deleteEmailAlert = async () => {
|
||||
setDeleteDialogOpen(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<IntegrationPageTitle environmentId={params.environmentId} title="Slack Alerts" goBackTo="alerts" />
|
||||
<div className="grid grid-cols-3 gap-6">
|
||||
<AlertCard
|
||||
onDelete={handleDeleteAlertClick}
|
||||
onEdit={handleAddAlertClick}
|
||||
title={exampleAlert.title}
|
||||
description={exampleAlert.description}
|
||||
icon={<Image src={SlackLogo} alt="Slack Logo" />}
|
||||
/>
|
||||
<AddAlertButton channel="Slack" onClick={() => handleAddAlertClick()} />
|
||||
</div>
|
||||
<AddSlackAlertModal open={isAlertModalOpen} setOpen={setAlertModalOpen} />
|
||||
<DeleteDialog
|
||||
deleteWhat="Email Alert"
|
||||
open={isDeleteDialogOpen}
|
||||
setOpen={setDeleteDialogOpen}
|
||||
onDelete={deleteEmailAlert}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
import IntegrationsTabs from "@/components/integrations/IntegrationsTabs";
|
||||
import ContentWrapper from "@/components/shared/ContentWrapper";
|
||||
|
||||
export default function EventsAttributesPage({ params }) {
|
||||
return (
|
||||
<div className="">
|
||||
<IntegrationsTabs activeId="data" environmentId={params.environmentId} />
|
||||
<ContentWrapper>Data</ContentWrapper>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
import DocsSidebar from "@/components/integrations/DocsSidebar";
|
||||
import IntegrationPageTitle from "@/components/integrations/IntegrationsPageTitle";
|
||||
import JSLogo from "@/images/jslogo.png";
|
||||
import { Input } from "@formbricks/ui";
|
||||
import Image from "next/image";
|
||||
|
||||
export default function JavaScriptPage({ params }) {
|
||||
/* useEffect(() => {
|
||||
Prism.highlightAll();
|
||||
}, []); */
|
||||
|
||||
return (
|
||||
<div>
|
||||
<IntegrationPageTitle
|
||||
environmentId={params.environmentId}
|
||||
title="JavaScript Snippet"
|
||||
icon={<Image src={JSLogo} alt="JavaScript Logo" />}
|
||||
goBackTo="installation"
|
||||
/>
|
||||
|
||||
<div className="grid grid-cols-3 gap-6">
|
||||
<div className="col-span-2">
|
||||
<div>
|
||||
<h3 className="text-xl font-bold text-slate-800">Quick Start</h3>
|
||||
<ol className="my-4 ml-2 list-decimal text-slate-900">
|
||||
<li>Copy the Javascript snippet below into the HEAD of your HTML file.</li>
|
||||
<li>Set up a button with the onClick handler below to let your users open the widget.</li>
|
||||
<li>PLACEHOLDER</li>
|
||||
</ol>
|
||||
<div className="flex">
|
||||
<div className="mr-6">
|
||||
<p className="font-bold text-slate-600">Production ID</p>
|
||||
<Input type="text" className="rounded border border-slate-200 bg-slate-100" />
|
||||
</div>
|
||||
<div>
|
||||
<p className="font-bold text-slate-600">Development ID</p>
|
||||
<Input type="text" className="rounded border border-slate-200 bg-slate-100" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="mt-12 text-xl font-bold text-slate-800">JavaScript Snippet</h3>
|
||||
<div className="col-span-3 rounded-md bg-black p-4 text-sm font-light text-slate-200">
|
||||
<pre>
|
||||
<code className="language-html whitespace-pre-wrap">
|
||||
{`<!--HTML header script -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/@formbricks/feedback@0.2" defer></script>
|
||||
|
||||
<script>
|
||||
window.formbricks = {
|
||||
...window.formbricks,
|
||||
config: {
|
||||
hqUrl: "https://app.formbricks.com",
|
||||
formId: "YOUR FEEDBACK BOX ID HERE", // copy from Formbricks dashboard
|
||||
contact: {
|
||||
name: "Matti",
|
||||
position: "Co-Founder",
|
||||
imgUrl: "https://avatars.githubusercontent.com/u/675065?s=128&v=4",
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
`}
|
||||
</code>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-span-1">
|
||||
<DocsSidebar />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
import ContentWrapper from "@/components/shared/ContentWrapper";
|
||||
import IntegrationsTabs from "@/components/integrations/IntegrationsTabs";
|
||||
|
||||
export default function InstallationsLayout({ children, params }) {
|
||||
return (
|
||||
<>
|
||||
<IntegrationsTabs activeId="installation" environmentId={params.environmentId} />
|
||||
<ContentWrapper>{children}</ContentWrapper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
import DocsSidebar from "@/components/integrations/DocsSidebar";
|
||||
import IntegrationPageTitle from "@/components/integrations/IntegrationsPageTitle";
|
||||
import NPMLogo from "@/images/npmlogo.png";
|
||||
import { Input } from "@formbricks/ui";
|
||||
import Image from "next/image";
|
||||
|
||||
export default function NPMPage({ params }) {
|
||||
/* useEffect(() => {
|
||||
Prism.highlightAll();
|
||||
}, []); */
|
||||
|
||||
return (
|
||||
<div>
|
||||
<IntegrationPageTitle
|
||||
environmentId={params.environmentId}
|
||||
title="NPM Install"
|
||||
icon={<Image src={NPMLogo} alt="NPM Logo" />}
|
||||
goBackTo="installation"
|
||||
/>
|
||||
|
||||
<div className="grid grid-cols-3 gap-6">
|
||||
<div className="col-span-2">
|
||||
<div>
|
||||
<h3 className="text-xl font-bold text-slate-800">Quick Start</h3>
|
||||
<ol className="my-4 ml-2 list-decimal text-slate-900">
|
||||
<li>Copy the Javascript snippet below into the HEAD of your HTML file.</li>
|
||||
<li>Set up a button with the onClick handler below to let your users open the widget.</li>
|
||||
<li>PLACEHOLDER</li>
|
||||
</ol>
|
||||
<div className="flex">
|
||||
<div className="mr-6">
|
||||
<p className="font-bold text-slate-600">Production ID</p>
|
||||
<Input type="text" className="rounded border border-slate-200 bg-slate-100" />
|
||||
</div>
|
||||
<div>
|
||||
<p className="font-bold text-slate-600">Development ID</p>
|
||||
<Input type="text" className="rounded border border-slate-200 bg-slate-100" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="mt-12 text-xl font-bold text-slate-800">JavaScript Snippet</h3>
|
||||
<div className="col-span-3 rounded-md bg-black p-4 text-sm font-light text-slate-200">
|
||||
<pre>
|
||||
<code className="language-html whitespace-pre-wrap">
|
||||
{`<!--HTML header script -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/@formbricks/feedback@0.2" defer></script>
|
||||
|
||||
<script>
|
||||
window.formbricks = {
|
||||
...window.formbricks,
|
||||
config: {
|
||||
hqUrl: "https://app.formbricks.com",
|
||||
formId: "YOUR FEEDBACK BOX ID HERE", // copy from Formbricks dashboard
|
||||
contact: {
|
||||
name: "Matti",
|
||||
position: "Co-Founder",
|
||||
imgUrl: "https://avatars.githubusercontent.com/u/675065?s=128&v=4",
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
`}
|
||||
</code>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-span-1">
|
||||
<DocsSidebar />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
import JSLogo from "@/images/jslogo.png";
|
||||
import NPMLogo from "@/images/npmlogo.png";
|
||||
import { Card, PageTitle } from "@formbricks/ui";
|
||||
import Image from "next/image";
|
||||
|
||||
export default function InstallationsPage({ params }) {
|
||||
return (
|
||||
<div>
|
||||
<PageTitle>Installation</PageTitle>
|
||||
<div className="grid grid-cols-3 gap-6">
|
||||
<Card
|
||||
href={`/environments/${params.environmentId}/integrations/installation/javascript`}
|
||||
title="JavaScript"
|
||||
description="Copy the Formbricks snippet into your HTML <head>."
|
||||
icon={<Image src={JSLogo} alt="JavaScript Logo" />}
|
||||
/>
|
||||
<Card
|
||||
href={`/environments/${params.environmentId}/integrations/installation/npm`}
|
||||
title="NPM"
|
||||
description="Use NPM or yarn to install the Formbricks SDK."
|
||||
icon={<Image src={NPMLogo} alt="NPM Logo" />}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
import DocsSidebar from "../DocsSidebar";
|
||||
import IntegrationPageTitle from "../IntegrationsPageTitle";
|
||||
import CodeBlock from "@/components/shared/CodeBlock";
|
||||
import JsLogo from "@/images/jslogo.png";
|
||||
import { WEBAPP_URL } from "@formbricks/lib/constants";
|
||||
import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
|
||||
export default function JsIntegrationPage({ params }) {
|
||||
return (
|
||||
<div>
|
||||
<IntegrationPageTitle
|
||||
environmentId={params.environmentId}
|
||||
title="Javascript Integration"
|
||||
icon={<Image src={JsLogo} alt="Javascript Logo" />}
|
||||
/>
|
||||
|
||||
<div className="flex justify-between gap-8">
|
||||
<div>
|
||||
<p className="mb-10 text-slate-800">
|
||||
The Formbricks Javascript Widget is the easiest way to integrate Formbricks into your web
|
||||
application. Once embedded, the SDK allows you to use all the Formbricks features like no code
|
||||
actions, show in-app surveys and synchronizing your user data with Formbricks.
|
||||
</p>
|
||||
<div className="prose prose-slate">
|
||||
<p className="text-lg font-semibold text-slate-800">Step 1: NPM Install</p>
|
||||
<CodeBlock language="sh">npm install @formbricks/js --save</CodeBlock>
|
||||
<p className="pt-4 text-lg font-semibold text-slate-800">Step 2: Initialize widget</p>
|
||||
<p>Import Formbricks and initialize the widget in your Component (e.g. App.tsx):</p>
|
||||
<CodeBlock language="js">{`import formbricks from "@formbricks/js";
|
||||
|
||||
if (typeof window !== "undefined") {
|
||||
formbricks.init({
|
||||
environmentId: "${params.environmentId}",
|
||||
apiHost: "${WEBAPP_URL}",
|
||||
logLevel: "debug", // remove when in production
|
||||
});
|
||||
}`}</CodeBlock>
|
||||
|
||||
<ul className="list-disc">
|
||||
<li>
|
||||
<span className="font-semibold">environmentId:</span> Used to identify the correct
|
||||
environment: {params.environmentId} is yours.
|
||||
</li>
|
||||
<li>
|
||||
<span className="font-semibold">apiHost:</span> This is the URL of your Formbricks backend.
|
||||
</li>
|
||||
</ul>
|
||||
<p className="text-lg font-semibold text-slate-800">You're done 🎉</p>
|
||||
<p>
|
||||
Your app now communicates with Formbricks - sending events, and loading surveys automatically!
|
||||
</p>
|
||||
|
||||
<ul className="list-disc text-slate-700">
|
||||
<li>
|
||||
<span className="font-semibold">Does your widget work? </span>
|
||||
<span>Scroll to the top!</span>
|
||||
</li>
|
||||
<li>
|
||||
<span className="font-semibold">
|
||||
Need a more detailed setup guide for React, Next.js or Vue.js?
|
||||
</span>{" "}
|
||||
<Link
|
||||
className="decoration-brand-dark"
|
||||
href="https://formbricks.com/docs/getting-started/quickstart"
|
||||
target="_blank">
|
||||
Check out the docs.
|
||||
</Link>
|
||||
</li>
|
||||
<li>
|
||||
<span className="font-semibold">Have a problem?</span>{" "}
|
||||
<Link
|
||||
className="decoration-brand-dark"
|
||||
target="_blank"
|
||||
href="https://github.com/formbricks/formbricks/issues">
|
||||
Open an issue on GitHub
|
||||
</Link>{" "}
|
||||
or{" "}
|
||||
<Link className="decoration-brand-dark" href="https://formbricks.com/discord" target="_blank">
|
||||
join Discord.
|
||||
</Link>
|
||||
</li>
|
||||
<li>
|
||||
<span className="font-semibold">
|
||||
Want to learn how to add user attributes, custom events and more?
|
||||
</span>{" "}
|
||||
<Link
|
||||
className="decoration-brand-dark"
|
||||
href="https://formbricks.com/docs/attributes/why"
|
||||
target="_blank">
|
||||
Dive into the docs.
|
||||
</Link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<DocsSidebar />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import ContentWrapper from "@/components/shared/ContentWrapper";
|
||||
|
||||
export default function IntegrationsLayout({ children }) {
|
||||
return (
|
||||
<>
|
||||
<ContentWrapper>{children}</ContentWrapper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -1,3 +1,19 @@
|
||||
export default function IntegrationsPage() {
|
||||
return <div>Integrations</div>;
|
||||
import { Card, PageTitle } from "@formbricks/ui";
|
||||
import Image from "next/image";
|
||||
import JsLogo from "@/images/jslogo.png";
|
||||
|
||||
export default function IntegrationsPage({ params }) {
|
||||
return (
|
||||
<div>
|
||||
<PageTitle>Integrations</PageTitle>
|
||||
<div className="grid grid-cols-3 gap-6">
|
||||
<Card
|
||||
href={`/environments/${params.environmentId}/integrations/js`}
|
||||
title="Javascript Widget"
|
||||
description="Integrate Formbricks into your Webapp"
|
||||
icon={<Image src={JsLogo} alt="Javascript Logo" />}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
"use client";
|
||||
|
||||
import { PlusCircleIcon } from "@heroicons/react/24/solid";
|
||||
|
||||
interface AddAlertButtonProps {
|
||||
channel: string;
|
||||
onClick?: () => void;
|
||||
}
|
||||
|
||||
export const AddAlertButton: React.FC<AddAlertButtonProps> = ({ channel, onClick = () => {} }) => {
|
||||
return (
|
||||
<button
|
||||
onClick={onClick}
|
||||
className="hover:border-brand-dark cursor-pointer rounded-lg border-2 border-dashed border-slate-300 p-8 transition-all duration-150 ease-in-out">
|
||||
<div className="flex w-full justify-center">
|
||||
<div className="mb-4 h-10 w-10 text-center">
|
||||
<PlusCircleIcon className="text-brand-dark" />
|
||||
</div>
|
||||
</div>
|
||||
<h3 className="text-lg font-bold text-slate-600">Add {channel} Alert</h3>
|
||||
<p className="text-xs text-slate-400">Keep your team in the loop.</p>
|
||||
</button>
|
||||
);
|
||||
};
|
||||
@@ -1,42 +0,0 @@
|
||||
import React from "react";
|
||||
import { Card } from "@formbricks/ui";
|
||||
import type { CardProps } from "@formbricks/ui";
|
||||
|
||||
import { TrashIcon, PencilSquareIcon } from "@heroicons/react/24/outline";
|
||||
|
||||
interface AlertCardProps extends CardProps {
|
||||
onDelete?: () => void;
|
||||
onEdit?: () => void;
|
||||
}
|
||||
|
||||
const AlertCard: React.FC<AlertCardProps> = ({ title, description, icon, onDelete, onEdit }) => (
|
||||
<div className="relative">
|
||||
<div className="absolute right-6 top-6">
|
||||
{onDelete && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
onDelete();
|
||||
}}>
|
||||
<TrashIcon className="mr-2 h-7 w-7 p-1 text-slate-500 hover:text-red-600" />
|
||||
</button>
|
||||
)}
|
||||
{onEdit && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
onEdit();
|
||||
}}>
|
||||
<PencilSquareIcon className="h-7 w-7 p-1 text-slate-500 hover:text-slate-800" />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
<Card onClick={onEdit} title={title} description={description} icon={icon} className="w-full" />
|
||||
</div>
|
||||
);
|
||||
|
||||
export default AlertCard;
|
||||
@@ -1,31 +0,0 @@
|
||||
import { BackIcon } from "@formbricks/ui";
|
||||
import Link from "next/link";
|
||||
|
||||
interface IntegrationPageTitleProps {
|
||||
title: string;
|
||||
icon?: React.ReactNode;
|
||||
goBackTo: string;
|
||||
environmentId: string;
|
||||
}
|
||||
|
||||
const IntegrationPageTitle: React.FC<IntegrationPageTitleProps> = ({
|
||||
title,
|
||||
icon,
|
||||
goBackTo,
|
||||
environmentId,
|
||||
}) => {
|
||||
return (
|
||||
<div className="mb-8">
|
||||
<Link className="inline-block" href={`/environments/${environmentId}/integrations/${goBackTo}`}>
|
||||
<BackIcon className="mb-2 h-6 w-6" />
|
||||
</Link>
|
||||
|
||||
<div className="my-4 flex items-baseline">
|
||||
{icon && <div className="h-6 w-6">{icon}</div>}
|
||||
<h1 className="ml-3 text-2xl font-bold text-slate-600">{title}</h1>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default IntegrationPageTitle;
|
||||
@@ -1,32 +0,0 @@
|
||||
import SecondNavbar from "../environments/SecondNavBar";
|
||||
import { CodeBracketSquareIcon, MegaphoneIcon, ArrowPathIcon } from "@heroicons/react/24/solid";
|
||||
|
||||
interface IntegrationsTabs {
|
||||
activeId: string;
|
||||
environmentId: string;
|
||||
}
|
||||
|
||||
export default function PeopleGroupsTabs({ activeId, environmentId }: IntegrationsTabs) {
|
||||
const tabs = [
|
||||
{
|
||||
id: "installation",
|
||||
label: "Installation",
|
||||
icon: <CodeBracketSquareIcon />,
|
||||
href: `/environments/${environmentId}/integrations/installation`,
|
||||
},
|
||||
{
|
||||
id: "alerts",
|
||||
label: "Team Alerts",
|
||||
icon: <MegaphoneIcon />,
|
||||
href: `/environments/${environmentId}/integrations/alerts`,
|
||||
},
|
||||
{
|
||||
id: "data",
|
||||
label: "Data Sync",
|
||||
icon: <ArrowPathIcon />,
|
||||
href: `/environments/${environmentId}/integrations/data`,
|
||||
},
|
||||
];
|
||||
|
||||
return <SecondNavbar tabs={tabs} activeId={activeId} />;
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
// components/ui/CodeBlock.tsx
|
||||
"use client";
|
||||
|
||||
import { DocumentDuplicateIcon } from "@heroicons/react/24/outline";
|
||||
import Prism from "prismjs";
|
||||
import "prismjs/themes/prism.css";
|
||||
|
||||
Reference in New Issue
Block a user