added shareSurveySheet

This commit is contained in:
Piyush Gupta
2023-09-29 11:44:31 +05:30
parent 3edf5539d5
commit 128ad4cb3a
7 changed files with 254 additions and 39 deletions

View File

@@ -27,7 +27,6 @@ import { cn } from "@formbricks/lib/cn";
import { QuestionType } from "@formbricks/types/questions";
import { SurveyInline } from "@/components/shared/Survey";
import { TProduct } from "@formbricks/types/v1/product";
import { useProfile } from "@/lib/profile";
import { TProfile } from "@formbricks/types/v1/profile";
interface EmbedSurveyModalProps {
@@ -36,6 +35,7 @@ interface EmbedSurveyModalProps {
setOpen: (open: boolean) => void;
surveyBaseUrl: string;
product: TProduct;
profile: TProfile;
}
const tabs = [
@@ -50,13 +50,12 @@ export default function EmbedSurveyModal({
setOpen,
surveyBaseUrl,
product,
profile,
}: EmbedSurveyModalProps) {
const [activeId, setActiveId] = useState(tabs[0].id);
const surveyUrl = useMemo(() => surveyBaseUrl + survey.id, [survey]);
const { profile } = useProfile();
const componentMap = {
link: <LinkTab surveyUrl={surveyUrl} survey={survey} product={product} />,
email: <EmailTab survey={survey} surveyUrl={surveyUrl} profile={profile} />,
@@ -98,7 +97,7 @@ export default function EmbedSurveyModal({
}
// 1st tab
const LinkTab = ({
export const LinkTab = ({
surveyUrl,
survey,
product,
@@ -123,11 +122,11 @@ const LinkTab = ({
};
return (
<div className="flex grow flex-col gap-5">
<div className="flex h-full grow flex-col gap-5">
<div className="flex justify-between gap-2">
<div
ref={linkTextRef}
className="relative grow overflow-auto rounded-lg border border-slate-300 bg-white px-3 py-2 text-center text-slate-800"
className="relative grow overflow-auto rounded-lg border border-slate-300 bg-white px-3 py-2 text-slate-800"
onClick={() => handleTextSelection()}>
<span style={{ wordBreak: "break-all" }}>{surveyUrl}</span>
</div>
@@ -172,15 +171,7 @@ const LinkTab = ({
};
// 2nd tab
const EmailTab = ({
survey,
surveyUrl,
profile,
}: {
survey: TSurvey;
surveyUrl: string;
profile: TProfile;
}) => {
export const EmailTab = ({ survey, surveyUrl, profile }: { survey: TSurvey; surveyUrl: string; profile }) => {
const [email, setEmail] = useState(profile.email);
const [showEmbed, setShowEmbed] = useState(false);
@@ -217,14 +208,16 @@ const EmailTab = ({
// console.log(res);
};
return (
<div className="flex grow flex-col gap-5">
<div className="flex h-full grow flex-col gap-5">
<div className="flex items-center gap-4">
<Input
type="email"
placeholder="user@mail.com"
className="h-11 grow bg-white"
value={email}
// onChange={(e) => setEmail(e.target.value)}
onChange={(e) => {
// setEmail(e.target.value)
}}
/>
{showEmbed ? (
<Button
@@ -303,7 +296,7 @@ const WebpageTab = ({ surveyUrl }) => {
</div>`;
return (
<div className="flex grow flex-col gap-5">
<div className="flex h-full grow flex-col gap-5">
<div className="flex justify-between">
<div className=""></div>
<Button

View File

@@ -7,6 +7,7 @@ import { useState } from "react";
import clsx from "clsx";
import { TProduct } from "@formbricks/types/v1/product";
import EmbedSurveyModal from "@/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/EmbedSurveyModal";
import ShareEmbedSurvey from "@/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/ShareEmbedSurvey";
interface LinkSurveyShareButtonProps {
survey: TSurvey;
@@ -34,7 +35,7 @@ export default function LinkSurveyShareButton({
onClick={() => setShowLinkModal(true)}>
<ShareIcon className="h-5 w-5" />
</Button>
{showLinkModal && (
{/* {showLinkModal && (
<EmbedSurveyModal
survey={survey}
open={showLinkModal}
@@ -42,6 +43,15 @@ export default function LinkSurveyShareButton({
product={product}
surveyBaseUrl={surveyBaseUrl}
/>
)} */}
{showLinkModal && (
<ShareEmbedSurvey
survey={survey}
open={showLinkModal}
setOpen={setShowLinkModal}
product={product}
surveyBaseUrl={surveyBaseUrl}
/>
)}
</>
);

View File

@@ -0,0 +1,99 @@
import EmbedSurveyModal, {
EmailTab,
LinkTab,
} from "@/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/EmbedSurveyModal";
import { useProfile } from "@/lib/profile";
import { cn } from "@formbricks/lib/cn";
import { TProduct } from "@formbricks/types/v1/product";
import { TSurvey } from "@formbricks/types/v1/surveys";
import { SheetContent, SheetHeader, Sheet, Button } from "@formbricks/ui";
import { useMemo, useState } from "react";
interface ShareEmbedSurveyProps {
survey: TSurvey;
open: boolean;
setOpen: (open: boolean) => void;
surveyBaseUrl: string;
product: TProduct;
}
export default function ShareEmbedSurvey({
survey,
open,
setOpen,
surveyBaseUrl,
product,
}: ShareEmbedSurveyProps) {
const surveyUrl = useMemo(() => surveyBaseUrl + survey.id, [survey]);
const { profile } = useProfile();
console.log({ survey, open, setOpen, surveyBaseUrl, product });
return (
<div className="">
<div className="hidden lg:hidden">
{/* <EmbedSurveyModal
survey={survey}
open={open}
setOpen={setOpen}
product={product}
surveyBaseUrl={surveyBaseUrl}
profile = {profile}
/> */}
</div>
<div className="invisible hidden lg:hidden">
<EmbedSurveySheet
survey={survey}
open={open}
setOpen={setOpen}
product={product}
surveyUrl={surveyUrl}
profile={profile}
/>
</div>
</div>
);
}
const EmbedSurveySheet = ({ survey, open, setOpen, surveyUrl, product, profile }) => {
const [activeId, setActiveId] = useState("link");
const tabs = [
{ id: "link", label: "Share Link" },
{ id: "email", label: "Embed in an Email" },
];
const componentMap = {
link: <LinkTab surveyUrl={surveyUrl} survey={survey} product={product} />,
email: <EmailTab survey={survey} surveyUrl={surveyUrl} profile={profile} />,
};
return (
<Sheet open={open} onOpenChange={setOpen}>
<SheetContent
className="over flex h-[90%] w-full flex-col gap-0 rounded-t-2xl bg-slate-50 p-0"
side={"bottom"}>
<SheetHeader>
<div className="border-b border-gray-200 px-6 py-4">Share or embed your survey</div>
</SheetHeader>
<div className="flex grow flex-col gap-6 overflow-y-scroll px-4 py-6">
<div className="tab grow overflow-y-scroll">{componentMap[activeId]}</div>
<div className="mx-auto flex max-w-max rounded-md bg-slate-100 p-1">
{tabs.map((tab) => (
<Button
variant="minimal"
key={tab.id}
onClick={() => setActiveId(tab.id)}
className={cn(
"rounded-sm px-3 py-[6px]",
tab.id === activeId
? "bg-white text-slate-900"
: "border-transparent text-slate-700 hover:text-slate-900"
)}>
{tab.label}
</Button>
))}
</div>
</div>
</SheetContent>
</Sheet>
);
};

View File

@@ -6,7 +6,7 @@ import { Confetti } from "@formbricks/ui";
import { useSearchParams } from "next/navigation";
import { useEffect, useState } from "react";
import toast from "react-hot-toast";
import EmbedSurveyModal from "./EmbedSurveyModal";
import ShareEmbedSurvey from "./ShareEmbedSurvey";
import { TProduct } from "@formbricks/types/v1/product";
interface SummaryMetadataProps {
@@ -55,7 +55,7 @@ export default function SuccessMessage({
return (
<>
{showLinkModal && (
<EmbedSurveyModal
<ShareEmbedSurvey
survey={survey}
open={showLinkModal}
setOpen={setShowLinkModal}

View File

@@ -0,0 +1,120 @@
"use client";
import * as React from "react";
import * as SheetPrimitive from "@radix-ui/react-dialog";
import { X } from "lucide-react";
import { cva, type VariantProps } from "class-variance-authority";
import { cn } from "@formbricks/lib/cn";
const Sheet = SheetPrimitive.Root;
const SheetTrigger = SheetPrimitive.Trigger;
const SheetClose = SheetPrimitive.Close;
const SheetPortal = ({ className, ...props }: SheetPrimitive.DialogPortalProps) => (
<SheetPrimitive.Portal className={cn(className)} {...props} />
);
SheetPortal.displayName = SheetPrimitive.Portal.displayName;
const SheetOverlay = React.forwardRef<
React.ElementRef<typeof SheetPrimitive.Overlay>,
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Overlay>
>(({ className, ...props }, ref) => (
<SheetPrimitive.Overlay
className={cn(
"bg-background/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 backdrop-blur-sm",
className
)}
{...props}
ref={ref}
/>
));
SheetOverlay.displayName = SheetPrimitive.Overlay.displayName;
const sheetVariants = cva(
"fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500",
{
variants: {
side: {
top: "inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",
bottom:
"inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",
left: "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm",
right:
"inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm",
},
},
defaultVariants: {
side: "right",
},
}
);
interface SheetContentProps
extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>,
VariantProps<typeof sheetVariants> {}
const SheetContent = React.forwardRef<React.ElementRef<typeof SheetPrimitive.Content>, SheetContentProps>(
({ side = "right", className, children, ...props }, ref) => (
<SheetPortal>
<SheetOverlay />
<SheetPrimitive.Content ref={ref} className={cn(sheetVariants({ side }), className)} {...props}>
{children}
<SheetPrimitive.Close className="ring-offset-background focus:ring-ring data-[state=open]:bg-secondary absolute right-4 top-4 rounded-sm opacity-70 transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:pointer-events-none">
<X className="h-4 w-4" />
<span className="sr-only">Close</span>
</SheetPrimitive.Close>
</SheetPrimitive.Content>
</SheetPortal>
)
);
SheetContent.displayName = SheetPrimitive.Content.displayName;
const SheetHeader = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (
<div className={cn("flex flex-col space-y-2 text-center sm:text-left", className)} {...props} />
);
SheetHeader.displayName = "SheetHeader";
const SheetFooter = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (
<div
className={cn("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2", className)}
{...props}
/>
);
SheetFooter.displayName = "SheetFooter";
const SheetTitle = React.forwardRef<
React.ElementRef<typeof SheetPrimitive.Title>,
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Title>
>(({ className, ...props }, ref) => (
<SheetPrimitive.Title
ref={ref}
className={cn("text-foreground text-lg font-semibold", className)}
{...props}
/>
));
SheetTitle.displayName = SheetPrimitive.Title.displayName;
const SheetDescription = React.forwardRef<
React.ElementRef<typeof SheetPrimitive.Description>,
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Description>
>(({ className, ...props }, ref) => (
<SheetPrimitive.Description
ref={ref}
className={cn("text-muted-foreground text-sm", className)}
{...props}
/>
));
SheetDescription.displayName = SheetPrimitive.Description.displayName;
export {
Sheet,
SheetTrigger,
SheetClose,
SheetContent,
SheetHeader,
SheetFooter,
SheetTitle,
SheetDescription,
};

View File

@@ -67,6 +67,16 @@ export {
SelectTrigger,
SelectValue,
} from "./components/Select";
export {
Sheet,
SheetContent,
SheetDescription,
SheetHeader,
SheetTitle,
SheetTrigger,
SheetClose,
SheetFooter,
} from "./components/Sheet";
export { Switch } from "./components/Switch";
export { TabBar } from "./components/TabBar";
export { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "./components/Tooltip";

19
pnpm-lock.yaml generated
View File

@@ -18449,23 +18449,6 @@ packages:
postcss: 8.4.27
yaml: 2.3.1
/postcss-load-config@4.0.1(postcss@8.4.30):
resolution: {integrity: sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==}
engines: {node: '>= 14'}
peerDependencies:
postcss: '>=8.0.9'
ts-node: '>=9.0.0'
peerDependenciesMeta:
postcss:
optional: true
ts-node:
optional: true
dependencies:
lilconfig: 2.1.0
postcss: 8.4.30
yaml: 2.3.1
dev: true
/postcss-loader@4.3.0(postcss@8.4.27)(webpack@4.46.0):
resolution: {integrity: sha512-M/dSoIiNDOo8Rk0mUqoj4kpGq91gcxCfb9PoyZVdZ76/AuhxylHDYZblNE8o+EQ9AMSASeMFEKxZf5aU6wlx1Q==}
engines: {node: '>= 10.13.0'}
@@ -22903,7 +22886,7 @@ packages:
execa: 5.1.1
globby: 11.1.0
joycon: 3.1.1
postcss-load-config: 4.0.1(postcss@8.4.30)
postcss-load-config: 4.0.1(postcss@8.4.27)
resolve-from: 5.0.0
rollup: 3.5.1
source-map: 0.8.0-beta.0