Add new Pause/Not Found screens for surveys (#285)

* Add new screens for surveys with different status (not found, paused, completed)

---------

Co-authored-by: Johannes <johannes@formbricks.com>
This commit is contained in:
Moritz Rengert
2023-05-23 13:35:13 +02:00
committed by GitHub
parent 69c05a3133
commit 96344d6123
7 changed files with 149 additions and 10 deletions

View File

@@ -4,7 +4,16 @@ import LoadingSpinner from "@/components/shared/LoadingSpinner";
import { useAttributeClasses } from "@/lib/attributeClasses/attributeClasses";
import { cn } from "@formbricks/lib/cn";
import type { Survey } from "@formbricks/types/surveys";
import { Button, Input, Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@formbricks/ui";
import {
Badge,
Button,
Input,
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@formbricks/ui";
import { CheckCircleIcon, PlusIcon, TrashIcon } from "@heroicons/react/24/solid";
import * as Collapsible from "@radix-ui/react-collapsible";
import { useEffect, useState } from "react"; /* */
@@ -98,6 +107,11 @@ export default function WhoToSendCard({ environmentId, localSurvey, setLocalSurv
Pre-segment your users with attributes filters.
</p>
</div>
{localSurvey.type === "link" && (
<div className="flex w-full items-center justify-end pr-2">
<Badge size="normal" text="In-app survey settings" type="warning" />
</div>
)}
</div>
</Collapsible.CollapsibleTrigger>
<Collapsible.CollapsibleContent className="">

View File

@@ -0,0 +1,41 @@
import React from "react";
import { CheckCircleIcon, PauseCircleIcon, QuestionMarkCircleIcon } from "@heroicons/react/24/solid";
import footerLogo from "./footerlogo.svg";
import Image from "next/image";
import Link from "next/link";
import { Button } from "@formbricks/ui";
const SurveyInactive = ({ status }) => {
const icons = {
"not found": <QuestionMarkCircleIcon className="h-20 w-20" />,
paused: <PauseCircleIcon className="h-20 w-20" />,
completed: <CheckCircleIcon className="h-20 w-20" />,
};
const descriptions = {
"not found": "There is not survey with this ID.",
paused: "This free & open-source survey is temporarily paused.",
completed: "This free & open-source survey has been closed.",
};
return (
<div className="flex min-h-screen flex-col items-center justify-between bg-gradient-to-tr from-slate-200 to-slate-50 py-8 text-center">
<div></div>
<div className="flex flex-col items-center space-y-3 text-slate-300">
{icons[status]}
<h1 className="text-4xl font-bold text-slate-800">Survey {status}.</h1>
<p className="text-lg leading-10 text-gray-500">{descriptions[status]}</p>
<Button variant="darkCTA" className="mt-2" href="https://formbricks.com">
Create your own
</Button>
</div>
<div>
<Link href="https://formbricks.com">
<Image src={footerLogo} alt="Brand logo" className="mx-auto w-40" />
</Link>
</div>
</div>
);
};
export default SurveyInactive;

View File

@@ -1,6 +1,7 @@
"use client";
import LinkSurvey from "@/app/s/[surveyId]/LinkSurvey";
import SurveyInactive from "@/app/s/[surveyId]/SurveyInactive";
import LegalFooter from "@/components/shared/LegalFooter";
import LoadingSpinner from "@/components/shared/LoadingSpinner";
import { useLinkSurvey } from "@/lib/linkSurvey/linkSurvey";
@@ -20,12 +21,12 @@ export default function SurveyPage({ surveyId }: SurveyPageProps) {
);
}
if (isErrorSurvey || !survey) {
return (
<div className="flex h-full w-full items-center justify-center">
<p className="text-sm text-slate-800">Survey cannot be found</p>
</div>
);
if (isErrorSurvey && isErrorSurvey.status === 404) {
return <SurveyInactive status="not found" />;
}
if (isErrorSurvey && isErrorSurvey.status === 403) {
return <SurveyInactive status={isErrorSurvey.info.reason} />;
}
return (

View File

@@ -0,0 +1,76 @@
<svg width="725" height="150" viewBox="0 0 725 150" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M143 116H157V87.4H183.6V75H157V58.6H184.1V46H143V116ZM217.309 117.3C233.409 117.3 245.009 105.1 245.009 90.1C245.009 75.1 233.409 62.8 217.309 62.8C201.209 62.8 189.609 75.1 189.609 90.1C189.609 105.1 201.209 117.3 217.309 117.3ZM203.109 90.1C203.109 82 208.709 75.1 217.309 75.1C225.909 75.1 231.509 82 231.509 90.1C231.509 98.2 225.909 105 217.309 105C208.709 105 203.109 98.2 203.109 90.1ZM250.984 116H264.484V89.4C264.484 80.7 270.484 75.5 278.284 75.5H280.184V62.8C271.184 62.3 265.884 66.4 264.084 73.9V64H250.984V116ZM288.676 116H302.176V87.5C302.176 78.5 307.276 74.6 312.976 74.6C319.676 74.6 324.176 78.5 324.176 87.5V116H337.676V87.5C337.676 77.5 341.976 74.6 348.276 74.6C354.376 74.6 358.676 78.5 358.676 87.5V116H372.176V84.2C372.176 71.1 363.576 62.8 352.376 62.8C343.276 62.8 338.276 66.3 334.776 72.6C331.376 66.3 325.176 62.8 317.876 62.8C309.876 62.8 304.676 65.8 301.976 71.6V64H288.676V116ZM413.591 117.3C427.891 117.3 439.291 105.2 439.291 90.2C439.291 75.2 427.891 62.9 413.591 62.9C404.691 62.9 399.991 66.5 397.191 72V43H383.691V116H396.791V107.5C399.591 113.4 404.291 117.3 413.591 117.3ZM396.791 90.2C396.791 82.1 402.491 75.1 411.391 75.1C419.991 75.1 425.791 82 425.791 90.1C425.791 98 419.991 105.1 411.391 105.1C402.491 105.1 396.791 98.3 396.791 90.2ZM447.313 116H460.813V89.4C460.813 80.7 466.813 75.5 474.613 75.5H476.513V62.8C467.513 62.3 462.213 66.4 460.413 73.9V64H447.313V116ZM485.004 116H498.504V64H485.004V116ZM483.604 51.7C483.604 56.1 487.104 59.7 491.704 59.7C496.404 59.7 499.804 56.2 499.804 51.7C499.804 47.4 496.404 43.8 491.704 43.8C487.104 43.8 483.604 47.4 483.604 51.7ZM531.288 117.3C541.488 117.3 548.688 113.6 553.588 107.3L543.788 98.8C541.088 102.4 537.688 105 532.488 105C523.888 105 517.988 98.1 517.988 90C517.988 81.9 523.588 75 532.188 75C536.788 75 540.788 77.3 543.188 80.9L553.588 72.4C549.188 66.3 541.488 62.6 531.988 62.7C516.088 62.8 504.488 74.9 504.488 90C504.488 105.1 516.388 117.3 531.288 117.3ZM593.33 116H611.23L586.63 88.2L611.13 64H591.93L572.43 85V43H558.93V116H572.43V91.3L593.33 116ZM633.562 117.3C645.062 117.3 653.762 110.1 653.762 100.5C653.762 92.7 650.262 87.1 635.162 83.2C628.962 81.6 628.162 80 628.162 78.2C628.162 75 630.962 73.6 634.662 73.6C638.162 73.6 641.362 75.2 643.862 79.2L653.662 71.7C648.362 64.8 642.762 62.7 634.362 62.7C622.162 62.7 614.962 69.5 614.962 78.6C614.962 85.2 617.062 91.5 630.962 94.8C639.162 96.7 640.462 98.2 640.462 100.9C640.462 104 637.862 106.3 633.262 106.3C628.862 106.3 624.862 104.2 621.062 99.9L611.962 108.2C617.662 114.3 624.762 117.3 633.562 117.3Z" fill="#0F172A"/>
<path d="M0 98.6416H25.3585V111.321C25.3585 118.323 19.6818 124 12.6792 124V124C5.67669 124 0 118.323 0 111.321V98.6416Z" fill="url(#paint0_linear_2625_5904)"/>
<path d="M0 69.3208H50.717C57.7195 69.3208 63.3962 74.9975 63.3962 82V82C63.3962 89.0026 57.7195 94.6793 50.717 94.6793H0V69.3208Z" fill="url(#paint1_linear_2625_5904)"/>
<path d="M0 60C0 48.9543 8.9543 40 20 40H50.717C57.7195 40 63.3962 45.6767 63.3962 52.6792V52.6792C63.3962 59.6818 57.7195 65.3585 50.717 65.3585H0V60Z" fill="url(#paint2_linear_2625_5904)"/>
<mask id="mask0_2625_5904" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="40" width="64" height="84">
<path d="M0 98.6416H25.3585V111.321C25.3585 118.323 19.6818 124 12.6792 124V124C5.67669 124 0 118.323 0 111.321V98.6416Z" fill="url(#paint3_linear_2625_5904)"/>
<path d="M0 69.3208H50.717C57.7195 69.3208 63.3962 74.9975 63.3962 82V82C63.3962 89.0026 57.7195 94.6793 50.717 94.6793H0V69.3208Z" fill="url(#paint4_linear_2625_5904)"/>
<path d="M0 60C0 48.9543 8.9543 40 20 40H50.717C57.7195 40 63.3962 45.6767 63.3962 52.6792V52.6792C63.3962 59.6818 57.7195 65.3585 50.717 65.3585H0V60Z" fill="url(#paint5_linear_2625_5904)"/>
</mask>
<g mask="url(#mask0_2625_5904)">
<g filter="url(#filter0_d_2625_5904)">
<mask id="mask1_2625_5904" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="40" width="64" height="84">
<path d="M0 98.6416H25.3585V111.321C25.3585 118.323 19.6818 124 12.6792 124V124C5.67669 124 0 118.323 0 111.321V98.6416Z" fill="black" fill-opacity="0.1"/>
<path d="M0 60C0 48.9543 8.9543 40 20 40H50.717C57.7195 40 63.3962 45.6767 63.3962 52.6792V52.6792C63.3962 59.6818 57.7195 65.3585 50.717 65.3585H0V60Z" fill="black" fill-opacity="0.1"/>
<path d="M0 69.3208H50.717C57.7195 69.3208 63.3962 74.9975 63.3962 82V82C63.3962 89.0026 57.7195 94.6793 50.717 94.6793H0V69.3208Z" fill="black" fill-opacity="0.1"/>
</mask>
<g mask="url(#mask1_2625_5904)">
<path d="M1.33026 18.158C11.2638 8.46307 36.4526 18.158 36.4526 18.158H1.33026C-1.10954 20.5391 -2.62906 24.09 -2.62906 29.2415C-2.62906 55.3672 25.6715 64.8676 25.6715 83.0764C25.6715 100.901 -1.4485 111.898 -2.59186 136.119H36.4526C36.4526 136.119 -2.62906 163.037 -2.62906 137.703C-2.62906 137.169 -2.61648 136.641 -2.59186 136.119H-19.8115L-16.4424 18.158H1.33026Z" fill="black" fill-opacity="0.1"/>
</g>
</g>
<g filter="url(#filter1_f_2625_5904)">
<circle cx="-7.92441" cy="112.906" r="23.7736" fill="#00C4B8"/>
</g>
<g filter="url(#filter2_f_2625_5904)">
<circle cx="-7.92441" cy="52.6793" r="23.7736" fill="#00C4B8"/>
</g>
</g>
<line x1="102.75" y1="38" x2="102.75" y2="125" stroke="#CBD5E1" stroke-width="1.5"/>
<defs>
<filter id="filter0_d_2625_5904" x="-2" y="28" width="60.4526" height="108" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dx="10"/>
<feGaussianBlur stdDeviation="6"/>
<feComposite in2="hardAlpha" operator="out"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_2625_5904"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_2625_5904" result="shape"/>
</filter>
<filter id="filter1_f_2625_5904" x="-51.698" y="69.1321" width="87.5471" height="87.5471" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feGaussianBlur stdDeviation="10" result="effect1_foregroundBlur_2625_5904"/>
</filter>
<filter id="filter2_f_2625_5904" x="-51.698" y="8.90576" width="87.5471" height="87.5471" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feGaussianBlur stdDeviation="10" result="effect1_foregroundBlur_2625_5904"/>
</filter>
<linearGradient id="paint0_linear_2625_5904" x1="25.4688" y1="110.861" x2="-0.00218275" y2="110.964" gradientUnits="userSpaceOnUse">
<stop stop-color="#00E6CA"/>
<stop offset="1" stop-color="#00C4B8"/>
</linearGradient>
<linearGradient id="paint1_linear_2625_5904" x1="63.6719" y1="81.5407" x2="7.75704e-09" y2="82.1838" gradientUnits="userSpaceOnUse">
<stop stop-color="#00E6CA"/>
<stop offset="1" stop-color="#00C4B8"/>
</linearGradient>
<linearGradient id="paint2_linear_2625_5904" x1="63.6719" y1="52.2199" x2="7.75704e-09" y2="52.863" gradientUnits="userSpaceOnUse">
<stop stop-color="#00E6CA"/>
<stop offset="1" stop-color="#00C4B8"/>
</linearGradient>
<linearGradient id="paint3_linear_2625_5904" x1="25.4688" y1="110.861" x2="-0.00218275" y2="110.964" gradientUnits="userSpaceOnUse">
<stop stop-color="#00FFE1"/>
<stop offset="1" stop-color="#01E0C6"/>
</linearGradient>
<linearGradient id="paint4_linear_2625_5904" x1="63.6719" y1="81.5407" x2="7.75704e-09" y2="82.1838" gradientUnits="userSpaceOnUse">
<stop stop-color="#00FFE1"/>
<stop offset="1" stop-color="#01E0C6"/>
</linearGradient>
<linearGradient id="paint5_linear_2625_5904" x1="63.6719" y1="52.2199" x2="7.75704e-09" y2="52.863" gradientUnits="userSpaceOnUse">
<stop stop-color="#00FFE1"/>
<stop offset="1" stop-color="#01E0C6"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 7.9 KiB

View File

@@ -65,7 +65,7 @@ export default function SurveyStatusDropdown({
if (updateLocalSurveyStatus)
updateLocalSurveyStatus(value as "draft" | "inProgress" | "paused" | "completed" | "archived");
}}>
<SelectTrigger className="w-[170px] bg-white py-1.5 md:w-[200px]">
<SelectTrigger className="w-[170px] bg-white py-6 md:w-[200px]">
<SelectValue>
<div className="flex items-center">
<SurveyStatusIndicator status={survey.status} environmentId={environmentId} />

View File

@@ -58,7 +58,7 @@ export default function SurveyStatusIndicator({
</>
) : status === "paused" ? (
<>
<span>Survey paused.</span>
<span className="text-slate-800">Survey paused.</span>
<div className=" rounded-full bg-slate-300 p-1">
<PauseIcon className="h-3 w-3 text-slate-600" />
</div>

View File

@@ -19,13 +19,14 @@ export default async function handle(req: NextApiRequest, res: NextApiResponse)
where: {
id: surveyId,
type: "link",
status: "inProgress",
// status: "inProgress",
},
select: {
id: true,
questions: true,
thankYouCard: true,
environmentId: true,
status: true,
},
});
@@ -48,6 +49,12 @@ export default async function handle(req: NextApiRequest, res: NextApiResponse)
},
});
if (survey.status !== "inProgress") {
return res
.status(403)
.json({ message: "Survey not running", reason: survey.status, brandColor: product?.brandColor });
}
// if survey exists, return survey
return res.status(200).json({ ...survey, brandColor: product?.brandColor });
}