diff --git a/apps/hq/src/lib/teams.ts b/apps/hq/src/lib/teams.ts deleted file mode 100644 index c7eae024f0..0000000000 --- a/apps/hq/src/lib/teams.ts +++ /dev/null @@ -1,13 +0,0 @@ -import useSWR from "swr"; -import { fetcher } from "./utils"; - -export const useTeam = (id: string) => { - const { data, error, mutate } = useSWR(`/api/teams/${id}/`, fetcher); - - return { - team: data, - isLoadingTeam: !error && !data, - isErrorTeam: error, - mutateTeam: mutate, - }; -}; diff --git a/apps/hq/.eslintrc.js b/apps/web/.eslintrc.js similarity index 100% rename from apps/hq/.eslintrc.js rename to apps/web/.eslintrc.js diff --git a/apps/hq/.gitignore b/apps/web/.gitignore similarity index 100% rename from apps/hq/.gitignore rename to apps/web/.gitignore diff --git a/apps/hq/CHANGELOG.md b/apps/web/CHANGELOG.md similarity index 100% rename from apps/hq/CHANGELOG.md rename to apps/web/CHANGELOG.md diff --git a/apps/hq/Dockerfile b/apps/web/Dockerfile similarity index 100% rename from apps/hq/Dockerfile rename to apps/web/Dockerfile diff --git a/apps/hq/README.md b/apps/web/README.md similarity index 100% rename from apps/hq/README.md rename to apps/web/README.md diff --git a/apps/hq/next-env.d.ts b/apps/web/next-env.d.ts similarity index 100% rename from apps/hq/next-env.d.ts rename to apps/web/next-env.d.ts diff --git a/apps/hq/next.config.js b/apps/web/next.config.js similarity index 91% rename from apps/hq/next.config.js rename to apps/web/next.config.js index 1925e22074..4a1a14d459 100644 --- a/apps/hq/next.config.js +++ b/apps/web/next.config.js @@ -25,15 +25,6 @@ const nextConfig = { // Important: return the modified config return config; }, - async redirects() { - return [ - { - source: "/", - destination: "/app/", - permanent: false, - }, - ]; - }, async headers() { return [ { diff --git a/apps/hq/package.json b/apps/web/package.json similarity index 95% rename from apps/hq/package.json rename to apps/web/package.json index e3aecadd6a..505f86694b 100644 --- a/apps/hq/package.json +++ b/apps/web/package.json @@ -1,6 +1,6 @@ { "private": true, - "name": "@formbricks/hq", + "name": "@formbricks/web", "version": "0.0.1", "scripts": { "dev": "next dev", @@ -24,6 +24,7 @@ "next-auth": "^4.17.0", "nextjs-cors": "^2.1.2", "nodemailer": "^6.8.0", + "platform": "^1.3.6", "prismjs": "^1.29.0", "react": "^18.2.0", "react-dom": "^18.2.0", diff --git a/apps/hq/pnpm-lock.yaml b/apps/web/pnpm-lock.yaml similarity index 100% rename from apps/hq/pnpm-lock.yaml rename to apps/web/pnpm-lock.yaml diff --git a/apps/hq/postcss.config.js b/apps/web/postcss.config.js similarity index 100% rename from apps/hq/postcss.config.js rename to apps/web/postcss.config.js diff --git a/apps/hq/public/favicon/android-chrome-192x192.png b/apps/web/public/favicon/android-chrome-192x192.png similarity index 100% rename from apps/hq/public/favicon/android-chrome-192x192.png rename to apps/web/public/favicon/android-chrome-192x192.png diff --git a/apps/hq/public/favicon/android-chrome-512x512.png b/apps/web/public/favicon/android-chrome-512x512.png similarity index 100% rename from apps/hq/public/favicon/android-chrome-512x512.png rename to apps/web/public/favicon/android-chrome-512x512.png diff --git a/apps/hq/public/favicon/apple-touch-icon.png b/apps/web/public/favicon/apple-touch-icon.png similarity index 100% rename from apps/hq/public/favicon/apple-touch-icon.png rename to apps/web/public/favicon/apple-touch-icon.png diff --git a/apps/hq/public/favicon/browserconfig.xml b/apps/web/public/favicon/browserconfig.xml similarity index 100% rename from apps/hq/public/favicon/browserconfig.xml rename to apps/web/public/favicon/browserconfig.xml diff --git a/apps/hq/public/favicon/favicon-16x16.png b/apps/web/public/favicon/favicon-16x16.png similarity index 100% rename from apps/hq/public/favicon/favicon-16x16.png rename to apps/web/public/favicon/favicon-16x16.png diff --git a/apps/hq/public/favicon/favicon-32x32.png b/apps/web/public/favicon/favicon-32x32.png similarity index 100% rename from apps/hq/public/favicon/favicon-32x32.png rename to apps/web/public/favicon/favicon-32x32.png diff --git a/apps/hq/public/favicon/favicon.ico b/apps/web/public/favicon/favicon.ico similarity index 100% rename from apps/hq/public/favicon/favicon.ico rename to apps/web/public/favicon/favicon.ico diff --git a/apps/hq/public/favicon/mstile-144x144.png b/apps/web/public/favicon/mstile-144x144.png similarity index 100% rename from apps/hq/public/favicon/mstile-144x144.png rename to apps/web/public/favicon/mstile-144x144.png diff --git a/apps/hq/public/favicon/mstile-150x150.png b/apps/web/public/favicon/mstile-150x150.png similarity index 100% rename from apps/hq/public/favicon/mstile-150x150.png rename to apps/web/public/favicon/mstile-150x150.png diff --git a/apps/hq/public/favicon/mstile-310x150.png b/apps/web/public/favicon/mstile-310x150.png similarity index 100% rename from apps/hq/public/favicon/mstile-310x150.png rename to apps/web/public/favicon/mstile-310x150.png diff --git a/apps/hq/public/favicon/mstile-310x310.png b/apps/web/public/favicon/mstile-310x310.png similarity index 100% rename from apps/hq/public/favicon/mstile-310x310.png rename to apps/web/public/favicon/mstile-310x310.png diff --git a/apps/hq/public/favicon/mstile-70x70.png b/apps/web/public/favicon/mstile-70x70.png similarity index 100% rename from apps/hq/public/favicon/mstile-70x70.png rename to apps/web/public/favicon/mstile-70x70.png diff --git a/apps/hq/public/favicon/safari-pinned-tab.svg b/apps/web/public/favicon/safari-pinned-tab.svg similarity index 100% rename from apps/hq/public/favicon/safari-pinned-tab.svg rename to apps/web/public/favicon/safari-pinned-tab.svg diff --git a/apps/hq/public/favicon/site.webmanifest b/apps/web/public/favicon/site.webmanifest similarity index 100% rename from apps/hq/public/favicon/site.webmanifest rename to apps/web/public/favicon/site.webmanifest diff --git a/apps/hq/sentry.client.config.js b/apps/web/sentry.client.config.js similarity index 100% rename from apps/hq/sentry.client.config.js rename to apps/web/sentry.client.config.js diff --git a/apps/hq/sentry.properties b/apps/web/sentry.properties similarity index 100% rename from apps/hq/sentry.properties rename to apps/web/sentry.properties diff --git a/apps/hq/sentry.server.config.js b/apps/web/sentry.server.config.js similarity index 100% rename from apps/hq/sentry.server.config.js rename to apps/web/sentry.server.config.js diff --git a/apps/hq/src/components/AnalyticsCard.tsx b/apps/web/src/components/AnalyticsCard.tsx similarity index 100% rename from apps/hq/src/components/AnalyticsCard.tsx rename to apps/web/src/components/AnalyticsCard.tsx diff --git a/apps/hq/src/components/EmptyPageFiller.tsx b/apps/web/src/components/EmptyPageFiller.tsx similarity index 100% rename from apps/hq/src/components/EmptyPageFiller.tsx rename to apps/web/src/components/EmptyPageFiller.tsx diff --git a/apps/hq/src/components/FeedbackButton.tsx b/apps/web/src/components/FeedbackButton.tsx similarity index 100% rename from apps/hq/src/components/FeedbackButton.tsx rename to apps/web/src/components/FeedbackButton.tsx diff --git a/apps/hq/src/components/LoadingSpinner.tsx b/apps/web/src/components/LoadingSpinner.tsx similarity index 100% rename from apps/hq/src/components/LoadingSpinner.tsx rename to apps/web/src/components/LoadingSpinner.tsx diff --git a/apps/hq/src/components/Logo.tsx b/apps/web/src/components/Logo.tsx similarity index 100% rename from apps/hq/src/components/Logo.tsx rename to apps/web/src/components/Logo.tsx diff --git a/apps/hq/src/components/Modal.tsx b/apps/web/src/components/Modal.tsx similarity index 100% rename from apps/hq/src/components/Modal.tsx rename to apps/web/src/components/Modal.tsx diff --git a/apps/hq/src/components/TabNavigation.tsx b/apps/web/src/components/TabNavigation.tsx similarity index 100% rename from apps/hq/src/components/TabNavigation.tsx rename to apps/web/src/components/TabNavigation.tsx diff --git a/apps/hq/src/components/auth/GithubButton.tsx b/apps/web/src/components/auth/GithubButton.tsx similarity index 100% rename from apps/hq/src/components/auth/GithubButton.tsx rename to apps/web/src/components/auth/GithubButton.tsx diff --git a/apps/hq/src/components/auth/PasswordResetForm.tsx b/apps/web/src/components/auth/PasswordResetForm.tsx similarity index 100% rename from apps/hq/src/components/auth/PasswordResetForm.tsx rename to apps/web/src/components/auth/PasswordResetForm.tsx diff --git a/apps/hq/src/components/auth/RequestVerificationEmail.tsx b/apps/web/src/components/auth/RequestVerificationEmail.tsx similarity index 100% rename from apps/hq/src/components/auth/RequestVerificationEmail.tsx rename to apps/web/src/components/auth/RequestVerificationEmail.tsx diff --git a/apps/hq/src/components/auth/ResetPasswordForm.tsx b/apps/web/src/components/auth/ResetPasswordForm.tsx similarity index 100% rename from apps/hq/src/components/auth/ResetPasswordForm.tsx rename to apps/web/src/components/auth/ResetPasswordForm.tsx diff --git a/apps/hq/src/components/auth/SignIn.tsx b/apps/web/src/components/auth/SignIn.tsx similarity index 90% rename from apps/hq/src/components/auth/SignIn.tsx rename to apps/web/src/components/auth/SignIn.tsx index 779a970587..931e86bb20 100644 --- a/apps/hq/src/components/auth/SignIn.tsx +++ b/apps/web/src/components/auth/SignIn.tsx @@ -8,7 +8,7 @@ export const SignIn = ({ token }) => { if (token) { signIn("token", { token: token, - callbackUrl: `/app`, + callbackUrl: `/`, }); } }, [token]); diff --git a/apps/hq/src/components/auth/SigninForm.tsx b/apps/web/src/components/auth/SigninForm.tsx similarity index 98% rename from apps/hq/src/components/auth/SigninForm.tsx rename to apps/web/src/components/auth/SigninForm.tsx index feeda0fe74..00a7c50e97 100644 --- a/apps/hq/src/components/auth/SigninForm.tsx +++ b/apps/web/src/components/auth/SigninForm.tsx @@ -10,7 +10,7 @@ export const SigninForm = ({ callbackUrl, error }) => { const handleSubmit = async (e) => { e.preventDefault(); await signIn("credentials", { - callbackUrl: callbackUrl || "/app", + callbackUrl: callbackUrl || "/", email: e.target.elements.email.value, password: e.target.elements.password.value, }); diff --git a/apps/hq/src/components/auth/SignupForm.tsx b/apps/web/src/components/auth/SignupForm.tsx similarity index 100% rename from apps/hq/src/components/auth/SignupForm.tsx rename to apps/web/src/components/auth/SignupForm.tsx diff --git a/apps/hq/src/components/customers/CustomersPage.tsx b/apps/web/src/components/customers/CustomersPage.tsx similarity index 88% rename from apps/hq/src/components/customers/CustomersPage.tsx rename to apps/web/src/components/customers/CustomersPage.tsx index e3294430a4..8acd413272 100644 --- a/apps/hq/src/components/customers/CustomersPage.tsx +++ b/apps/web/src/components/customers/CustomersPage.tsx @@ -3,7 +3,7 @@ import LoadingSpinner from "@/components/LoadingSpinner"; import EmptyPageFiller from "@/components/EmptyPageFiller"; import { useCustomers } from "@/lib/customers"; -import { useTeam } from "@/lib/teams"; +import { useWorkspace } from "@/lib/workspaces"; import { convertDateTimeString } from "@/lib/utils"; import { UsersIcon } from "@heroicons/react/24/outline"; import Link from "next/link"; @@ -11,10 +11,14 @@ import { useRouter } from "next/router"; export default function FormsPage() { const router = useRouter(); - const { customers, isLoadingCustomers, isErrorCustomers } = useCustomers(router.query.teamId?.toString()); - const { team, isLoadingTeam, isErrorTeam } = useTeam(router.query.teamId?.toString()); + const { customers, isLoadingCustomers, isErrorCustomers } = useCustomers( + router.query.workspaceId?.toString() + ); + const { workspace, isLoadingWorkspace, isErrorWorkspace } = useWorkspace( + router.query.workspaceId?.toString() + ); - if (isLoadingCustomers || isLoadingTeam) { + if (isLoadingCustomers || isLoadingWorkspace) { return (
@@ -22,7 +26,7 @@ export default function FormsPage() { ); } - if (isErrorCustomers || isErrorTeam) { + if (isErrorCustomers || isErrorWorkspace) { return
Error loading ressources. Maybe you don‘t have enough access rights.
; } return ( @@ -31,7 +35,7 @@ export default function FormsPage() {

Customers - {team.name} + {workspace.name}

@@ -74,7 +78,7 @@ export default function FormsPage() { {customers.map((customer, customerIdx) => ( - + {customer.id} @@ -86,7 +90,7 @@ export default function FormsPage() { View, {customer.name} diff --git a/apps/hq/src/components/customers/SingleCustomerPage.tsx b/apps/web/src/components/customers/SingleCustomerPage.tsx similarity index 95% rename from apps/hq/src/components/customers/SingleCustomerPage.tsx rename to apps/web/src/components/customers/SingleCustomerPage.tsx index 27b490188d..e9ca9f3584 100644 --- a/apps/hq/src/components/customers/SingleCustomerPage.tsx +++ b/apps/web/src/components/customers/SingleCustomerPage.tsx @@ -4,7 +4,7 @@ import AnalyticsCard from "@/components/AnalyticsCard"; import SubmissionDisplay from "@/components/forms/submissions/SubmissionDisplay"; import LoadingSpinner from "@/components/LoadingSpinner"; import { useCustomer } from "@/lib/customers"; -import { useTeam } from "@/lib/teams"; +import { useWorkspace } from "@/lib/workspaces"; import { convertDateTimeString, onlyUnique } from "@/lib/utils"; import { BackIcon, BugIcon, ComplimentIcon, IdeaIcon } from "@formbricks/ui"; import { Dialog, Transition } from "@headlessui/react"; @@ -17,9 +17,11 @@ import EmptyPageFiller from "../EmptyPageFiller"; export default function SingleCustomerPage() { const router = useRouter(); - const { team, isLoadingTeam, isErrorTeam } = useTeam(router.query.teamId?.toString()); + const { workspace, isLoadingWorkspace, isErrorWorkspace } = useWorkspace( + router.query.workspaceId?.toString() + ); const { customer, isLoadingCustomer, isErrorCustomer } = useCustomer( - router.query.teamId?.toString(), + router.query.workspaceId?.toString(), router.query.customerId?.toString() ); @@ -29,7 +31,7 @@ export default function SingleCustomerPage() { } }, [customer]); - if (isLoadingTeam || isLoadingCustomer) { + if (isLoadingWorkspace || isLoadingCustomer) { return (

@@ -37,7 +39,7 @@ export default function SingleCustomerPage() { ); } - if (isErrorTeam || isErrorCustomer) { + if (isErrorWorkspace || isErrorCustomer) { return
Error loading ressources. Maybe you don‘t have enough access rights
; } return ( @@ -45,7 +47,7 @@ export default function SingleCustomerPage() {
+ href={`/workspaces/${router.query.workspaceId}/customers/`}> Back to customers overview diff --git a/apps/hq/src/components/forms/FormOverviewPage.tsx b/apps/web/src/components/forms/FormOverviewPage.tsx similarity index 97% rename from apps/hq/src/components/forms/FormOverviewPage.tsx rename to apps/web/src/components/forms/FormOverviewPage.tsx index c58aa2fc81..9c6f920e0e 100644 --- a/apps/hq/src/components/forms/FormOverviewPage.tsx +++ b/apps/web/src/components/forms/FormOverviewPage.tsx @@ -2,7 +2,7 @@ import LoadingSpinner from "@/components/LoadingSpinner"; import { useForm } from "@/lib/forms"; -import { useTeam } from "@/lib/teams"; +import { useWorkspace } from "@/lib/workspaces"; import { Button } from "@formbricks/ui"; import { UserIcon } from "@heroicons/react/20/solid"; import clsx from "clsx"; @@ -27,9 +27,11 @@ export default function FormOverviewPage() { const router = useRouter(); const { form, isLoadingForm, isErrorForm } = useForm( router.query.formId?.toString(), - router.query.teamId?.toString() + router.query.workspaceId?.toString() + ); + const { workspace, isLoadingWorkspace, isErrorWorkspace } = useWorkspace( + router.query.workspaceId?.toString() ); - const { team, isLoadingTeam, isErrorTeam } = useTeam(router.query.teamId?.toString()); const [activeTab, setActiveTab] = useState(tabs[0]); useEffect(() => { @@ -38,7 +40,7 @@ export default function FormOverviewPage() { } }, [isLoadingForm]); - if (isLoadingForm || isLoadingTeam) { + if (isLoadingForm || isLoadingWorkspace) { return (
@@ -46,7 +48,7 @@ export default function FormOverviewPage() { ); } - if (isErrorForm || isErrorTeam) { + if (isErrorForm || isErrorWorkspace) { return
Error loading ressources. Maybe you don‘t have enough access rights
; } return ( @@ -55,7 +57,7 @@ export default function FormOverviewPage() {

{form.label} - {team.name} + {workspace.name}

@@ -174,7 +176,7 @@ export default function FormOverviewPage() {
  • View submission under{" "} Submissions {" "} @@ -183,7 +185,7 @@ export default function FormOverviewPage() {
  • Get notified or pipe submission data to a different tool in the{" "} Pipelines {" "} diff --git a/apps/hq/src/components/forms/FormsList.tsx b/apps/web/src/components/forms/FormsList.tsx similarity index 95% rename from apps/hq/src/components/forms/FormsList.tsx rename to apps/web/src/components/forms/FormsList.tsx index 5d69305633..d68d17b20a 100644 --- a/apps/hq/src/components/forms/FormsList.tsx +++ b/apps/web/src/components/forms/FormsList.tsx @@ -10,8 +10,8 @@ import Link from "next/link"; import { Fragment, useState } from "react"; import NewFormModal from "@/components/forms/NewFormModal"; -export default function FormsList({ teamId }) { - const { forms, mutateForms, isLoadingForms } = useForms(teamId); +export default function FormsList({ workspaceId }) { + const { forms, mutateForms, isLoadingForms } = useForms(workspaceId); const [openNewFormModal, setOpenNewFormModal] = useState(false); const newForm = async () => { @@ -20,7 +20,7 @@ export default function FormsList({ teamId }) { const deleteFormAction = async (form, formIdx) => { try { - await deleteForm(teamId, form.id); + await deleteForm(workspaceId, form.id); // remove locally const updatedForms = JSON.parse(JSON.stringify(forms)); updatedForms.splice(formIdx, 1); @@ -67,7 +67,7 @@ export default function FormsList({ teamId }) {

    {form.label}

  • @@ -135,7 +135,7 @@ export default function FormsList({ teamId }) { ))}
    - + ); } diff --git a/apps/hq/src/components/forms/FormsPage.tsx b/apps/web/src/components/forms/FormsPage.tsx similarity index 72% rename from apps/hq/src/components/forms/FormsPage.tsx rename to apps/web/src/components/forms/FormsPage.tsx index eef9d464b2..56f1160721 100644 --- a/apps/hq/src/components/forms/FormsPage.tsx +++ b/apps/web/src/components/forms/FormsPage.tsx @@ -3,15 +3,17 @@ import FormsList from "@/components/forms/FormsList"; import LoadingSpinner from "@/components/LoadingSpinner"; import { useForms } from "@/lib/forms"; -import { useTeam } from "@/lib/teams"; +import { useWorkspace } from "@/lib/workspaces"; import { useRouter } from "next/router"; export default function FormsPage({}) { const router = useRouter(); - const { isLoadingForms, isErrorForms } = useForms(router.query.teamId?.toString()); - const { team, isLoadingTeam, isErrorTeam } = useTeam(router.query.teamId?.toString()); + const { isLoadingForms, isErrorForms } = useForms(router.query.workspaceId?.toString()); + const { workspace, isLoadingWorkspace, isErrorWorkspace } = useWorkspace( + router.query.workspaceId?.toString() + ); - if (isLoadingForms || isLoadingTeam) { + if (isLoadingForms || isLoadingWorkspace) { return (
    @@ -19,7 +21,7 @@ export default function FormsPage({}) { ); } - if (isErrorForms || isErrorTeam) { + if (isErrorForms || isErrorWorkspace) { return
    Error loading ressources. Maybe you don‘t have enough access rights
    ; } return ( @@ -28,11 +30,11 @@ export default function FormsPage({}) {

    Forms - {team.name} + {workspace.name}

    - +
    ); } diff --git a/apps/hq/src/components/forms/NewFormModal.tsx b/apps/web/src/components/forms/NewFormModal.tsx similarity index 94% rename from apps/hq/src/components/forms/NewFormModal.tsx rename to apps/web/src/components/forms/NewFormModal.tsx index bf2f4ceb3d..e3236e99e2 100644 --- a/apps/hq/src/components/forms/NewFormModal.tsx +++ b/apps/web/src/components/forms/NewFormModal.tsx @@ -11,16 +11,16 @@ import { BsPlus } from "react-icons/bs"; type FormOnboardingModalProps = { open: boolean; setOpen: (v: boolean) => void; - teamId: string; + workspaceId: string; }; -export default function NewFormModal({ open, setOpen, teamId }: FormOnboardingModalProps) { +export default function NewFormModal({ open, setOpen, workspaceId }: FormOnboardingModalProps) { const router = useRouter(); const [label, setLabel] = useState(""); const createFormAction = async (e) => { e.preventDefault(); - const form = await createForm(teamId, { + const form = await createForm(workspaceId, { label, type: "feedback", schema: { @@ -41,7 +41,7 @@ export default function NewFormModal({ open, setOpen, teamId }: FormOnboardingMo ], }, }); - router.push(`/app/teams/${teamId}/forms/${form.id}/feedback/`); + router.push(`/workspaces/${workspaceId}/forms/${form.id}/feedback/`); }; return ( diff --git a/apps/hq/src/components/forms/feedback/FeedbackPage.tsx b/apps/web/src/components/forms/feedback/FeedbackPage.tsx similarity index 97% rename from apps/hq/src/components/forms/feedback/FeedbackPage.tsx rename to apps/web/src/components/forms/feedback/FeedbackPage.tsx index 6dea330baf..8477b85286 100644 --- a/apps/hq/src/components/forms/feedback/FeedbackPage.tsx +++ b/apps/web/src/components/forms/feedback/FeedbackPage.tsx @@ -21,7 +21,7 @@ export default function FeedbackPage() { const [currentTab, setCurrentTab] = useState("Results"); const { form, isLoadingForm, isErrorForm } = useForm( router.query.formId?.toString(), - router.query.teamId?.toString() + router.query.workspaceId?.toString() ); if (isLoadingForm) { diff --git a/apps/hq/src/components/forms/feedback/FeedbackResults.tsx b/apps/web/src/components/forms/feedback/FeedbackResults.tsx similarity index 99% rename from apps/hq/src/components/forms/feedback/FeedbackResults.tsx rename to apps/web/src/components/forms/feedback/FeedbackResults.tsx index 238eb4fbfd..e2db42d03d 100644 --- a/apps/hq/src/components/forms/feedback/FeedbackResults.tsx +++ b/apps/web/src/components/forms/feedback/FeedbackResults.tsx @@ -21,7 +21,7 @@ const subCategories = [ export default function FeedbackResults() { const router = useRouter(); const { submissions, isLoadingSubmissions, isErrorSubmissions, mutateSubmissions } = useSubmissions( - router.query.teamId?.toString(), + router.query.workspaceId?.toString(), router.query.formId?.toString() ); const [mobileFiltersOpen, setMobileFiltersOpen] = useState(false); diff --git a/apps/hq/src/components/forms/feedback/FeedbackTimeline.tsx b/apps/web/src/components/forms/feedback/FeedbackTimeline.tsx similarity index 94% rename from apps/hq/src/components/forms/feedback/FeedbackTimeline.tsx rename to apps/web/src/components/forms/feedback/FeedbackTimeline.tsx index c5bd901935..b8e0f3cf9c 100644 --- a/apps/hq/src/components/forms/feedback/FeedbackTimeline.tsx +++ b/apps/web/src/components/forms/feedback/FeedbackTimeline.tsx @@ -1,6 +1,6 @@ import EmptyPageFiller from "@/components/EmptyPageFiller"; import { persistSubmission, useSubmissions } from "@/lib/submissions"; -import { convertDateTimeString } from "@/lib/utils"; +import { convertDateTimeString, parseUserAgent } from "@/lib/utils"; import { BugIcon, Button, ComplimentIcon, IdeaIcon } from "@formbricks/ui"; import { InboxIcon } from "@heroicons/react/24/outline"; import clsx from "clsx"; @@ -12,7 +12,7 @@ export default function FeedbackTimeline({ submissions, setSubmissions }) { const router = useRouter(); const { submissions: allSubmissions, mutateSubmissions } = useSubmissions( - router.query.teamId?.toString(), + router.query.workspaceId?.toString(), router.query.formId?.toString() ); @@ -22,7 +22,7 @@ export default function FeedbackTimeline({ submissions, setSubmissions }) { // save submission without customer const submissionWoCustomer = { ...updatedSubmission }; delete submissionWoCustomer.customer; - persistSubmission(submissionWoCustomer, router.query.teamId?.toString()); + persistSubmission(submissionWoCustomer, router.query.workspaceId?.toString()); // update all submissions const submissionIdx = allSubmissions.findIndex((s) => s.id === submission.id); const updatedSubmissions = JSON.parse(JSON.stringify(allSubmissions)); @@ -107,7 +107,7 @@ export default function FeedbackTimeline({ submissions, setSubmissions }) { {submission.customer ? ( + href={`/workspaces/${router.query.workspaceId}/customers/${submission.customer.id}`}> {submission.customer.id} ) : ( @@ -116,7 +116,9 @@ export default function FeedbackTimeline({ submissions, setSubmissions }) {

    Device

    -

    {submission.meta.userAgent}

    +

    + {parseUserAgent(submission.meta.userAgent)} +

    Page

    diff --git a/apps/hq/src/components/forms/feedback/SetupInstructions.tsx b/apps/web/src/components/forms/feedback/SetupInstructions.tsx similarity index 100% rename from apps/hq/src/components/forms/feedback/SetupInstructions.tsx rename to apps/web/src/components/forms/feedback/SetupInstructions.tsx diff --git a/apps/hq/src/components/forms/pipelines/AddPipelineModal.tsx b/apps/web/src/components/forms/pipelines/AddPipelineModal.tsx similarity index 97% rename from apps/hq/src/components/forms/pipelines/AddPipelineModal.tsx rename to apps/web/src/components/forms/pipelines/AddPipelineModal.tsx index 1c5055160f..b7120f6b09 100644 --- a/apps/hq/src/components/forms/pipelines/AddPipelineModal.tsx +++ b/apps/web/src/components/forms/pipelines/AddPipelineModal.tsx @@ -23,7 +23,7 @@ export default function AddPipelineModal({ open, setOpen }) { const [pipeline, setPipeline] = useState(getEmptyPipeline()); const { pipelines, mutatePipelines } = usePipelines( router.query.formId?.toString(), - router.query.teamId?.toString() + router.query.workspaceId?.toString() ); useEffect(() => { @@ -43,7 +43,7 @@ export default function AddPipelineModal({ open, setOpen }) { e.preventDefault(); const newPipeline = await createPipeline( router.query.formId?.toString(), - router.query.teamId?.toString(), + router.query.workspaceId?.toString(), pipeline ); const newPipelines = JSON.parse(JSON.stringify(pipelines)); diff --git a/apps/hq/src/components/forms/pipelines/PipelineSettings.tsx b/apps/web/src/components/forms/pipelines/PipelineSettings.tsx similarity index 100% rename from apps/hq/src/components/forms/pipelines/PipelineSettings.tsx rename to apps/web/src/components/forms/pipelines/PipelineSettings.tsx diff --git a/apps/hq/src/components/forms/pipelines/PipelinesOverview.tsx b/apps/web/src/components/forms/pipelines/PipelinesOverview.tsx similarity index 95% rename from apps/hq/src/components/forms/pipelines/PipelinesOverview.tsx rename to apps/web/src/components/forms/pipelines/PipelinesOverview.tsx index 75b5aa51ce..7ed987a0c4 100644 --- a/apps/hq/src/components/forms/pipelines/PipelinesOverview.tsx +++ b/apps/web/src/components/forms/pipelines/PipelinesOverview.tsx @@ -4,7 +4,7 @@ import EmptyPageFiller from "@/components/EmptyPageFiller"; import LoadingSpinner from "@/components/LoadingSpinner"; import { useForm } from "@/lib/forms"; import { deletePipeline, persistPipeline, usePipelines } from "@/lib/pipelines"; -import { useTeam } from "@/lib/teams"; +import { useWorkspace } from "@/lib/workspaces"; import { Button } from "@formbricks/ui"; import { Switch } from "@headlessui/react"; import { BoltIcon, Cog6ToothIcon, TrashIcon } from "@heroicons/react/20/solid"; @@ -87,12 +87,14 @@ export default function PipelinesOverview({}) { const router = useRouter(); const { form, isLoadingForm, isErrorForm } = useForm( router.query.formId?.toString(), - router.query.teamId?.toString() + router.query.workspaceId?.toString() + ); + const { workspace, isLoadingWorkspace, isErrorWorkspace } = useWorkspace( + router.query.workspaceId?.toString() ); - const { team, isLoadingTeam, isErrorTeam } = useTeam(router.query.teamId?.toString()); const { pipelines, isLoadingPipelines, isErrorPipelines, mutatePipelines } = usePipelines( router.query.formId?.toString(), - router.query.teamId?.toString() + router.query.workspaceId?.toString() ); const [openAddModal, setOpenAddModal] = useState(false); @@ -102,7 +104,7 @@ export default function PipelinesOverview({}) { const toggleEnabled = async (pipeline) => { const newPipeline = JSON.parse(JSON.stringify(pipeline)); newPipeline.enabled = !newPipeline.enabled; - await persistPipeline(router.query.formId, router.query.teamId, newPipeline); + await persistPipeline(router.query.formId, router.query.workspaceId, newPipeline); const pipelineIdx = pipelines.findIndex((p) => p.id === pipeline.id); if (pipelineIdx !== -1) { const newPipelines = JSON.parse(JSON.stringify(pipelines)); @@ -117,7 +119,7 @@ export default function PipelinesOverview({}) { }; const deletePipelineAction = async (pipelineId) => { - await deletePipeline(router.query.formId?.toString(), router.query.teamId?.toString(), pipelineId); + await deletePipeline(router.query.formId?.toString(), router.query.workspaceId?.toString(), pipelineId); const newPipelines = JSON.parse(JSON.stringify(pipelines)); const pipelineIdx = newPipelines.findIndex((p) => p.id === pipelineId); if (pipelineIdx > -1) { @@ -126,7 +128,7 @@ export default function PipelinesOverview({}) { } }; - if (isLoadingForm || isLoadingTeam || isLoadingPipelines) { + if (isLoadingForm || isLoadingWorkspace || isLoadingPipelines) { return (
    @@ -134,7 +136,7 @@ export default function PipelinesOverview({}) { ); } - if (isErrorForm || isErrorTeam || isErrorPipelines) { + if (isErrorForm || isErrorWorkspace || isErrorPipelines) { return
    Error loading ressources. Maybe you don‘t have enough access rights
    ; } return ( diff --git a/apps/hq/src/components/forms/pipelines/UpdatePipelineModal.tsx b/apps/web/src/components/forms/pipelines/UpdatePipelineModal.tsx similarity index 94% rename from apps/hq/src/components/forms/pipelines/UpdatePipelineModal.tsx rename to apps/web/src/components/forms/pipelines/UpdatePipelineModal.tsx index 44f4a5c86d..cf5a05a82d 100644 --- a/apps/hq/src/components/forms/pipelines/UpdatePipelineModal.tsx +++ b/apps/web/src/components/forms/pipelines/UpdatePipelineModal.tsx @@ -7,18 +7,18 @@ import PipelineSettings from "./PipelineSettings"; export default function UpdatePipelineModal({ open, setOpen, pipelineId }) { const router = useRouter(); const { pipeline, isLoadingPipeline, mutatePipeline } = usePipeline( - router.query.teamId?.toString(), + router.query.workspaceId?.toString(), router.query.formId?.toString(), pipelineId ); const { pipelines, mutatePipelines } = usePipelines( router.query.formId?.toString(), - router.query.teamId?.toString() + router.query.workspaceId?.toString() ); const handleSubmit = async (e) => { e.preventDefault(); - await persistPipeline(router.query.formId?.toString(), router.query.teamId?.toString(), pipeline); + await persistPipeline(router.query.formId?.toString(), router.query.workspaceId?.toString(), pipeline); const newPipelines = JSON.parse(JSON.stringify(pipelines)); const pipelineIdx = pipelines.findIndex((p) => p.id === pipelineId); if (pipelineIdx > -1) { diff --git a/apps/hq/src/components/forms/pipelines/emailNotification.tsx b/apps/web/src/components/forms/pipelines/emailNotification.tsx similarity index 100% rename from apps/hq/src/components/forms/pipelines/emailNotification.tsx rename to apps/web/src/components/forms/pipelines/emailNotification.tsx diff --git a/apps/hq/src/components/forms/pipelines/slackNotification.tsx b/apps/web/src/components/forms/pipelines/slackNotification.tsx similarity index 100% rename from apps/hq/src/components/forms/pipelines/slackNotification.tsx rename to apps/web/src/components/forms/pipelines/slackNotification.tsx diff --git a/apps/hq/src/components/forms/pipelines/webhook.tsx b/apps/web/src/components/forms/pipelines/webhook.tsx similarity index 100% rename from apps/hq/src/components/forms/pipelines/webhook.tsx rename to apps/web/src/components/forms/pipelines/webhook.tsx diff --git a/apps/hq/src/components/forms/submissions/SubmissionDisplay.tsx b/apps/web/src/components/forms/submissions/SubmissionDisplay.tsx similarity index 100% rename from apps/hq/src/components/forms/submissions/SubmissionDisplay.tsx rename to apps/web/src/components/forms/submissions/SubmissionDisplay.tsx diff --git a/apps/hq/src/components/forms/submissions/SubmissionsPage.tsx b/apps/web/src/components/forms/submissions/SubmissionsPage.tsx similarity index 96% rename from apps/hq/src/components/forms/submissions/SubmissionsPage.tsx rename to apps/web/src/components/forms/submissions/SubmissionsPage.tsx index 844a191033..d97aff2e85 100644 --- a/apps/hq/src/components/forms/submissions/SubmissionsPage.tsx +++ b/apps/web/src/components/forms/submissions/SubmissionsPage.tsx @@ -17,18 +17,22 @@ import { useRouter } from "next/router"; export default function SubmissionsPage() { const router = useRouter(); const { submissions, isLoadingSubmissions, mutateSubmissions, isErrorSubmissions } = useSubmissions( - router.query.teamId?.toString(), + router.query.workspaceId?.toString(), router.query.formId?.toString() ); const { form, isLoadingForm, isErrorForm } = useForm( router.query.formId?.toString(), - router.query.teamId?.toString() + router.query.workspaceId?.toString() ); const [activeSubmission, setActiveSubmission] = useState(null); const handleDelete = async (submission: Submission) => { try { - await deleteSubmission(router.query.teamId?.toString(), router.query.formId?.toString(), submission.id); + await deleteSubmission( + router.query.workspaceId?.toString(), + router.query.formId?.toString(), + submission.id + ); await mutateSubmissions(); setActiveSubmission(null); diff --git a/apps/hq/src/components/forms/summary/SummaryPage.tsx b/apps/web/src/components/forms/summary/SummaryPage.tsx similarity index 93% rename from apps/hq/src/components/forms/summary/SummaryPage.tsx rename to apps/web/src/components/forms/summary/SummaryPage.tsx index de39de8dd6..361b4c6dbb 100644 --- a/apps/hq/src/components/forms/summary/SummaryPage.tsx +++ b/apps/web/src/components/forms/summary/SummaryPage.tsx @@ -4,7 +4,7 @@ import AnalyticsCard from "@/components/AnalyticsCard"; import LoadingSpinner from "@/components/LoadingSpinner"; import { useForm } from "@/lib/forms"; import { useSubmissions } from "@/lib/submissions"; -import { useTeam } from "@/lib/teams"; +import { useWorkspace } from "@/lib/workspaces"; import { Bar, Nps, Table } from "@formbricks/charts"; import { ExclamationTriangleIcon } from "@heroicons/react/20/solid"; import Link from "next/link"; @@ -14,15 +14,17 @@ export default function SummaryPage() { const router = useRouter(); const { form, isLoadingForm, isErrorForm } = useForm( router.query.formId?.toString(), - router.query.teamId?.toString() + router.query.workspaceId?.toString() + ); + const { workspace, isLoadingWorkspace, isErrorWorkspace } = useWorkspace( + router.query.workspaceId?.toString() ); - const { team, isLoadingTeam, isErrorTeam } = useTeam(router.query.teamId?.toString()); const { submissions, isLoadingSubmissions, mutateSubmissions } = useSubmissions( - router.query.teamId?.toString(), + router.query.workspaceId?.toString(), router.query.formId?.toString() ); - if (isLoadingForm || isLoadingTeam || isLoadingSubmissions) { + if (isLoadingForm || isLoadingWorkspace || isLoadingSubmissions) { return (
    @@ -30,7 +32,7 @@ export default function SummaryPage() { ); } - if (isErrorForm || isErrorTeam) { + if (isErrorForm || isErrorWorkspace) { return
    Error loading ressources. Maybe you don‘t have enough access rights
    ; } return ( @@ -39,7 +41,7 @@ export default function SummaryPage() {

    Summary - {form.label} - {team.name} + {workspace.name}

    diff --git a/apps/hq/src/components/layout/LayoutApp.tsx b/apps/web/src/components/layout/LayoutApp.tsx similarity index 98% rename from apps/hq/src/components/layout/LayoutApp.tsx rename to apps/web/src/components/layout/LayoutApp.tsx index 6a755f1739..5a95dcb8ec 100644 --- a/apps/hq/src/components/layout/LayoutApp.tsx +++ b/apps/web/src/components/layout/LayoutApp.tsx @@ -18,7 +18,7 @@ export default function LayoutApp({ children }) { { name: "Settings", onClick: () => { - router.push("/app/me/settings"); + router.push("/me/settings"); }, }, { name: "Sign out", onClick: () => signOut() }, @@ -51,7 +51,7 @@ export default function LayoutApp({ children }) {
    - +
    diff --git a/apps/hq/src/components/layout/LayoutAuth.tsx b/apps/web/src/components/layout/LayoutAuth.tsx similarity index 97% rename from apps/hq/src/components/layout/LayoutAuth.tsx rename to apps/web/src/components/layout/LayoutAuth.tsx index 443547029a..091fe3f536 100644 --- a/apps/hq/src/components/layout/LayoutAuth.tsx +++ b/apps/web/src/components/layout/LayoutAuth.tsx @@ -13,7 +13,7 @@ export default function LayoutAuth({ title = "Formbricks HQ", children }: Props) const router = useRouter(); if (session) { - router.push("/app"); + router.push("/"); } return ( <> diff --git a/apps/hq/src/components/layout/LayoutWrapperForm.tsx b/apps/web/src/components/layout/LayoutWrapperForm.tsx similarity index 87% rename from apps/hq/src/components/layout/LayoutWrapperForm.tsx rename to apps/web/src/components/layout/LayoutWrapperForm.tsx index 37033ddf4d..28f37917f8 100644 --- a/apps/hq/src/components/layout/LayoutWrapperForm.tsx +++ b/apps/web/src/components/layout/LayoutWrapperForm.tsx @@ -14,22 +14,22 @@ export default function LayoutWrapperForm({ children }) { () => [ { name: "Form", - href: `/app/teams/${router.query.teamId}/forms/${router.query.formId}/`, + href: `/workspaces/${router.query.workspaceId}/forms/${router.query.formId}/`, current: pathname.endsWith(router.query.formId?.toString()), }, { name: "Pipelines", - href: `/app/teams/${router.query.teamId}/forms/${router.query.formId}/pipelines/`, + href: `/workspaces/${router.query.workspaceId}/forms/${router.query.formId}/pipelines/`, current: pathname.includes("pipelines"), }, { name: "Summary", - href: `/app/teams/${router.query.teamId}/forms/${router.query.formId}/summary/`, + href: `/workspaces/${router.query.workspaceId}/forms/${router.query.formId}/summary/`, current: pathname.includes("summary"), }, { name: "Submissions", - href: `/app/teams/${router.query.teamId}/forms/${router.query.formId}/submissions/`, + href: `/workspaces/${router.query.workspaceId}/forms/${router.query.formId}/submissions/`, current: pathname.includes("submissions"), }, ], diff --git a/apps/hq/src/components/layout/LayoutWrapperTeam.tsx b/apps/web/src/components/layout/LayoutWrapperWorkspace.tsx similarity index 96% rename from apps/hq/src/components/layout/LayoutWrapperTeam.tsx rename to apps/web/src/components/layout/LayoutWrapperWorkspace.tsx index c2b620406d..0afa56e049 100644 --- a/apps/hq/src/components/layout/LayoutWrapperTeam.tsx +++ b/apps/web/src/components/layout/LayoutWrapperWorkspace.tsx @@ -10,7 +10,7 @@ import { usePathname } from "next/navigation"; import { useRouter } from "next/router"; import { Fragment, useMemo, useState } from "react"; -export default function LayoutWrapperTeam({ children }) { +export default function LayoutWrapperWorkspace({ children }) { const router = useRouter(); const [mobileMenuOpen, setMobileMenuOpen] = useState(false); const pathname = usePathname(); @@ -18,19 +18,19 @@ export default function LayoutWrapperTeam({ children }) { () => [ { name: "Forms", - href: `/app/teams/${router.query.teamId}/forms`, + href: `/workspaces/${router.query.workspaceId}/forms`, icon: FormIcon, current: pathname.includes("/form"), }, { name: "Customers", - href: `/app/teams/${router.query.teamId}/customers`, + href: `/workspaces/${router.query.workspaceId}/customers`, icon: CustomersIcon, current: pathname.includes("/customers"), }, /* { name: "Settings", - href: `/app/teams/${router.query.teamId}/settings`, + href: `/workspaces/${router.query.workspaceId}/settings`, icon: Cog8ToothIcon, current: pathname.includes("/settings"), }, */ diff --git a/apps/hq/src/components/me/ProfileSettingsPage.tsx b/apps/web/src/components/me/ProfileSettingsPage.tsx similarity index 100% rename from apps/hq/src/components/me/ProfileSettingsPage.tsx rename to apps/web/src/components/me/ProfileSettingsPage.tsx diff --git a/apps/hq/src/components/settings/SettingsPage.tsx b/apps/web/src/components/settings/SettingsPage.tsx similarity index 74% rename from apps/hq/src/components/settings/SettingsPage.tsx rename to apps/web/src/components/settings/SettingsPage.tsx index 4bf3599ea5..c49d597b69 100644 --- a/apps/hq/src/components/settings/SettingsPage.tsx +++ b/apps/web/src/components/settings/SettingsPage.tsx @@ -2,16 +2,18 @@ import LoadingSpinner from "@/components/LoadingSpinner"; import { useForms } from "@/lib/forms"; -import { useTeam } from "@/lib/teams"; +import { useWorkspace } from "@/lib/workspaces"; import { InformationCircleIcon } from "@heroicons/react/20/solid"; import { useRouter } from "next/router"; export default function SettingsPage() { const router = useRouter(); - const { forms, isLoadingForms, isErrorForms } = useForms(router.query.teamId?.toString()); - const { team, isLoadingTeam, isErrorTeam } = useTeam(router.query.teamId?.toString()); + const { forms, isLoadingForms, isErrorForms } = useForms(router.query.workspaceId?.toString()); + const { workspace, isLoadingWorkspace, isErrorWorkspace } = useWorkspace( + router.query.workspaceId?.toString() + ); - if (isLoadingForms || isLoadingTeam) { + if (isLoadingForms || isLoadingWorkspace) { return (
    @@ -19,7 +21,7 @@ export default function SettingsPage() { ); } - if (isErrorForms || isErrorTeam) { + if (isErrorForms || isErrorWorkspace) { return
    Error loading ressources. Maybe you don‘t have enough access rights
    ; } return ( @@ -28,7 +30,7 @@ export default function SettingsPage() {

    Settings - {team.name} + {workspace.name}

    @@ -38,7 +40,9 @@ export default function SettingsPage() {
    -

    Team Management Settings coming to Formbricks HQ soon.

    +

    + Workspace Management Settings coming to Formbricks HQ soon. +

    diff --git a/apps/hq/src/images/avatar-placeholder.png b/apps/web/src/images/avatar-placeholder.png similarity index 100% rename from apps/hq/src/images/avatar-placeholder.png rename to apps/web/src/images/avatar-placeholder.png diff --git a/apps/hq/src/lib/apiHelper.ts b/apps/web/src/lib/apiHelper.ts similarity index 100% rename from apps/hq/src/lib/apiHelper.ts rename to apps/web/src/lib/apiHelper.ts diff --git a/apps/hq/src/lib/apiKeys.ts b/apps/web/src/lib/apiKeys.ts similarity index 100% rename from apps/hq/src/lib/apiKeys.ts rename to apps/web/src/lib/apiKeys.ts diff --git a/apps/hq/src/lib/auth.ts b/apps/web/src/lib/auth.ts similarity index 100% rename from apps/hq/src/lib/auth.ts rename to apps/web/src/lib/auth.ts diff --git a/apps/hq/src/lib/customers.ts b/apps/web/src/lib/customers.ts similarity index 51% rename from apps/hq/src/lib/customers.ts rename to apps/web/src/lib/customers.ts index e35943664f..687bbb556b 100644 --- a/apps/hq/src/lib/customers.ts +++ b/apps/web/src/lib/customers.ts @@ -1,8 +1,8 @@ import useSWR from "swr"; import { fetcher } from "./utils"; -export const useCustomers = (teamId: string) => { - const { data, error, mutate } = useSWR(`/api/teams/${teamId}/customers`, fetcher); +export const useCustomers = (workspaceId: string) => { + const { data, error, mutate } = useSWR(`/api/workspaces/${workspaceId}/customers`, fetcher); return { customers: data, @@ -12,8 +12,8 @@ export const useCustomers = (teamId: string) => { }; }; -export const useCustomer = (teamId: string, customerId: string) => { - const { data, error, mutate } = useSWR(`/api/teams/${teamId}/customers/${customerId}`, fetcher); +export const useCustomer = (workspaceId: string, customerId: string) => { + const { data, error, mutate } = useSWR(`/api/workspaces/${workspaceId}/customers/${customerId}`, fetcher); return { customer: data, @@ -23,9 +23,9 @@ export const useCustomer = (teamId: string, customerId: string) => { }; }; -export const deleteCustomer = async (id: string, teamId: string) => { +export const deleteCustomer = async (id: string, workspaceId: string) => { try { - await fetch(`/api/teams/${teamId}/customers/${id}`, { + await fetch(`/api/workspaces/${workspaceId}/customers/${id}`, { method: "DELETE", }); } catch (error) { diff --git a/apps/hq/src/lib/email.ts b/apps/web/src/lib/email.ts similarity index 94% rename from apps/hq/src/lib/email.ts rename to apps/web/src/lib/email.ts index b13037ebb6..f8d799be50 100644 --- a/apps/hq/src/lib/email.ts +++ b/apps/web/src/lib/email.ts @@ -45,7 +45,7 @@ export const sendVerificationEmail = async (user) => { The link is valid for one day. If it has expired please request a new token here:
    ${verificationRequestLink}

    - Your Formbricks Team`, + Your Formbricks Workspace`, }); }; @@ -66,7 +66,7 @@ export const sendForgotPasswordEmail = async (user) => {
    Your password won't change until you access the link above and create a new one.

    - Your Formbricks Team`, + Your Formbricks Workspace`, }); }; @@ -76,13 +76,13 @@ export const sendPasswordResetNotifyEmail = async (user) => { subject: "Your Formbricks password has been changed", html: `We're contacting you to notify you that your password has been changed.

    - Your Formbricks Team`, + Your Formbricks Workspace`, }); }; export const sendSubmissionEmail = async ( email: string, - teamId, + workspaceId, formId, formLabel: string, schema: any, @@ -104,7 +104,7 @@ export const sendSubmissionEmail = async ( Click here to see new submission. + }/workspaces/${workspaceId}/forms/${formId}/feedback">here to see new submission. ${submission.customer?.email ? "
    You can reply to this email to contact the user directly." : ""}`, }); }; diff --git a/apps/hq/src/lib/forms.ts b/apps/web/src/lib/forms.ts similarity index 77% rename from apps/hq/src/lib/forms.ts rename to apps/web/src/lib/forms.ts index 88dc16c75c..99f8edb57a 100644 --- a/apps/hq/src/lib/forms.ts +++ b/apps/web/src/lib/forms.ts @@ -1,8 +1,8 @@ import useSWR from "swr"; import { fetcher } from "./utils"; -export const useForms = (teamId: string) => { - const { data, error, mutate } = useSWR(`/api/teams/${teamId}/forms`, fetcher); +export const useForms = (workspaceId: string) => { + const { data, error, mutate } = useSWR(`/api/workspaces/${workspaceId}/forms`, fetcher); return { forms: data, @@ -12,8 +12,8 @@ export const useForms = (teamId: string) => { }; }; -export const useForm = (id: string, teamId: string) => { - const { data, error, mutate } = useSWR(`/api/teams/${teamId}/forms/${id}`, fetcher); +export const useForm = (id: string, workspaceId: string) => { + const { data, error, mutate } = useSWR(`/api/workspaces/${workspaceId}/forms/${id}`, fetcher); return { form: data, @@ -25,7 +25,7 @@ export const useForm = (id: string, teamId: string) => { export const persistForm = async (form) => { try { - await fetch(`/api/teams/${form.teamId}/forms/${form.id}/`, { + await fetch(`/api/workspaces/${form.workspaceId}/forms/${form.id}/`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(form), @@ -35,9 +35,9 @@ export const persistForm = async (form) => { } }; -export const createForm = async (teamId: string, form = {}) => { +export const createForm = async (workspaceId: string, form = {}) => { try { - const res = await fetch(`/api/teams/${teamId}/forms`, { + const res = await fetch(`/api/workspaces/${workspaceId}/forms`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(form), @@ -49,9 +49,9 @@ export const createForm = async (teamId: string, form = {}) => { } }; -export const deleteForm = async (teamId: string, formId: string) => { +export const deleteForm = async (workspaceId: string, formId: string) => { try { - await fetch(`/api/teams/${teamId}/forms/${formId}`, { + await fetch(`/api/workspaces/${workspaceId}/forms/${formId}`, { method: "DELETE", }); } catch (error) { diff --git a/apps/hq/src/lib/jwt.ts b/apps/web/src/lib/jwt.ts similarity index 100% rename from apps/hq/src/lib/jwt.ts rename to apps/web/src/lib/jwt.ts diff --git a/apps/hq/src/lib/memberships.ts b/apps/web/src/lib/memberships.ts similarity index 100% rename from apps/hq/src/lib/memberships.ts rename to apps/web/src/lib/memberships.ts diff --git a/apps/hq/src/lib/pipelines.ts b/apps/web/src/lib/pipelines.ts similarity index 54% rename from apps/hq/src/lib/pipelines.ts rename to apps/web/src/lib/pipelines.ts index 1e79936d12..2d18707bcc 100644 --- a/apps/hq/src/lib/pipelines.ts +++ b/apps/web/src/lib/pipelines.ts @@ -2,8 +2,8 @@ import useSWR from "swr"; import { fetcher } from "./utils"; -export const usePipelines = (formId: string, teamId: string) => { - const { data, error, mutate } = useSWR(`/api/teams/${teamId}/forms/${formId}/pipelines`, fetcher); +export const usePipelines = (formId: string, workspaceId: string) => { + const { data, error, mutate } = useSWR(`/api/workspaces/${workspaceId}/forms/${formId}/pipelines`, fetcher); return { pipelines: data, @@ -13,9 +13,9 @@ export const usePipelines = (formId: string, teamId: string) => { }; }; -export const usePipeline = (teamId: string, formId: string, pipelineId: string) => { +export const usePipeline = (workspaceId: string, formId: string, pipelineId: string) => { const { data, error, mutate } = useSWR( - `/api/teams/${teamId}/forms/${formId}/pipelines/${pipelineId}`, + `/api/workspaces/${workspaceId}/forms/${formId}/pipelines/${pipelineId}`, fetcher ); @@ -27,9 +27,9 @@ export const usePipeline = (teamId: string, formId: string, pipelineId: string) }; }; -export const persistPipeline = async (formId, teamId, pipeline) => { +export const persistPipeline = async (formId, workspaceId, pipeline) => { try { - await fetch(`/api/teams/${teamId}/forms/${formId}/pipelines/${pipeline.id}/`, { + await fetch(`/api/workspaces/${workspaceId}/forms/${formId}/pipelines/${pipeline.id}/`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(pipeline), @@ -39,9 +39,9 @@ export const persistPipeline = async (formId, teamId, pipeline) => { } }; -export const createPipeline = async (formId: string, teamId: string, pipeline = {}) => { +export const createPipeline = async (formId: string, workspaceId: string, pipeline = {}) => { try { - const res = await fetch(`/api/teams/${teamId}/forms/${formId}/pipelines`, { + const res = await fetch(`/api/workspaces/${workspaceId}/forms/${formId}/pipelines`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(pipeline), @@ -53,9 +53,9 @@ export const createPipeline = async (formId: string, teamId: string, pipeline = } }; -export const deletePipeline = async (formId: string, teamId: string, pipelineId: string) => { +export const deletePipeline = async (formId: string, workspaceId: string, pipelineId: string) => { try { - await fetch(`/api/teams/${teamId}/forms/${formId}/pipelines/${pipelineId}`, { + await fetch(`/api/workspaces/${workspaceId}/forms/${formId}/pipelines/${pipelineId}`, { method: "DELETE", }); } catch (error) { diff --git a/apps/hq/src/lib/pipelinesHandler.ts b/apps/web/src/lib/pipelinesHandler.ts similarity index 92% rename from apps/hq/src/lib/pipelinesHandler.ts rename to apps/web/src/lib/pipelinesHandler.ts index b2381adeb5..1e7b7919fb 100644 --- a/apps/hq/src/lib/pipelinesHandler.ts +++ b/apps/web/src/lib/pipelinesHandler.ts @@ -50,7 +50,7 @@ async function handleEmailNotification(pipeline, form, submission) { const { email } = pipeline.config.valueOf() as { email: string }; if (pipeline.events.includes("submissionCreated")) { - await sendSubmissionEmail(email, form.teamId, form.id, form.label, form.schema, submission); + await sendSubmissionEmail(email, form.workspaceId, form.id, form.label, form.schema, submission); } } @@ -64,7 +64,7 @@ async function handleSlackNotification(pipeline, form, submission) { type: "section", text: { type: "mrkdwn", - text: `Someone just filled out your form "${form.label}". <${process.env.NEXTAUTH_URL}/app/teams/${form.teamId}/forms/${form.id}/feedback|View in Formbricks>`, + text: `Someone just filled out your form "${form.label}". <${process.env.NEXTAUTH_URL}/workspaces/${form.workspaceId}/forms/${form.id}/feedback|View in Formbricks>`, }, }, { diff --git a/apps/hq/src/lib/posthog.ts b/apps/web/src/lib/posthog.ts similarity index 100% rename from apps/hq/src/lib/posthog.ts rename to apps/web/src/lib/posthog.ts diff --git a/apps/hq/src/lib/session.ts b/apps/web/src/lib/session.ts similarity index 100% rename from apps/hq/src/lib/session.ts rename to apps/web/src/lib/session.ts diff --git a/apps/hq/src/lib/submissions.ts b/apps/web/src/lib/submissions.ts similarity index 64% rename from apps/hq/src/lib/submissions.ts rename to apps/web/src/lib/submissions.ts index e9b7d6c0c1..5fbe51584b 100644 --- a/apps/hq/src/lib/submissions.ts +++ b/apps/web/src/lib/submissions.ts @@ -1,8 +1,11 @@ import useSWR from "swr"; import { fetcher } from "@/lib/utils"; -export const useSubmissions = (teamId: string, formId: string) => { - const { data, error, mutate } = useSWR(`/api/teams/${teamId}/forms/${formId}/submissions`, fetcher); +export const useSubmissions = (workspaceId: string, formId: string) => { + const { data, error, mutate } = useSWR( + `/api/workspaces/${workspaceId}/forms/${formId}/submissions`, + fetcher + ); return { submissions: data, @@ -12,9 +15,9 @@ export const useSubmissions = (teamId: string, formId: string) => { }; }; -export const deleteSubmission = async (teamId: string, formId: string, submissionId: string) => { +export const deleteSubmission = async (workspaceId: string, formId: string, submissionId: string) => { try { - await fetch(`/api/teams/${teamId}/forms/${formId}/submissions/${submissionId}`, { + await fetch(`/api/workspaces/${workspaceId}/forms/${formId}/submissions/${submissionId}`, { method: "DELETE", }); } catch (error) { @@ -23,9 +26,9 @@ export const deleteSubmission = async (teamId: string, formId: string, submissio } }; -export const persistSubmission = async (submission, teamId) => { +export const persistSubmission = async (submission, workspaceId) => { try { - await fetch(`/api/teams/${teamId}/forms/${submission.formId}/submissions/${submission.id}/`, { + await fetch(`/api/workspaces/${workspaceId}/forms/${submission.formId}/submissions/${submission.id}/`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(submission), diff --git a/apps/hq/src/lib/telemetry.ts b/apps/web/src/lib/telemetry.ts similarity index 100% rename from apps/hq/src/lib/telemetry.ts rename to apps/web/src/lib/telemetry.ts diff --git a/apps/hq/src/lib/token.ts b/apps/web/src/lib/token.ts similarity index 100% rename from apps/hq/src/lib/token.ts rename to apps/web/src/lib/token.ts diff --git a/apps/hq/src/lib/users.ts b/apps/web/src/lib/users.ts similarity index 100% rename from apps/hq/src/lib/users.ts rename to apps/web/src/lib/users.ts diff --git a/apps/hq/src/lib/utils.ts b/apps/web/src/lib/utils.ts similarity index 91% rename from apps/hq/src/lib/utils.ts rename to apps/web/src/lib/utils.ts index 6214a820d3..32d3977ce5 100644 --- a/apps/hq/src/lib/utils.ts +++ b/apps/web/src/lib/utils.ts @@ -1,6 +1,7 @@ import crypto from "crypto"; import intlFormat from "date-fns/intlFormat"; import { formatDistance } from "date-fns"; +import platform from "platform"; export const fetcher = async (url) => { const res = await fetch(url); @@ -86,3 +87,8 @@ export const hashString = (string: string) => { export const onlyUnique = (value, index, self) => { return self.indexOf(value) === index; }; + +export const parseUserAgent = (userAgent: string) => { + const info = platform.parse(userAgent); + return info.description; +}; diff --git a/apps/web/src/lib/workspaces.ts b/apps/web/src/lib/workspaces.ts new file mode 100644 index 0000000000..69c42c6f3a --- /dev/null +++ b/apps/web/src/lib/workspaces.ts @@ -0,0 +1,13 @@ +import useSWR from "swr"; +import { fetcher } from "./utils"; + +export const useWorkspace = (id: string) => { + const { data, error, mutate } = useSWR(`/api/workspaces/${id}/`, fetcher); + + return { + workspace: data, + isLoadingWorkspace: !error && !data, + isErrorWorkspace: error, + mutateWorkspace: mutate, + }; +}; diff --git a/apps/hq/src/pages/_app.tsx b/apps/web/src/pages/_app.tsx similarity index 100% rename from apps/hq/src/pages/_app.tsx rename to apps/web/src/pages/_app.tsx diff --git a/apps/hq/src/pages/_document.tsx b/apps/web/src/pages/_document.tsx similarity index 100% rename from apps/hq/src/pages/_document.tsx rename to apps/web/src/pages/_document.tsx diff --git a/apps/hq/src/pages/_error.js b/apps/web/src/pages/_error.js similarity index 100% rename from apps/hq/src/pages/_error.js rename to apps/web/src/pages/_error.js diff --git a/apps/hq/src/pages/api/auth/[...nextauth].ts b/apps/web/src/pages/api/auth/[...nextauth].ts similarity index 98% rename from apps/hq/src/pages/api/auth/[...nextauth].ts rename to apps/web/src/pages/api/auth/[...nextauth].ts index f406c59706..ec7f07a9b6 100644 --- a/apps/hq/src/pages/api/auth/[...nextauth].ts +++ b/apps/web/src/pages/api/auth/[...nextauth].ts @@ -226,14 +226,14 @@ export const authOptions: NextAuthOptions = { accounts: { create: [{ ...account }], }, - teams: { + workspaces: { create: [ { accepted: true, role: "owner", - team: { + workspace: { create: { - name: `${user.name}'s Team`, + name: `${user.name}'s Workspace`, }, }, }, diff --git a/apps/hq/src/pages/api/capture/forms/[formId]/schema/index.ts b/apps/web/src/pages/api/capture/forms/[formId]/schema/index.ts similarity index 100% rename from apps/hq/src/pages/api/capture/forms/[formId]/schema/index.ts rename to apps/web/src/pages/api/capture/forms/[formId]/schema/index.ts diff --git a/apps/hq/src/pages/api/capture/forms/[formId]/submissions/index.ts b/apps/web/src/pages/api/capture/forms/[formId]/submissions/index.ts similarity index 90% rename from apps/hq/src/pages/api/capture/forms/[formId]/submissions/index.ts rename to apps/web/src/pages/api/capture/forms/[formId]/submissions/index.ts index ad2bf91f70..51fe74bf43 100644 --- a/apps/hq/src/pages/api/capture/forms/[formId]/submissions/index.ts +++ b/apps/web/src/pages/api/capture/forms/[formId]/submissions/index.ts @@ -43,14 +43,14 @@ export default async function handle(req: NextApiRequest, res: NextApiResponse) event.data.customer = { connectOrCreate: { where: { - id_teamId: { + id_workspaceId: { id: submission.customer.id, - teamId: form.teamId, + workspaceId: form.workspaceId, }, }, create: { id: customerId, - team: { connect: { id: form.teamId } }, + workspace: { connect: { id: form.workspaceId } }, data: customerData, }, }, @@ -61,7 +61,7 @@ export default async function handle(req: NextApiRequest, res: NextApiResponse) const submissionResult = await prisma.submission.create(event); await runPipelines(form, submission); // tracking - capturePosthogEvent(form.teamId, "submission received", { + capturePosthogEvent(form.workspaceId, "submission received", { formId, }); captureTelemetry("submission received"); diff --git a/apps/hq/src/pages/api/memberships/index.ts b/apps/web/src/pages/api/memberships/index.ts similarity index 90% rename from apps/hq/src/pages/api/memberships/index.ts rename to apps/web/src/pages/api/memberships/index.ts index 1fbfa00e56..1b8b74d20d 100644 --- a/apps/hq/src/pages/api/memberships/index.ts +++ b/apps/web/src/pages/api/memberships/index.ts @@ -9,15 +9,15 @@ export default async function handle(req: NextApiRequest, res: NextApiResponse) return res.status(401).json({ message: "Not authenticated" }); } - // GET /api/teams - // Get all of my teams + // GET /api/workspaces + // Get all of my workspaces if (req.method === "GET") { const memberships = await prisma.membership.findMany({ where: { user: { email: session.email }, }, include: { - team: true, + workspace: true, }, }); return res.json(memberships); diff --git a/apps/hq/src/pages/api/users/forgot-password.tsx b/apps/web/src/pages/api/users/forgot-password.tsx similarity index 100% rename from apps/hq/src/pages/api/users/forgot-password.tsx rename to apps/web/src/pages/api/users/forgot-password.tsx diff --git a/apps/hq/src/pages/api/users/index.tsx b/apps/web/src/pages/api/users/index.tsx similarity index 94% rename from apps/hq/src/pages/api/users/index.tsx rename to apps/web/src/pages/api/users/index.tsx index c0839824c5..25c7fbc1d7 100644 --- a/apps/hq/src/pages/api/users/index.tsx +++ b/apps/web/src/pages/api/users/index.tsx @@ -21,14 +21,14 @@ export default async function handle(req: NextApiRequest, res: NextApiResponse) const userData = await prisma.user.create({ data: { ...user, - teams: { + workspaces: { create: [ { accepted: true, role: "owner", - team: { + workspace: { create: { - name: `${user.name}'s Team`, + name: `${user.name}'s Workspace`, }, }, }, diff --git a/apps/hq/src/pages/api/users/me/api-keys/[apiKeyId]/index.ts b/apps/web/src/pages/api/users/me/api-keys/[apiKeyId]/index.ts similarity index 100% rename from apps/hq/src/pages/api/users/me/api-keys/[apiKeyId]/index.ts rename to apps/web/src/pages/api/users/me/api-keys/[apiKeyId]/index.ts diff --git a/apps/hq/src/pages/api/users/me/api-keys/index.ts b/apps/web/src/pages/api/users/me/api-keys/index.ts similarity index 100% rename from apps/hq/src/pages/api/users/me/api-keys/index.ts rename to apps/web/src/pages/api/users/me/api-keys/index.ts diff --git a/apps/hq/src/pages/api/users/me/index.ts b/apps/web/src/pages/api/users/me/index.ts similarity index 100% rename from apps/hq/src/pages/api/users/me/index.ts rename to apps/web/src/pages/api/users/me/index.ts diff --git a/apps/hq/src/pages/api/users/reset-password.tsx b/apps/web/src/pages/api/users/reset-password.tsx similarity index 100% rename from apps/hq/src/pages/api/users/reset-password.tsx rename to apps/web/src/pages/api/users/reset-password.tsx diff --git a/apps/hq/src/pages/api/users/verification-email.tsx b/apps/web/src/pages/api/users/verification-email.tsx similarity index 100% rename from apps/hq/src/pages/api/users/verification-email.tsx rename to apps/web/src/pages/api/users/verification-email.tsx diff --git a/apps/hq/src/pages/api/teams/[teamId]/customers/[customerId]/index.ts b/apps/web/src/pages/api/workspaces/[workspaceId]/customers/[customerId]/index.ts similarity index 70% rename from apps/hq/src/pages/api/teams/[teamId]/customers/[customerId]/index.ts rename to apps/web/src/pages/api/workspaces/[workspaceId]/customers/[customerId]/index.ts index 149108afe5..08f0073fba 100644 --- a/apps/hq/src/pages/api/teams/[teamId]/customers/[customerId]/index.ts +++ b/apps/web/src/pages/api/workspaces/[workspaceId]/customers/[customerId]/index.ts @@ -9,31 +9,33 @@ export default async function handle(req: NextApiRequest, res: NextApiResponse) return res.status(401).json({ message: "Not authenticated" }); } - const teamId = req.query.teamId.toString(); + const workspaceId = req.query.workspaceId.toString(); const customerId = req.query.customerId.toString(); - // check team permission + // check workspace permission const membership = await prisma.membership.findUnique({ where: { - userId_teamId: { + userId_workspaceId: { userId: user.id, - teamId, + workspaceId, }, }, }); if (membership === null) { - return res.status(403).json({ message: "You don't have access to this team or this team doesn't exist" }); + return res + .status(403) + .json({ message: "You don't have access to this workspace or this workspace doesn't exist" }); } - // GET /api/teams[teamId]/customers/[customerId] - // Get a specific team + // GET /api/workspaces[workspaceId]/customers/[customerId] + // Get a specific workspace if (req.method === "GET") { const customer = await prisma.customer.findUnique({ where: { - id_teamId: { + id_workspaceId: { id: customerId, - teamId, + workspaceId, }, }, include: { @@ -44,15 +46,15 @@ export default async function handle(req: NextApiRequest, res: NextApiResponse) return res.json(customer); } - // POST /api/teams[teamId]/customer/[customerId] + // POST /api/workspaces[workspaceId]/customer/[customerId] // Replace a specific customer else if (req.method === "POST") { const data = { ...req.body, updatedAt: new Date() }; const prismaRes = await prisma.customer.update({ where: { - id_teamId: { + id_workspaceId: { id: customerId, - teamId, + workspaceId, }, }, data, @@ -60,14 +62,14 @@ export default async function handle(req: NextApiRequest, res: NextApiResponse) return res.json(prismaRes); } - // Delete /api/teams[teamId]/customer/[customerId] + // Delete /api/workspaces[workspaceId]/customer/[customerId] // Deletes a single customer else if (req.method === "DELETE") { const prismaRes = await prisma.customer.delete({ where: { - id_teamId: { + id_workspaceId: { id: customerId, - teamId: teamId, + workspaceId: workspaceId, }, }, }); diff --git a/apps/hq/src/pages/api/teams/[teamId]/customers/index.ts b/apps/web/src/pages/api/workspaces/[workspaceId]/customers/index.ts similarity index 69% rename from apps/hq/src/pages/api/teams/[teamId]/customers/index.ts rename to apps/web/src/pages/api/workspaces/[workspaceId]/customers/index.ts index 8ff2831801..5d10257faa 100644 --- a/apps/hq/src/pages/api/teams/[teamId]/customers/index.ts +++ b/apps/web/src/pages/api/workspaces/[workspaceId]/customers/index.ts @@ -9,28 +9,30 @@ export default async function handle(req: NextApiRequest, res: NextApiResponse) return res.status(401).json({ message: "Not authenticated" }); } - const teamId = req.query.teamId.toString(); + const workspaceId = req.query.workspaceId.toString(); - // check team permission + // check workspace permission const membership = await prisma.membership.findUnique({ where: { - userId_teamId: { + userId_workspaceId: { userId: user.id, - teamId, + workspaceId, }, }, }); if (membership === null) { - return res.status(403).json({ message: "You don't have access to this team or this team doesn't exist" }); + return res + .status(403) + .json({ message: "You don't have access to this workspace or this workspace doesn't exist" }); } - // GET /api/teams[teamId]/customers - // Get all customers of a specific team + // GET /api/workspaces[workspaceId]/customers + // Get all customers of a specific workspace if (req.method === "GET") { const forms = await prisma.customer.findMany({ where: { - team: { - id: teamId, + workspace: { + id: workspaceId, }, }, include: { diff --git a/apps/hq/src/pages/api/teams/[teamId]/forms/[formId]/index.ts b/apps/web/src/pages/api/workspaces/[workspaceId]/forms/[formId]/index.ts similarity index 72% rename from apps/hq/src/pages/api/teams/[teamId]/forms/[formId]/index.ts rename to apps/web/src/pages/api/workspaces/[workspaceId]/forms/[formId]/index.ts index a35d12b04f..5fc4d624b0 100644 --- a/apps/hq/src/pages/api/teams/[teamId]/forms/[formId]/index.ts +++ b/apps/web/src/pages/api/workspaces/[workspaceId]/forms/[formId]/index.ts @@ -10,37 +10,39 @@ export default async function handle(req: NextApiRequest, res: NextApiResponse) return res.status(401).json({ message: "Not authenticated" }); } - const teamId = req.query.teamId.toString(); + const workspaceId = req.query.workspaceId.toString(); const formId = req.query.formId.toString(); - // check team permission + // check workspace permission const membership = await prisma.membership.findUnique({ where: { - userId_teamId: { + userId_workspaceId: { userId: user.id, - teamId, + workspaceId, }, }, }); if (membership === null) { - return res.status(403).json({ message: "You don't have access to this team or this team doesn't exist" }); + return res + .status(403) + .json({ message: "You don't have access to this workspace or this workspace doesn't exist" }); } - // GET /api/teams[teamId]/forms/[formId] - // Get a specific team + // GET /api/workspaces[workspaceId]/forms/[formId] + // Get a specific workspace if (req.method === "GET") { const forms = await prisma.form.findFirst({ where: { id: formId, - teamId, + workspaceId, }, }); return res.json(forms); } - // POST /api/teams[teamId]/forms/[formId] + // POST /api/workspaces[workspaceId]/forms/[formId] // Replace a specific form else if (req.method === "POST") { const data = { ...req.body, updatedAt: new Date() }; @@ -51,13 +53,13 @@ export default async function handle(req: NextApiRequest, res: NextApiResponse) return res.json(prismaRes); } - // Delete /api/teams[teamId]/forms/[formId] + // Delete /api/workspaces[workspaceId]/forms/[formId] // Deletes a single form else if (req.method === "DELETE") { const prismaRes = await prisma.form.delete({ where: { id: formId }, }); - capturePosthogEvent(teamId, "form created", { + capturePosthogEvent(workspaceId, "form created", { formId, }); return res.json(prismaRes); diff --git a/apps/hq/src/pages/api/teams/[teamId]/forms/[formId]/pipelines/[pipelineId]/index.ts b/apps/web/src/pages/api/workspaces/[workspaceId]/forms/[formId]/pipelines/[pipelineId]/index.ts similarity index 73% rename from apps/hq/src/pages/api/teams/[teamId]/forms/[formId]/pipelines/[pipelineId]/index.ts rename to apps/web/src/pages/api/workspaces/[workspaceId]/forms/[formId]/pipelines/[pipelineId]/index.ts index 74b493f6ce..a73850ada5 100644 --- a/apps/hq/src/pages/api/teams/[teamId]/forms/[formId]/pipelines/[pipelineId]/index.ts +++ b/apps/web/src/pages/api/workspaces/[workspaceId]/forms/[formId]/pipelines/[pipelineId]/index.ts @@ -10,24 +10,26 @@ export default async function handle(req: NextApiRequest, res: NextApiResponse) return res.status(401).json({ message: "Not authenticated" }); } - const teamId = req.query.teamId.toString(); + const workspaceId = req.query.workspaceId.toString(); const formId = req.query.formId.toString(); const pipelineId = req.query.pipelineId.toString(); - // check team permission + // check workspace permission const membership = await prisma.membership.findUnique({ where: { - userId_teamId: { + userId_workspaceId: { userId: user.id, - teamId, + workspaceId, }, }, }); if (membership === null) { - return res.status(403).json({ message: "You don't have access to this team or this team doesn't exist" }); + return res + .status(403) + .json({ message: "You don't have access to this workspace or this workspace doesn't exist" }); } - // GET /api/teams[teamId]/forms/[formId]/pipelines/[pipelineId] + // GET /api/workspaces[workspaceId]/forms/[formId]/pipelines/[pipelineId] // Get a specific pipeline if (req.method === "GET") { const pipeline = await prisma.pipeline.findFirst({ @@ -40,7 +42,7 @@ export default async function handle(req: NextApiRequest, res: NextApiResponse) return res.json(pipeline); } - // POST /api/teams[teamId]/forms/[formId]/pipelines/[pipelineId] + // POST /api/workspaces[workspaceId]/forms/[formId]/pipelines/[pipelineId] // Replace a specific pipeline else if (req.method === "POST") { const data = { ...req.body, updatedAt: new Date() }; @@ -51,13 +53,13 @@ export default async function handle(req: NextApiRequest, res: NextApiResponse) return res.json(prismaRes); } - // Delete /api/teams[teamId]/forms/[formId]/pipelines/[pipelineId] + // Delete /api/workspaces[workspaceId]/forms/[formId]/pipelines/[pipelineId] // Deletes a single form else if (req.method === "DELETE") { const prismaRes = await prisma.pipeline.delete({ where: { id: pipelineId }, }); - capturePosthogEvent(teamId, "pipeline deleted", { + capturePosthogEvent(workspaceId, "pipeline deleted", { formId, pipelineId, }); diff --git a/apps/hq/src/pages/api/teams/[teamId]/forms/[formId]/pipelines/index.ts b/apps/web/src/pages/api/workspaces/[workspaceId]/forms/[formId]/pipelines/index.ts similarity index 75% rename from apps/hq/src/pages/api/teams/[teamId]/forms/[formId]/pipelines/index.ts rename to apps/web/src/pages/api/workspaces/[workspaceId]/forms/[formId]/pipelines/index.ts index ad00a02fe5..ac926614a7 100644 --- a/apps/hq/src/pages/api/teams/[teamId]/forms/[formId]/pipelines/index.ts +++ b/apps/web/src/pages/api/workspaces/[workspaceId]/forms/[formId]/pipelines/index.ts @@ -10,23 +10,25 @@ export default async function handle(req: NextApiRequest, res: NextApiResponse) return res.status(401).json({ message: "Not authenticated" }); } - const teamId = req.query.teamId.toString(); + const workspaceId = req.query.workspaceId.toString(); const formId = req.query.formId.toString(); - // check team permission + // check workspace permission const membership = await prisma.membership.findUnique({ where: { - userId_teamId: { + userId_workspaceId: { userId: user.id, - teamId, + workspaceId, }, }, }); if (membership === null) { - return res.status(403).json({ message: "You don't have access to this team or this team doesn't exist" }); + return res + .status(403) + .json({ message: "You don't have access to this workspace or this workspace doesn't exist" }); } - // GET /api/teams[teamId]/forms/[formId]/pipelines + // GET /api/workspaces[workspaceId]/forms/[formId]/pipelines // Get pipelines if (req.method === "GET") { // get submission @@ -34,7 +36,7 @@ export default async function handle(req: NextApiRequest, res: NextApiResponse) where: { form: { id: formId, - teamId, + workspaceId, }, }, }); @@ -42,7 +44,7 @@ export default async function handle(req: NextApiRequest, res: NextApiResponse) return res.json(pipelines); } - // POST /api/teams[teamId]/forms/[formId]/pipelines + // POST /api/workspaces[workspaceId]/forms/[formId]/pipelines // Create a new pipeline // Required fields in body: name, type // Optional fields in body: enabled, config @@ -56,7 +58,7 @@ export default async function handle(req: NextApiRequest, res: NextApiResponse) form: { connect: { id: formId } }, }, }); - capturePosthogEvent(teamId, "pipeline created", { + capturePosthogEvent(workspaceId, "pipeline created", { formId, pipelineId: result.id, }); diff --git a/apps/hq/src/pages/api/teams/[teamId]/forms/[formId]/submissions/[submissionId]/index.ts b/apps/web/src/pages/api/workspaces/[workspaceId]/forms/[formId]/submissions/[submissionId]/index.ts similarity index 75% rename from apps/hq/src/pages/api/teams/[teamId]/forms/[formId]/submissions/[submissionId]/index.ts rename to apps/web/src/pages/api/workspaces/[workspaceId]/forms/[formId]/submissions/[submissionId]/index.ts index 46545bf9d4..535df85622 100644 --- a/apps/hq/src/pages/api/teams/[teamId]/forms/[formId]/submissions/[submissionId]/index.ts +++ b/apps/web/src/pages/api/workspaces/[workspaceId]/forms/[formId]/submissions/[submissionId]/index.ts @@ -10,24 +10,26 @@ export default async function handle(req: NextApiRequest, res: NextApiResponse) return res.status(401).json({ message: "Not authenticated" }); } - const teamId = req.query.teamId.toString(); + const workspaceId = req.query.workspaceId.toString(); const formId = req.query.formId.toString(); const submissionId = req.query.submissionId.toString(); - // check team permission + // check workspace permission const membership = await prisma.membership.findUnique({ where: { - userId_teamId: { + userId_workspaceId: { userId: user.id, - teamId, + workspaceId, }, }, }); if (membership === null) { - return res.status(403).json({ message: "You don't have access to this team or this team doesn't exist" }); + return res + .status(403) + .json({ message: "You don't have access to this workspace or this workspace doesn't exist" }); } - // GET /api/teams[teamId]/forms/[formId]/submissions/[submissionId] + // GET /api/workspaces[workspaceId]/forms/[formId]/submissions/[submissionId] // Get a specific submission if (req.method === "GET") { const submission = await prisma.submission.findFirst({ @@ -40,7 +42,7 @@ export default async function handle(req: NextApiRequest, res: NextApiResponse) return res.json(submission); } - // POST /api/teams[teamId]/forms/[formId]/submissions/[submissionId] + // POST /api/workspaces[workspaceId]/forms/[formId]/submissions/[submissionId] // Replace a specific submission else if (req.method === "POST") { const data = { ...req.body, updatedAt: new Date() }; @@ -51,7 +53,7 @@ export default async function handle(req: NextApiRequest, res: NextApiResponse) return res.json(prismaRes); } - // Delete /api/teams[teamId]/forms/[formId]/submissions/[submissionId] + // Delete /api/workspaces[workspaceId]/forms/[formId]/submissions/[submissionId] // Deletes a single form else if (req.method === "DELETE") { const prismaRes = await prisma.submission.delete({ diff --git a/apps/hq/src/pages/api/teams/[teamId]/forms/[formId]/submissions/index.ts b/apps/web/src/pages/api/workspaces/[workspaceId]/forms/[formId]/submissions/index.ts similarity index 76% rename from apps/hq/src/pages/api/teams/[teamId]/forms/[formId]/submissions/index.ts rename to apps/web/src/pages/api/workspaces/[workspaceId]/forms/[formId]/submissions/index.ts index d6d7ddcb3c..362b8e5918 100644 --- a/apps/hq/src/pages/api/teams/[teamId]/forms/[formId]/submissions/index.ts +++ b/apps/web/src/pages/api/workspaces/[workspaceId]/forms/[formId]/submissions/index.ts @@ -9,23 +9,25 @@ export default async function handle(req: NextApiRequest, res: NextApiResponse) return res.status(401).json({ message: "Not authenticated" }); } - const teamId = req.query.teamId.toString(); + const workspaceId = req.query.workspaceId.toString(); const formId = req.query.formId.toString(); - // check team permission + // check workspace permission const membership = await prisma.membership.findUnique({ where: { - userId_teamId: { + userId_workspaceId: { userId: user.id, - teamId, + workspaceId, }, }, }); if (membership === null) { - return res.status(403).json({ message: "You don't have access to this team or this team doesn't exist" }); + return res + .status(403) + .json({ message: "You don't have access to this workspace or this workspace doesn't exist" }); } - // GET /api/teams[teamId]/forms/[formId]/submissions + // GET /api/workspaces[workspaceId]/forms/[formId]/submissions // Get submissions if (req.method === "GET") { // get submission diff --git a/apps/hq/src/pages/api/teams/[teamId]/forms/index.ts b/apps/web/src/pages/api/workspaces/[workspaceId]/forms/index.ts similarity index 70% rename from apps/hq/src/pages/api/teams/[teamId]/forms/index.ts rename to apps/web/src/pages/api/workspaces/[workspaceId]/forms/index.ts index 2e89f36afd..9f59c8c008 100644 --- a/apps/hq/src/pages/api/teams/[teamId]/forms/index.ts +++ b/apps/web/src/pages/api/workspaces/[workspaceId]/forms/index.ts @@ -10,28 +10,30 @@ export default async function handle(req: NextApiRequest, res: NextApiResponse) return res.status(401).json({ message: "Not authenticated" }); } - const teamId = req.query.teamId.toString(); + const workspaceId = req.query.workspaceId.toString(); - // check team permission + // check workspace permission const membership = await prisma.membership.findUnique({ where: { - userId_teamId: { + userId_workspaceId: { userId: user.id, - teamId, + workspaceId, }, }, }); if (membership === null) { - return res.status(403).json({ message: "You don't have access to this team or this team doesn't exist" }); + return res + .status(403) + .json({ message: "You don't have access to this workspace or this workspace doesn't exist" }); } - // GET /api/teams[teamId]/forms - // Get a specific team + // GET /api/workspaces[workspaceId]/forms + // Get a specific workspace if (req.method === "GET") { const forms = await prisma.form.findMany({ where: { - team: { - id: teamId, + workspace: { + id: workspaceId, }, }, include: { @@ -44,7 +46,7 @@ export default async function handle(req: NextApiRequest, res: NextApiResponse) return res.json(forms); } - // POST /api/teams[teamId]/forms + // POST /api/workspaces[workspaceId]/forms // Create a new form // Required fields in body: - // Optional fields in body: label, schema @@ -55,10 +57,10 @@ export default async function handle(req: NextApiRequest, res: NextApiResponse) const result = await prisma.form.create({ data: { ...form, - team: { connect: { id: teamId } }, + workspace: { connect: { id: workspaceId } }, }, }); - capturePosthogEvent(teamId, "form created", { + capturePosthogEvent(workspaceId, "form created", { formId: result.id, }); res.json(result); diff --git a/apps/hq/src/pages/api/teams/[teamId]/index.ts b/apps/web/src/pages/api/workspaces/[workspaceId]/index.ts similarity index 68% rename from apps/hq/src/pages/api/teams/[teamId]/index.ts rename to apps/web/src/pages/api/workspaces/[workspaceId]/index.ts index 7bb1df8c72..c34465e824 100644 --- a/apps/hq/src/pages/api/teams/[teamId]/index.ts +++ b/apps/web/src/pages/api/workspaces/[workspaceId]/index.ts @@ -9,31 +9,31 @@ export default async function handle(req: NextApiRequest, res: NextApiResponse) return res.status(401).json({ message: "Not authenticated" }); } - const teamId = req.query.teamId.toString(); + const workspaceId = req.query.workspaceId.toString(); - // GET /api/teams[teamId] - // Get a specific team + // GET /api/workspaces[workspaceId] + // Get a specific workspace if (req.method === "GET") { // check if membership exists const membership = await prisma.membership.findUnique({ where: { - userId_teamId: { + userId_workspaceId: { userId: user.id, - teamId, + workspaceId, }, }, }); if (membership === null) { return res .status(403) - .json({ message: "You don't have access to this team or this team doesn't exist" }); + .json({ message: "You don't have access to this workspace or this workspace doesn't exist" }); } - const team = await prisma.team.findUnique({ + const workspace = await prisma.workspace.findUnique({ where: { - id: teamId, + id: workspaceId, }, }); - return res.json(team); + return res.json(workspace); } // Unknown HTTP Method diff --git a/apps/hq/src/pages/auth/forgot-password/email-sent/index.tsx b/apps/web/src/pages/auth/forgot-password/email-sent/index.tsx similarity index 100% rename from apps/hq/src/pages/auth/forgot-password/email-sent/index.tsx rename to apps/web/src/pages/auth/forgot-password/email-sent/index.tsx diff --git a/apps/hq/src/pages/auth/forgot-password/index.tsx b/apps/web/src/pages/auth/forgot-password/index.tsx similarity index 100% rename from apps/hq/src/pages/auth/forgot-password/index.tsx rename to apps/web/src/pages/auth/forgot-password/index.tsx diff --git a/apps/hq/src/pages/auth/forgot-password/reset/index.tsx b/apps/web/src/pages/auth/forgot-password/reset/index.tsx similarity index 100% rename from apps/hq/src/pages/auth/forgot-password/reset/index.tsx rename to apps/web/src/pages/auth/forgot-password/reset/index.tsx diff --git a/apps/hq/src/pages/auth/forgot-password/reset/success/index.tsx b/apps/web/src/pages/auth/forgot-password/reset/success/index.tsx similarity index 100% rename from apps/hq/src/pages/auth/forgot-password/reset/success/index.tsx rename to apps/web/src/pages/auth/forgot-password/reset/success/index.tsx diff --git a/apps/hq/src/pages/auth/signin/index.tsx b/apps/web/src/pages/auth/signin/index.tsx similarity index 100% rename from apps/hq/src/pages/auth/signin/index.tsx rename to apps/web/src/pages/auth/signin/index.tsx diff --git a/apps/hq/src/pages/auth/signup-without-verification-success/index.tsx b/apps/web/src/pages/auth/signup-without-verification-success/index.tsx similarity index 100% rename from apps/hq/src/pages/auth/signup-without-verification-success/index.tsx rename to apps/web/src/pages/auth/signup-without-verification-success/index.tsx diff --git a/apps/hq/src/pages/auth/signup/index.tsx b/apps/web/src/pages/auth/signup/index.tsx similarity index 100% rename from apps/hq/src/pages/auth/signup/index.tsx rename to apps/web/src/pages/auth/signup/index.tsx diff --git a/apps/hq/src/pages/auth/verification-requested/index.tsx b/apps/web/src/pages/auth/verification-requested/index.tsx similarity index 100% rename from apps/hq/src/pages/auth/verification-requested/index.tsx rename to apps/web/src/pages/auth/verification-requested/index.tsx diff --git a/apps/hq/src/pages/auth/verify/index.tsx b/apps/web/src/pages/auth/verify/index.tsx similarity index 100% rename from apps/hq/src/pages/auth/verify/index.tsx rename to apps/web/src/pages/auth/verify/index.tsx diff --git a/apps/hq/src/pages/app/index.tsx b/apps/web/src/pages/index.tsx similarity index 84% rename from apps/hq/src/pages/app/index.tsx rename to apps/web/src/pages/index.tsx index 132ed7b942..a4789d52fd 100644 --- a/apps/hq/src/pages/app/index.tsx +++ b/apps/web/src/pages/index.tsx @@ -5,7 +5,7 @@ import { useMemberships } from "@/lib/memberships"; import { useSession } from "next-auth/react"; import { useRouter } from "next/navigation"; import { useEffect } from "react"; -import LoadingSpinner from "../../components/LoadingSpinner"; +import LoadingSpinner from "@/components/LoadingSpinner"; export default function ProjectsPage() { const { data: session } = useSession(); @@ -14,8 +14,8 @@ export default function ProjectsPage() { useEffect(() => { if (session && memberships && memberships.length > 0) { - const teamId = memberships[0].teamId; - router.push(`/app/teams/${teamId}/forms`); + const workspaceId = memberships[0].workspaceId; + router.push(`/workspaces/${workspaceId}/forms`); } if (!session) { router.push(`/auth/signin?callbackUrl=${encodeURIComponent(window.location.href)}`); diff --git a/apps/hq/src/pages/app/me/settings/index.tsx b/apps/web/src/pages/me/settings/index.tsx similarity index 81% rename from apps/hq/src/pages/app/me/settings/index.tsx rename to apps/web/src/pages/me/settings/index.tsx index dfa8796f1d..4d12104d2e 100644 --- a/apps/hq/src/pages/app/me/settings/index.tsx +++ b/apps/web/src/pages/me/settings/index.tsx @@ -3,7 +3,7 @@ import LayoutApp from "@/components/layout/LayoutApp"; import ProfileSettingsPage from "@/components/me/ProfileSettingsPage"; -export default function TeamFormsPage({}) { +export default function WorkspaceFormsPage({}) { return ( diff --git a/apps/hq/src/pages/sentry_sample_error.js b/apps/web/src/pages/sentry_sample_error.js similarity index 100% rename from apps/hq/src/pages/sentry_sample_error.js rename to apps/web/src/pages/sentry_sample_error.js diff --git a/apps/hq/src/pages/app/teams/[teamId]/customers/[customerId]/index.tsx b/apps/web/src/pages/workspaces/[workspaceId]/customers/[customerId]/index.tsx similarity index 65% rename from apps/hq/src/pages/app/teams/[teamId]/customers/[customerId]/index.tsx rename to apps/web/src/pages/workspaces/[workspaceId]/customers/[customerId]/index.tsx index ca785b8032..69d700f249 100644 --- a/apps/hq/src/pages/app/teams/[teamId]/customers/[customerId]/index.tsx +++ b/apps/web/src/pages/workspaces/[workspaceId]/customers/[customerId]/index.tsx @@ -2,14 +2,14 @@ import SingleCustomerPage from "@/components/customers/SingleCustomerPage"; import LayoutApp from "@/components/layout/LayoutApp"; -import LayoutWrapperTeam from "@/components/layout/LayoutWrapperTeam"; +import LayoutWrapperWorkspace from "@/components/layout/LayoutWrapperWorkspace"; export default function Customers({}) { return ( - + - + ); } diff --git a/apps/hq/src/pages/app/teams/[teamId]/customers/index.tsx b/apps/web/src/pages/workspaces/[workspaceId]/customers/index.tsx similarity index 63% rename from apps/hq/src/pages/app/teams/[teamId]/customers/index.tsx rename to apps/web/src/pages/workspaces/[workspaceId]/customers/index.tsx index f29042fc99..8936b18630 100644 --- a/apps/hq/src/pages/app/teams/[teamId]/customers/index.tsx +++ b/apps/web/src/pages/workspaces/[workspaceId]/customers/index.tsx @@ -2,14 +2,14 @@ import CustomersPage from "@/components/customers/CustomersPage"; import LayoutApp from "@/components/layout/LayoutApp"; -import LayoutWrapperTeam from "@/components/layout/LayoutWrapperTeam"; +import LayoutWrapperWorkspace from "@/components/layout/LayoutWrapperWorkspace"; export default function Customers({}) { return ( - + - + ); } diff --git a/apps/hq/src/pages/app/teams/[teamId]/forms/[formId]/feedback/index.tsx b/apps/web/src/pages/workspaces/[workspaceId]/forms/[formId]/feedback/index.tsx similarity index 52% rename from apps/hq/src/pages/app/teams/[teamId]/forms/[formId]/feedback/index.tsx rename to apps/web/src/pages/workspaces/[workspaceId]/forms/[formId]/feedback/index.tsx index 929cd522a6..4d78cad7c8 100644 --- a/apps/hq/src/pages/app/teams/[teamId]/forms/[formId]/feedback/index.tsx +++ b/apps/web/src/pages/workspaces/[workspaceId]/forms/[formId]/feedback/index.tsx @@ -2,14 +2,14 @@ import FeedbackPage from "@/components/forms/feedback/FeedbackPage"; import LayoutApp from "@/components/layout/LayoutApp"; -import LayoutWrapperTeam from "@/components/layout/LayoutWrapperTeam"; +import LayoutWrapperWorkspace from "@/components/layout/LayoutWrapperWorkspace"; -export default function TeamFormsPage({}) { +export default function WorkspaceFormsPage({}) { return ( - + - + ); } diff --git a/apps/hq/src/pages/app/teams/[teamId]/forms/[formId]/index.tsx b/apps/web/src/pages/workspaces/[workspaceId]/forms/[formId]/index.tsx similarity index 72% rename from apps/hq/src/pages/app/teams/[teamId]/forms/[formId]/index.tsx rename to apps/web/src/pages/workspaces/[workspaceId]/forms/[formId]/index.tsx index 0de9e6e475..8bc928357d 100644 --- a/apps/hq/src/pages/app/teams/[teamId]/forms/[formId]/index.tsx +++ b/apps/web/src/pages/workspaces/[workspaceId]/forms/[formId]/index.tsx @@ -1,16 +1,16 @@ import FormOverviewPage from "@/components/forms/FormOverviewPage"; import LayoutApp from "@/components/layout/LayoutApp"; import LayoutWrapperForm from "@/components/layout/LayoutWrapperForm"; -import LayoutWrapperTeam from "@/components/layout/LayoutWrapperTeam"; +import LayoutWrapperWorkspace from "@/components/layout/LayoutWrapperWorkspace"; export default function FormOverview({}) { return ( - + - + ); } diff --git a/apps/hq/src/pages/app/teams/[teamId]/forms/[formId]/pipelines/index.tsx b/apps/web/src/pages/workspaces/[workspaceId]/forms/[formId]/pipelines/index.tsx similarity index 72% rename from apps/hq/src/pages/app/teams/[teamId]/forms/[formId]/pipelines/index.tsx rename to apps/web/src/pages/workspaces/[workspaceId]/forms/[formId]/pipelines/index.tsx index ba7923e317..b943487a62 100644 --- a/apps/hq/src/pages/app/teams/[teamId]/forms/[formId]/pipelines/index.tsx +++ b/apps/web/src/pages/workspaces/[workspaceId]/forms/[formId]/pipelines/index.tsx @@ -1,16 +1,16 @@ import PipelinesPage from "@/components/forms/pipelines/PipelinesOverview"; import LayoutApp from "@/components/layout/LayoutApp"; import LayoutWrapperForm from "@/components/layout/LayoutWrapperForm"; -import LayoutWrapperTeam from "@/components/layout/LayoutWrapperTeam"; +import LayoutWrapperWorkspace from "@/components/layout/LayoutWrapperWorkspace"; export default function Pipeline({}) { return ( - + - + ); } diff --git a/apps/hq/src/pages/app/teams/[teamId]/forms/[formId]/submissions/index.tsx b/apps/web/src/pages/workspaces/[workspaceId]/forms/[formId]/submissions/index.tsx similarity index 72% rename from apps/hq/src/pages/app/teams/[teamId]/forms/[formId]/submissions/index.tsx rename to apps/web/src/pages/workspaces/[workspaceId]/forms/[formId]/submissions/index.tsx index 64710f965f..105738e303 100644 --- a/apps/hq/src/pages/app/teams/[teamId]/forms/[formId]/submissions/index.tsx +++ b/apps/web/src/pages/workspaces/[workspaceId]/forms/[formId]/submissions/index.tsx @@ -1,16 +1,16 @@ import SubmissionsPage from "@/components/forms/submissions/SubmissionsPage"; import LayoutApp from "@/components/layout/LayoutApp"; import LayoutWrapperForm from "@/components/layout/LayoutWrapperForm"; -import LayoutWrapperTeam from "@/components/layout/LayoutWrapperTeam"; +import LayoutWrapperWorkspace from "@/components/layout/LayoutWrapperWorkspace"; export default function Submissions({}) { return ( - + - + ); } diff --git a/apps/hq/src/pages/app/teams/[teamId]/forms/[formId]/summary/index.tsx b/apps/web/src/pages/workspaces/[workspaceId]/forms/[formId]/summary/index.tsx similarity index 71% rename from apps/hq/src/pages/app/teams/[teamId]/forms/[formId]/summary/index.tsx rename to apps/web/src/pages/workspaces/[workspaceId]/forms/[formId]/summary/index.tsx index 45c2d77e27..0cd8ecbf05 100644 --- a/apps/hq/src/pages/app/teams/[teamId]/forms/[formId]/summary/index.tsx +++ b/apps/web/src/pages/workspaces/[workspaceId]/forms/[formId]/summary/index.tsx @@ -1,16 +1,16 @@ import SummaryPage from "@/components/forms/summary/SummaryPage"; import LayoutApp from "@/components/layout/LayoutApp"; import LayoutWrapperForm from "@/components/layout/LayoutWrapperForm"; -import LayoutWrapperTeam from "@/components/layout/LayoutWrapperTeam"; +import LayoutWrapperWorkspace from "@/components/layout/LayoutWrapperWorkspace"; export default function Submissions({}) { return ( - + - + ); } diff --git a/apps/hq/src/pages/app/teams/[teamId]/forms/index.tsx b/apps/web/src/pages/workspaces/[workspaceId]/forms/index.tsx similarity index 50% rename from apps/hq/src/pages/app/teams/[teamId]/forms/index.tsx rename to apps/web/src/pages/workspaces/[workspaceId]/forms/index.tsx index b60ddefebd..c7b9571c8b 100644 --- a/apps/hq/src/pages/app/teams/[teamId]/forms/index.tsx +++ b/apps/web/src/pages/workspaces/[workspaceId]/forms/index.tsx @@ -2,14 +2,14 @@ import FormsPage from "@/components/forms/FormsPage"; import LayoutApp from "@/components/layout/LayoutApp"; -import LayoutWrapperTeam from "@/components/layout/LayoutWrapperTeam"; +import LayoutWrapperWorkspace from "@/components/layout/LayoutWrapperWorkspace"; -export default function TeamFormsPage({}) { +export default function WorkspaceFormsPage({}) { return ( - + - + ); } diff --git a/apps/hq/src/pages/app/teams/[teamId]/settings/index.tsx b/apps/web/src/pages/workspaces/[workspaceId]/settings/index.tsx similarity index 52% rename from apps/hq/src/pages/app/teams/[teamId]/settings/index.tsx rename to apps/web/src/pages/workspaces/[workspaceId]/settings/index.tsx index 8ab86de0a7..1436ebc8e8 100644 --- a/apps/hq/src/pages/app/teams/[teamId]/settings/index.tsx +++ b/apps/web/src/pages/workspaces/[workspaceId]/settings/index.tsx @@ -1,15 +1,15 @@ "use client"; import LayoutApp from "@/components/layout/LayoutApp"; -import LayoutWrapperTeam from "@/components/layout/LayoutWrapperTeam"; +import LayoutWrapperWorkspace from "@/components/layout/LayoutWrapperWorkspace"; import SettingsPage from "@/components/settings/SettingsPage"; -export default function TeamFormsPage({}) { +export default function WorkspaceFormsPage({}) { return ( - + - + ); } diff --git a/apps/hq/src/styles/globals.css b/apps/web/src/styles/globals.css similarity index 100% rename from apps/hq/src/styles/globals.css rename to apps/web/src/styles/globals.css diff --git a/apps/hq/src/styles/prism.css b/apps/web/src/styles/prism.css similarity index 100% rename from apps/hq/src/styles/prism.css rename to apps/web/src/styles/prism.css diff --git a/apps/hq/src/styles/toastify.css b/apps/web/src/styles/toastify.css similarity index 100% rename from apps/hq/src/styles/toastify.css rename to apps/web/src/styles/toastify.css diff --git a/apps/hq/tailwind.config.js b/apps/web/tailwind.config.js similarity index 100% rename from apps/hq/tailwind.config.js rename to apps/web/tailwind.config.js diff --git a/apps/hq/tsconfig.json b/apps/web/tsconfig.json similarity index 100% rename from apps/hq/tsconfig.json rename to apps/web/tsconfig.json diff --git a/packages/database/prisma/migrations/20230109135603_update_team_id_in_submission/migration.sql b/packages/database/prisma/migrations/20230109135603_update_team_id_in_submission/migration.sql deleted file mode 100644 index cd314f9487..0000000000 --- a/packages/database/prisma/migrations/20230109135603_update_team_id_in_submission/migration.sql +++ /dev/null @@ -1,15 +0,0 @@ -/* - Warnings: - - - You are about to drop the column `teamId` on the `Submission` table. All the data in the column will be lost. - -*/ --- DropForeignKey -ALTER TABLE "Submission" DROP CONSTRAINT "Submission_customerId_teamId_fkey"; - --- AlterTable -ALTER TABLE "Submission" DROP COLUMN "teamId", -ADD COLUMN "customerTeamId" TEXT; - --- AddForeignKey -ALTER TABLE "Submission" ADD CONSTRAINT "Submission_customerId_customerTeamId_fkey" FOREIGN KEY ("customerId", "customerTeamId") REFERENCES "Customer"("id", "teamId") ON DELETE SET NULL ON UPDATE CASCADE; diff --git a/packages/database/prisma/migrations/20230112143317_add_slack_notification/migration.sql b/packages/database/prisma/migrations/20230112143317_add_slack_notification/migration.sql deleted file mode 100644 index 0579681348..0000000000 --- a/packages/database/prisma/migrations/20230112143317_add_slack_notification/migration.sql +++ /dev/null @@ -1,2 +0,0 @@ --- AlterEnum -ALTER TYPE "PipelineType" ADD VALUE 'slackNotification'; diff --git a/packages/database/prisma/migrations/20230104115809_init/migration.sql b/packages/database/prisma/migrations/20230115111533_init/migration.sql similarity index 81% rename from packages/database/prisma/migrations/20230104115809_init/migration.sql rename to packages/database/prisma/migrations/20230115111533_init/migration.sql index 46248df269..9b2bb45b23 100644 --- a/packages/database/prisma/migrations/20230104115809_init/migration.sql +++ b/packages/database/prisma/migrations/20230115111533_init/migration.sql @@ -1,5 +1,5 @@ -- CreateEnum -CREATE TYPE "PipelineType" AS ENUM ('webhook', 'emailNotification'); +CREATE TYPE "PipelineType" AS ENUM ('webhook', 'emailNotification', 'slackNotification'); -- CreateEnum CREATE TYPE "PipelineEvent" AS ENUM ('submissionCreated'); @@ -33,10 +33,10 @@ CREATE TABLE "Customer" ( "id" TEXT NOT NULL, "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "updated_at" TIMESTAMP(3) NOT NULL, - "teamId" TEXT NOT NULL, + "workspaceId" TEXT NOT NULL, "data" JSONB NOT NULL DEFAULT '{}', - CONSTRAINT "Customer_pkey" PRIMARY KEY ("id","teamId") + CONSTRAINT "Customer_pkey" PRIMARY KEY ("id","workspaceId") ); -- CreateTable @@ -46,7 +46,7 @@ CREATE TABLE "Form" ( "updated_at" TIMESTAMP(3) NOT NULL, "type" "FormType" NOT NULL, "label" TEXT NOT NULL, - "teamId" TEXT NOT NULL, + "workspaceId" TEXT NOT NULL, "schema" JSONB NOT NULL DEFAULT '{}', CONSTRAINT "Form_pkey" PRIMARY KEY ("id") @@ -60,7 +60,7 @@ CREATE TABLE "Submission" ( "archived" BOOLEAN NOT NULL DEFAULT false, "formId" TEXT NOT NULL, "customerId" TEXT, - "teamId" TEXT, + "customerWorkspaceId" TEXT, "data" JSONB NOT NULL DEFAULT '{}', "meta" JSONB NOT NULL DEFAULT '{}', @@ -68,23 +68,23 @@ CREATE TABLE "Submission" ( ); -- CreateTable -CREATE TABLE "Team" ( +CREATE TABLE "Workspace" ( "id" TEXT NOT NULL, "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "updated_at" TIMESTAMP(3) NOT NULL, "name" TEXT NOT NULL, - CONSTRAINT "Team_pkey" PRIMARY KEY ("id") + CONSTRAINT "Workspace_pkey" PRIMARY KEY ("id") ); -- CreateTable CREATE TABLE "Membership" ( - "teamId" TEXT NOT NULL, + "workspaceId" TEXT NOT NULL, "userId" TEXT NOT NULL, "accepted" BOOLEAN NOT NULL DEFAULT false, "role" "MembershipRole" NOT NULL, - CONSTRAINT "Membership_pkey" PRIMARY KEY ("userId","teamId") + CONSTRAINT "Membership_pkey" PRIMARY KEY ("userId","workspaceId") ); -- CreateTable @@ -150,19 +150,19 @@ CREATE UNIQUE INDEX "User_email_key" ON "User"("email"); ALTER TABLE "Pipeline" ADD CONSTRAINT "Pipeline_formId_fkey" FOREIGN KEY ("formId") REFERENCES "Form"("id") ON DELETE CASCADE ON UPDATE CASCADE; -- AddForeignKey -ALTER TABLE "Customer" ADD CONSTRAINT "Customer_teamId_fkey" FOREIGN KEY ("teamId") REFERENCES "Team"("id") ON DELETE CASCADE ON UPDATE CASCADE; +ALTER TABLE "Customer" ADD CONSTRAINT "Customer_workspaceId_fkey" FOREIGN KEY ("workspaceId") REFERENCES "Workspace"("id") ON DELETE CASCADE ON UPDATE CASCADE; -- AddForeignKey -ALTER TABLE "Form" ADD CONSTRAINT "Form_teamId_fkey" FOREIGN KEY ("teamId") REFERENCES "Team"("id") ON DELETE CASCADE ON UPDATE CASCADE; +ALTER TABLE "Form" ADD CONSTRAINT "Form_workspaceId_fkey" FOREIGN KEY ("workspaceId") REFERENCES "Workspace"("id") ON DELETE CASCADE ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "Submission" ADD CONSTRAINT "Submission_formId_fkey" FOREIGN KEY ("formId") REFERENCES "Form"("id") ON DELETE CASCADE ON UPDATE CASCADE; -- AddForeignKey -ALTER TABLE "Submission" ADD CONSTRAINT "Submission_customerId_teamId_fkey" FOREIGN KEY ("customerId", "teamId") REFERENCES "Customer"("id", "teamId") ON DELETE SET NULL ON UPDATE CASCADE; +ALTER TABLE "Submission" ADD CONSTRAINT "Submission_customerId_customerWorkspaceId_fkey" FOREIGN KEY ("customerId", "customerWorkspaceId") REFERENCES "Customer"("id", "workspaceId") ON DELETE SET NULL ON UPDATE CASCADE; -- AddForeignKey -ALTER TABLE "Membership" ADD CONSTRAINT "Membership_teamId_fkey" FOREIGN KEY ("teamId") REFERENCES "Team"("id") ON DELETE CASCADE ON UPDATE CASCADE; +ALTER TABLE "Membership" ADD CONSTRAINT "Membership_workspaceId_fkey" FOREIGN KEY ("workspaceId") REFERENCES "Workspace"("id") ON DELETE CASCADE ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "Membership" ADD CONSTRAINT "Membership_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/packages/database/prisma/schema.prisma b/packages/database/prisma/schema.prisma index 5e07c6e5c6..062cf560d6 100644 --- a/packages/database/prisma/schema.prisma +++ b/packages/database/prisma/schema.prisma @@ -38,12 +38,12 @@ model Customer { id String createdAt DateTime @default(now()) @map(name: "created_at") updatedAt DateTime @updatedAt @map(name: "updated_at") - team Team @relation(fields: [teamId], references: [id], onDelete: Cascade) - teamId String + workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade) + workspaceId String submissions Submission[] data Json @default("{}") - @@id([id, teamId]) + @@id([id, workspaceId]) } enum FormType { @@ -56,28 +56,28 @@ model Form { updatedAt DateTime @updatedAt @map(name: "updated_at") type FormType label String - team Team @relation(fields: [teamId], references: [id], onDelete: Cascade) - teamId String + workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade) + workspaceId String schema Json @default("{}") submissions Submission[] pipelines Pipeline[] } model Submission { - id String @id @default(cuid()) - createdAt DateTime @default(now()) @map(name: "created_at") - updatedAt DateTime @updatedAt @map(name: "updated_at") - archived Boolean @default(false) - form Form @relation(fields: [formId], references: [id], onDelete: Cascade) - formId String - customer Customer? @relation(fields: [customerId, customerTeamId], references: [id, teamId]) - customerId String? - customerTeamId String? - data Json @default("{}") - meta Json @default("{}") + id String @id @default(cuid()) + createdAt DateTime @default(now()) @map(name: "created_at") + updatedAt DateTime @updatedAt @map(name: "updated_at") + archived Boolean @default(false) + form Form @relation(fields: [formId], references: [id], onDelete: Cascade) + formId String + customer Customer? @relation(fields: [customerId, customerWorkspaceId], references: [id, workspaceId]) + customerId String? + customerWorkspaceId String? + data Json @default("{}") + meta Json @default("{}") } -model Team { +model Workspace { id String @id @default(cuid()) createdAt DateTime @default(now()) @map(name: "created_at") updatedAt DateTime @updatedAt @map(name: "updated_at") @@ -94,14 +94,14 @@ enum MembershipRole { } model Membership { - team Team @relation(fields: [teamId], references: [id], onDelete: Cascade) - teamId String - user User @relation(fields: [userId], references: [id], onDelete: Cascade) - userId String - accepted Boolean @default(false) - role MembershipRole + workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade) + workspaceId String + user User @relation(fields: [userId], references: [id], onDelete: Cascade) + userId String + accepted Boolean @default(false) + role MembershipRole - @@id([userId, teamId]) + @@id([userId, workspaceId]) } model ApiKey { @@ -149,7 +149,7 @@ model User { password String? identityProvider IdentityProvider @default(email) identityProviderAccountId String? - teams Membership[] + workspaces Membership[] accounts Account[] apiKeys ApiKey[] } diff --git a/packages/feedback-widget/test-div.html b/packages/feedback-widget/test-div.html index 5ddb0ce69d..c9d341e81c 100644 --- a/packages/feedback-widget/test-div.html +++ b/packages/feedback-widget/test-div.html @@ -4,7 +4,7 @@ window.formbricks = { config: { hqUrl: "http://localhost:3000", - formId: "clct71ckl0006yzy54f4gcv3x", + formId: "clcxavrfm0006yz11frfb0ms2", divId: "test-div", contact: { name: "Peer", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f8d168af0d..52f7244ad3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -150,6 +150,7 @@ importers: next-auth: ^4.17.0 nextjs-cors: ^2.1.2 nodemailer: ^6.8.0 + platform: ^1.3.6 postcss: ^8.4.19 prismjs: ^1.29.0 react: ^18.2.0 @@ -175,6 +176,7 @@ importers: next-auth: 4.17.0_2xoejpawkzgot77rbv5mbik6ve nextjs-cors: 2.1.2_next@13.0.5 nodemailer: 6.8.0 + platform: 1.3.6 prismjs: 1.29.0 react: 18.2.0 react-dom: 18.2.0_react@18.2.0 @@ -13992,6 +13994,10 @@ packages: find-up: 5.0.0 dev: true + /platform/1.3.6: + resolution: {integrity: sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==} + dev: false + /pnp-webpack-plugin/1.6.4_typescript@4.9.3: resolution: {integrity: sha512-7Wjy+9E3WwLOEL30D+m8TSTF7qJJUJLONBnwQp0518siuMxUQUbgZwssaFX+QKlZkjHZcw/IpZCt/H0srrntSg==} engines: {node: '>=6'}