feat: add QR code download functionality to share modals

- Integrated QR code generation and download options in both ShareFileModal and ShareMultipleFilesModal.
- Updated UI components to include a download button for QR codes, enhancing user experience.
- Improved icon usage by adding download functionality alongside existing share options.
This commit is contained in:
Daniel Luiz Alves
2025-07-18 11:14:56 -03:00
parent 1a5c1de510
commit 236f94247a
2 changed files with 73 additions and 10 deletions

View File

@@ -1,8 +1,9 @@
"use client"; "use client";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { IconCalendar, IconCopy, IconEye, IconLink, IconLock, IconShare } from "@tabler/icons-react"; import { IconCalendar, IconCopy, IconDownload, IconEye, IconLink, IconLock, IconShare } from "@tabler/icons-react";
import { useTranslations } from "next-intl"; import { useTranslations } from "next-intl";
import QRCode from "react-qr-code";
import { toast } from "sonner"; import { toast } from "sonner";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
@@ -123,6 +124,18 @@ export function ShareFileModal({ isOpen, file, onClose, onSuccess }: ShareFileMo
toast.success(t("generateShareLink.copied")); toast.success(t("generateShareLink.copied"));
}; };
const downloadQRCode = () => {
const canvas = document.getElementById("share-file-qr-code") as HTMLCanvasElement;
if (canvas) {
const link = document.createElement("a");
link.download = "share-file-qr-code.png";
link.href = canvas.toDataURL("image/png");
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
};
const handleClose = () => { const handleClose = () => {
onClose(); onClose();
setTimeout(() => { setTimeout(() => {
@@ -259,8 +272,26 @@ export function ShareFileModal({ isOpen, file, onClose, onSuccess }: ShareFileMo
</> </>
) : ( ) : (
<> <>
<div className="flex flex-col items-center justify-center">
<div className="p-4 bg-white rounded-lg">
<svg style={{ display: "none" }} /> {/* For SSR safety */}
<QRCode
id="share-file-qr-code"
value={generatedLink}
size={250}
level="H"
fgColor="#000000"
bgColor="#FFFFFF"
/>
</div>
</div>
<p className="text-sm text-muted-foreground">{t("shareFile.linkReady")}</p> <p className="text-sm text-muted-foreground">{t("shareFile.linkReady")}</p>
<Input readOnly value={generatedLink} /> <div className="flex gap-2">
<Input readOnly value={generatedLink} className="flex-1" />
<Button size="icon" variant="outline" onClick={handleCopyLink} title={t("shareFile.copyLink")}>
<IconCopy className="h-4 w-4" />
</Button>
</div>
</> </>
)} )}
</div> </div>
@@ -294,9 +325,9 @@ export function ShareFileModal({ isOpen, file, onClose, onSuccess }: ShareFileMo
<Button variant="outline" onClick={handleSuccess}> <Button variant="outline" onClick={handleSuccess}>
{t("common.close")} {t("common.close")}
</Button> </Button>
<Button onClick={handleCopyLink}> <Button onClick={downloadQRCode}>
<IconCopy className="h-4 w-4" /> <IconDownload className="h-4 w-4" />
{t("shareFile.copyLink")} {t("qrCodeModal.download")}
</Button> </Button>
</> </>
)} )}

View File

@@ -1,8 +1,9 @@
"use client"; "use client";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { IconCalendar, IconCopy, IconEye, IconLink, IconLock, IconShare } from "@tabler/icons-react"; import { IconCalendar, IconCopy, IconDownload, IconEye, IconLink, IconLock, IconShare } from "@tabler/icons-react";
import { useTranslations } from "next-intl"; import { useTranslations } from "next-intl";
import QRCode from "react-qr-code";
import { toast } from "sonner"; import { toast } from "sonner";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
@@ -115,6 +116,19 @@ export function ShareMultipleFilesModal({ files, isOpen, onClose, onSuccess }: S
toast.success(t("generateShareLink.copied")); toast.success(t("generateShareLink.copied"));
}; };
const downloadQRCode = () => {
const qrCodeElement = document.getElementById("share-multiple-files-qr-code");
if (qrCodeElement) {
const canvas = qrCodeElement.querySelector("canvas");
if (canvas) {
const link = document.createElement("a");
link.download = "share-multiple-files-qr-code.png";
link.href = canvas.toDataURL("image/png");
link.click();
}
}
};
const handleClose = () => { const handleClose = () => {
onClose(); onClose();
setTimeout(() => { setTimeout(() => {
@@ -282,8 +296,26 @@ export function ShareMultipleFilesModal({ files, isOpen, onClose, onSuccess }: S
</> </>
) : ( ) : (
<> <>
<div className="flex flex-col items-center justify-center">
<div className="p-4 bg-white rounded-lg">
<svg style={{ display: "none" }} /> {/* For SSR safety */}
<QRCode
id="share-multiple-files-qr-code"
value={generatedLink}
size={250}
level="H"
fgColor="#000000"
bgColor="#FFFFFF"
/>
</div>
</div>
<p className="text-sm text-muted-foreground">{t("shareFile.linkReady")}</p> <p className="text-sm text-muted-foreground">{t("shareFile.linkReady")}</p>
<Input readOnly value={generatedLink} /> <div className="flex gap-2">
<Input readOnly value={generatedLink} className="flex-1" />
<Button variant="outline" size="icon" onClick={handleCopyLink} title={t("shareFile.copyLink")}>
<IconCopy className="h-4 w-4" />
</Button>
</div>
</> </>
)} )}
</div> </div>
@@ -323,9 +355,9 @@ export function ShareMultipleFilesModal({ files, isOpen, onClose, onSuccess }: S
<Button variant="outline" onClick={handleSuccess}> <Button variant="outline" onClick={handleSuccess}>
{t("common.close")} {t("common.close")}
</Button> </Button>
<Button onClick={handleCopyLink}> <Button onClick={downloadQRCode}>
<IconCopy className="h-4 w-4" /> <IconDownload className="h-4 w-4" />
{t("shareFile.copyLink")} {t("qrCodeModal.download")}
</Button> </Button>
</> </>
)} )}