feat: added qr code feature (#4951)

This commit is contained in:
Paribesh Nepal
2025-03-18 19:51:32 +05:30
committed by GitHub
parent a391089efc
commit b1e8cb5a07
12 changed files with 149 additions and 15 deletions
@@ -16,6 +16,7 @@ interface LinkTabProps {
export const LinkTab = ({ survey, webAppUrl, surveyUrl, setSurveyUrl, locale }: LinkTabProps) => {
const { t } = useTranslate();
const docsLinks = [
{
title: t("environments.surveys.summary.data_prefilling"),
@@ -48,6 +49,7 @@ export const LinkTab = ({ survey, webAppUrl, surveyUrl, setSurveyUrl, locale }:
locale={locale}
/>
</div>
<div className="flex flex-wrap justify-between gap-2">
<p className="pt-2 font-semibold text-slate-700">
{t("environments.surveys.summary.you_can_do_a_lot_more_with_links_surveys")} 💡
@@ -0,0 +1,36 @@
import { Options } from "qr-code-styling";
export const getQRCodeOptions = (width: number, height: number): Options => ({
width,
height,
type: "svg",
data: "",
margin: 0,
qrOptions: {
typeNumber: 0,
mode: "Byte",
errorCorrectionLevel: "L",
},
imageOptions: {
saveAsBlob: true,
hideBackgroundDots: false,
imageSize: 0,
margin: 0,
},
dotsOptions: {
type: "extra-rounded",
color: "#000000",
roundSize: true,
},
backgroundOptions: {
color: "#ffffff",
},
cornersSquareOptions: {
type: "dot",
color: "#000000",
},
cornersDotOptions: {
type: "dot",
color: "#000000",
},
});
@@ -0,0 +1,44 @@
"use client";
import { getQRCodeOptions } from "@/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/lib/get-qr-code-options";
import { useTranslate } from "@tolgee/react";
import QRCodeStyling from "qr-code-styling";
import { useEffect, useRef } from "react";
import { toast } from "react-hot-toast";
export const useSurveyQRCode = (surveyUrl: string) => {
const qrCodeRef = useRef<HTMLDivElement>(null);
const qrInstance = useRef<QRCodeStyling | null>(null);
const { t } = useTranslate();
useEffect(() => {
try {
if (!qrInstance.current) {
qrInstance.current = new QRCodeStyling(getQRCodeOptions(70, 70));
}
if (surveyUrl && qrInstance.current) {
qrInstance.current.update({ data: surveyUrl });
if (qrCodeRef.current) {
qrCodeRef.current.innerHTML = "";
qrInstance.current.append(qrCodeRef.current);
}
}
} catch (error) {
toast.error(t("environments.surveys.summary.failed_to_generate_qr_code"));
}
}, [surveyUrl]);
const downloadQRCode = () => {
try {
const downloadInstance = new QRCodeStyling(getQRCodeOptions(500, 500));
downloadInstance.update({ data: surveyUrl });
downloadInstance.download({ name: "survey-qr", extension: "png" });
} catch (error) {
toast.error(t("environments.surveys.summary.failed_to_generate_qr_code"));
}
};
return { qrCodeRef, downloadQRCode };
};
@@ -1,10 +1,11 @@
"use client";
import { useSurveyQRCode } from "@/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/lib/survey-qr-code";
import { getFormattedErrorMessage } from "@/lib/utils/helper";
import { generateSingleUseIdAction } from "@/modules/survey/list/actions";
import { Button } from "@/modules/ui/components/button";
import { useTranslate } from "@tolgee/react";
import { Copy, RefreshCcw, SquareArrowOutUpRight } from "lucide-react";
import { Copy, QrCode, RefreshCcw, SquareArrowOutUpRight } from "lucide-react";
import { useCallback, useEffect, useState } from "react";
import { toast } from "react-hot-toast";
import { TSurvey } from "@formbricks/types/surveys/types";
@@ -68,6 +69,8 @@ export const ShareSurveyLink = ({
getUrl();
}, [survey, getUrl, language]);
const { downloadQRCode } = useSurveyQRCode(surveyUrl);
return (
<div
className={`flex max-w-full flex-col items-center justify-center space-x-2 ${survey.singleUse?.enabled ? "flex-col" : "lg:flex-row"}`}>
@@ -100,6 +103,14 @@ export const ShareSurveyLink = ({
{t("common.copy")}
<Copy />
</Button>
<Button
variant="secondary"
title={t("environments.surveys.summary.download_qr_code")}
aria-label={t("environments.surveys.summary.download_qr_code")}
size={"icon"}
onClick={downloadQRCode}>
<QrCode style={{ width: "24px", height: "24px" }} />
</Button>
{survey.singleUse?.enabled && (
<Button
title="Regenerate single use survey link"
+1
View File
@@ -115,6 +115,7 @@
"papaparse": "5.4.1",
"posthog-js": "1.200.2",
"prismjs": "1.30.0",
"qr-code-styling": "1.9.1",
"react": "19.0.0",
"react-colorful": "5.6.1",
"react-confetti": "6.1.0",