Skip to content

Commit

Permalink
Remove Ticket Download Button (#2140)
Browse files Browse the repository at this point in the history
Hide Ticket Download Button

<img width="356" alt="Screenshot 2024-11-09 at 21 44 18"
src="https://github.com/user-attachments/assets/31d4d2d8-df7c-440e-bb9e-de414ecdb1ad">
  • Loading branch information
17Amir17 authored Nov 9, 2024
1 parent 9d94b10 commit f39c613
Show file tree
Hide file tree
Showing 7 changed files with 15 additions and 242 deletions.
31 changes: 5 additions & 26 deletions apps/passport-client/components/shared/PCDCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import {
TicketQR as EddsaTicketQR
} from "@pcd/eddsa-ticket-pcd-ui";
import { PCD, PCDUI } from "@pcd/pcd-types";
import { isPODPCD } from "@pcd/pod-pcd";
import { PODPCDUI } from "@pcd/pod-pcd-ui";
import { isPODTicketPCD } from "@pcd/pod-ticket-pcd";
import {
PODTicketPCDUI,
Expand All @@ -28,8 +30,6 @@ import { pcdRenderers } from "../../src/pcdRenderers";
import { usePackage } from "../../src/usePackage";
import { Button, H4, Spacer, TextCenter } from "../core";
import { MainIdentityCard } from "./MainIdentityCard";
import { isPODPCD } from "@pcd/pod-pcd";
import { PODPCDUI } from "@pcd/pod-pcd-ui";

export const PCDCard = memo(PCDCardImpl);

Expand Down Expand Up @@ -245,9 +245,8 @@ const TicketWrapper = forwardRef<
pcd: EdDSATicketPCD;
hidePadding?: boolean;
addOns?: AddOnsProps;
showDownloadButton?: boolean;
}
>(({ pcd, hidePadding, addOns, showDownloadButton }, ref) => {
>(({ pcd, hidePadding, addOns }, ref) => {
const Card = EdDSATicketPCDUI.renderCardBody;
const identityPCD = useUserIdentityPCD();
const ticketCategory = pcd.claim.ticket.ticketCategory;
Expand Down Expand Up @@ -298,7 +297,6 @@ const TicketWrapper = forwardRef<
verifyURL={verifyURL}
idBasedVerifyURL={idBasedVerifyURL}
addOns={addOns}
showDownloadButton={showDownloadButton}
/>
</div>
) : null;
Expand All @@ -312,37 +310,19 @@ type CardBodyProps = {
isMainIdentity: boolean;
hidePadding?: boolean;
addOns?: AddOnsProps;
showDownloadButton?: boolean;
deletePodPcd?: () => Promise<void>;
};

export const CardBody = forwardRef<HTMLDivElement, CardBodyProps>(
(
{
pcd,
isMainIdentity,
hidePadding,
addOns,
showDownloadButton,
deletePodPcd
},
ref
) => {
({ pcd, isMainIdentity, hidePadding, addOns, deletePodPcd }, ref) => {
const pcdCollection = usePCDCollection();

if (isMainIdentity) {
return <MainIdentityCard />;
}
if (pcdCollection.hasPackage(pcd.type)) {
if (isEdDSATicketPCD(pcd)) {
return (
<TicketWrapper
showDownloadButton={showDownloadButton}
ref={ref}
pcd={pcd}
hidePadding={hidePadding}
/>
);
return <TicketWrapper ref={ref} pcd={pcd} hidePadding={hidePadding} />;
}
if (isPODTicketPCD(pcd)) {
const Component = PODTicketPCDUI.renderCardBody;
Expand All @@ -352,7 +332,6 @@ export const CardBody = forwardRef<HTMLDivElement, CardBodyProps>(
id={pcd.claim.ticket.eventId + pcd.claim.ticket.attendeeEmail}
>
<Component
showDownoladButton={showDownloadButton}
ticketData={pcd.claim.ticket}
addOns={addOns}
pcd={pcd}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,6 @@ export const NewHomeScreen = (): ReactElement => {
{packs.map((pack) => {
return (
<CardBody
showDownloadButton={true}
key={pack.eventName + pack.attendeeEmail}
addOns={
pack.addOns.length > 0
Expand Down
3 changes: 1 addition & 2 deletions packages/ui/eddsa-ticket-pcd-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,7 @@
"@pcd/eddsa-ticket-pcd": "0.10.0",
"@pcd/passport-interface": "^0.15.0",
"@pcd/passport-ui": "0.15.0",
"@pcd/pcd-types": "0.15.0",
"html-to-image": "^1.11.11"
"@pcd/pcd-types": "0.15.0"
},
"devDependencies": {
"@pcd/eslint-config-custom": "0.15.0",
Expand Down
84 changes: 2 additions & 82 deletions packages/ui/eddsa-ticket-pcd-ui/src/CardBody.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ import {
import { ZUCONNECT_23_DAY_PASS_PRODUCT_ID } from "@pcd/passport-interface";
import { styled } from "@pcd/passport-ui";
import { PCDUI } from "@pcd/pcd-types";
import { toCanvas } from "html-to-image";
import { useRef, useState } from "react";
import { useRef } from "react";
import { TicketQR } from "./TicketQR";

type NEW_UI__AddOns = {
Expand All @@ -29,8 +28,6 @@ export interface EdDSATicketPCDCardProps {
hidePadding?: boolean;
// when clicked on the the addons sections, if there is any, do something
addOns?: NEW_UI__AddOns;
// defined by if the image has QR code displayed and by this flag.
showDownloadButton?: boolean;
}

export const EdDSATicketPCDUI: PCDUI<EdDSATicketPCD, EdDSATicketPCDCardProps> =
Expand All @@ -43,14 +40,12 @@ function EdDSATicketPCDCardBody({
pcd,
verifyURL,
idBasedVerifyURL,
addOns,
showDownloadButton
addOns
}: {
pcd: EdDSATicketPCD;
} & EdDSATicketPCDCardProps): JSX.Element {
const ticketImageRef = useRef<HTMLDivElement>(null);
const ticketData = getEdDSATicketData(pcd);
const [downloading, setDownloading] = useState(false);

// If ticket has an `eventStartDate` render the `qrCodeOverrideImageUrl`, if it exists
// Else, render the `imageUrl`, if it existss
Expand Down Expand Up @@ -96,26 +91,6 @@ function EdDSATicketPCDCardBody({
</NEW_UI__InfoContainer>
</NEW_UI__TicketImageContainer>
<div>
{!imageToRender && showDownloadButton && (
<NEW_UI__ExtraSection
onClick={async () => {
if (downloading) return;
setDownloading(true);
const ticketElement = ticketImageRef.current;
if (!ticketElement) return;
await shareOrDownloadImage(
ticketElement,
(ticketData?.eventName || "event-ticket-data") + ".jpeg"
);
setDownloading(false);
}}
>
<NEW_UI__ExtraSectionText $disabled={downloading}>
Download ticket
</NEW_UI__ExtraSectionText>
<DownloadIcon />
</NEW_UI__ExtraSection>
)}
{addOns && (
<NEW_UI__ExtraSection onClick={addOns.onClick}>
<NEW_UI__ExtraSectionText>{addOns.text}</NEW_UI__ExtraSectionText>
Expand Down Expand Up @@ -257,20 +232,6 @@ const ExtraSectionSecondaryText = styled.div`
line-height: 135%; /* 16.2px */
`;

const DownloadIcon = (): JSX.Element => (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 16 16"
fill="var(--text-tertiary)"
className="size-4"
width={20}
height={20}
>
<path d="M6.22 8.72a.75.75 0 0 0 1.06 1.06l5.22-5.22v1.69a.75.75 0 0 0 1.5 0v-3.5a.75.75 0 0 0-.75-.75h-3.5a.75.75 0 0 0 0 1.5h1.69L6.22 8.72Z" />
<path d="M3.5 6.75c0-.69.56-1.25 1.25-1.25H7A.75.75 0 0 0 7 4H4.75A2.75 2.75 0 0 0 2 6.75v4.5A2.75 2.75 0 0 0 4.75 14h4.5A2.75 2.75 0 0 0 12 11.25V9a.75.75 0 0 0-1.5 0v2.25c0 .69-.56 1.25-1.25 1.25h-4.5c-.69 0-1.25-.56-1.25-1.25v-4.5Z" />
</svg>
);

const QRIcon = (): JSX.Element => (
<svg
xmlns="http://www.w3.org/2000/svg"
Expand Down Expand Up @@ -300,44 +261,3 @@ const QRIcon = (): JSX.Element => (
<path d="M8.5 9.417a.917.917 0 1 1 1.833 0 .917.917 0 0 1-1.833 0ZM8.5 13.083a.917.917 0 1 1 1.833 0 .917.917 0 0 1-1.833 0ZM13.083 8.5a.917.917 0 1 0 0 1.833.917.917 0 0 0 0-1.833ZM12.166 13.084a.917.917 0 1 1 1.833 0 .917.917 0 0 1-1.833 0ZM11.25 10.333a.917.917 0 1 0 0 1.833.917.917 0 0 0 0-1.833Z" />
</svg>
);

const shareOrDownloadImage = async (
ticketElement: HTMLElement | null,
fileName: string
): Promise<void> => {
if (!ticketElement) return;

const canvas: HTMLCanvasElement = await toCanvas(ticketElement);
const blob: Blob | null = await new Promise((resolve) =>
canvas.toBlob(resolve, "image/jpeg")
);
if (!blob) return; // Ensure the blob exists before proceeding

const downloadImage = (blob: Blob, fileName: string): void => {
const url = URL.createObjectURL(blob);
const link = document.createElement("a");
link.href = url;
link.download = fileName;
link.click();
URL.revokeObjectURL(url);
};
const file = new File([blob], fileName, { type: "image/jpeg" });
if (navigator.share && navigator.canShare({ files: [file] })) {
try {
await navigator.share({
files: [file]
});
} catch (e) {
console.error("Error sharing image", e);
// Ignore errors related to the user aborting the share or a share already in progress
if (
e instanceof Error &&
["AbortError", "InvalidStateError"].includes(e.name)
)
return;
downloadImage(blob, fileName);
}
} else {
downloadImage(blob, fileName);
}
};
1 change: 0 additions & 1 deletion packages/ui/pod-ticket-pcd-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
"@pcd/passport-ui": "0.15.0",
"@pcd/pcd-types": "0.15.0",
"@pcd/pod-ticket-pcd": "0.5.0",
"html-to-image": "^1.11.11",
"url-join": "4.0.1"
},
"devDependencies": {
Expand Down
89 changes: 3 additions & 86 deletions packages/ui/pod-ticket-pcd-ui/src/CardBody.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ import { QRDisplayWithRegenerateAndStorage, styled } from "@pcd/passport-ui";
import { PCDUI } from "@pcd/pcd-types";
import { PODTicketPCD } from "@pcd/pod-ticket-pcd";
import { IPODTicketData } from "@pcd/pod-ticket-pcd/src/schema";
import { toCanvas } from "html-to-image";
import { useCallback, useRef, useState } from "react";
import { useCallback, useRef } from "react";
import urlJoin from "url-join";

type NEW_UI__AddOns = {
Expand All @@ -14,7 +13,6 @@ export interface PODTicketPCDCardProps {
ticketData: IPODTicketData;
idBasedVerifyURL: string;
addOns?: NEW_UI__AddOns;
showDownoladButton?: boolean;
}

export const PODTicketPCDUI: PCDUI<PODTicketPCD, PODTicketPCDCardProps> = {
Expand All @@ -24,17 +22,14 @@ export const PODTicketPCDUI: PCDUI<PODTicketPCD, PODTicketPCDCardProps> = {
function PODTicketCardBody({
pcd,
idBasedVerifyURL,
addOns,
showDownoladButton
addOns
}: {
pcd: PODTicketPCD;
idBasedVerifyURL: string;
addOns?: NEW_UI__AddOns;
showDownoladButton?: boolean;
}): JSX.Element {
return (
<PODTicketCardBodyImpl
showDownoladButton={showDownoladButton}
ticketData={pcd.claim.ticket}
idBasedVerifyURL={idBasedVerifyURL}
addOns={addOns}
Expand All @@ -45,13 +40,10 @@ function PODTicketCardBody({
export function PODTicketCardBodyImpl({
ticketData,
idBasedVerifyURL,
addOns,
showDownoladButton
addOns
}: PODTicketPCDCardProps): JSX.Element {
const ticketImageRef = useRef<HTMLDivElement>(null);

const [downloading, setDownloading] = useState(false);

// If ticket has an `eventStartDate` render the `qrCodeOverrideImageUrl`, if it exists
// Else, render the `imageUrl`, if it existss
const imageToRender = ticketData?.eventStartDate
Expand Down Expand Up @@ -94,26 +86,6 @@ export function PODTicketCardBodyImpl({
</NEW_UI__InfoContainer>
</NEW_UI__TicketImageContainer>
<div>
{showDownoladButton && !imageToRender && (
<NEW_UI__ExtraSection
onClick={async () => {
if (downloading) return;
setDownloading(true);
const ticketElement = ticketImageRef.current;
if (!ticketElement) return;
await shareOrDownloadImage(
ticketElement,
(ticketData?.eventName || "event-ticket-data") + ".jpeg"
);
setDownloading(false);
}}
>
<NEW_UI__ExtraSectionText $disabled={downloading}>
Download ticket
</NEW_UI__ExtraSectionText>
<DownloadIcon />
</NEW_UI__ExtraSection>
)}
{addOns && (
<NEW_UI__ExtraSection onClick={addOns.onClick}>
<NEW_UI__ExtraSectionText>{addOns.text}</NEW_UI__ExtraSectionText>
Expand Down Expand Up @@ -289,20 +261,6 @@ const ExtraSectionSecondaryText = styled.div`
line-height: 135%; /* 16.2px */
`;

const DownloadIcon = (): JSX.Element => (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 16 16"
fill="var(--text-tertiary)"
className="size-4"
width={20}
height={20}
>
<path d="M6.22 8.72a.75.75 0 0 0 1.06 1.06l5.22-5.22v1.69a.75.75 0 0 0 1.5 0v-3.5a.75.75 0 0 0-.75-.75h-3.5a.75.75 0 0 0 0 1.5h1.69L6.22 8.72Z" />
<path d="M3.5 6.75c0-.69.56-1.25 1.25-1.25H7A.75.75 0 0 0 7 4H4.75A2.75 2.75 0 0 0 2 6.75v4.5A2.75 2.75 0 0 0 4.75 14h4.5A2.75 2.75 0 0 0 12 11.25V9a.75.75 0 0 0-1.5 0v2.25c0 .69-.56 1.25-1.25 1.25h-4.5c-.69 0-1.25-.56-1.25-1.25v-4.5Z" />
</svg>
);

const QRIcon = (): JSX.Element => (
<svg
xmlns="http://www.w3.org/2000/svg"
Expand Down Expand Up @@ -332,44 +290,3 @@ const QRIcon = (): JSX.Element => (
<path d="M8.5 9.417a.917.917 0 1 1 1.833 0 .917.917 0 0 1-1.833 0ZM8.5 13.083a.917.917 0 1 1 1.833 0 .917.917 0 0 1-1.833 0ZM13.083 8.5a.917.917 0 1 0 0 1.833.917.917 0 0 0 0-1.833ZM12.166 13.084a.917.917 0 1 1 1.833 0 .917.917 0 0 1-1.833 0ZM11.25 10.333a.917.917 0 1 0 0 1.833.917.917 0 0 0 0-1.833Z" />
</svg>
);

const shareOrDownloadImage = async (
ticketElement: HTMLElement | null,
fileName: string
): Promise<void> => {
if (!ticketElement) return;

const canvas: HTMLCanvasElement = await toCanvas(ticketElement);
const blob: Blob | null = await new Promise((resolve) =>
canvas.toBlob(resolve, "image/jpeg")
);
if (!blob) return; // Ensure the blob exists before proceeding

const downloadImage = (blob: Blob, fileName: string): void => {
const url = URL.createObjectURL(blob);
const link = document.createElement("a");
link.href = url;
link.download = fileName;
link.click();
URL.revokeObjectURL(url);
};
const file = new File([blob], fileName, { type: "image/jpeg" });
if (navigator.share && navigator.canShare({ files: [file] })) {
try {
await navigator.share({
files: [file]
});
} catch (e) {
console.error("Error sharing image", e);
// Ignore errors related to the user aborting the share or a share already in progress
if (
e instanceof Error &&
["AbortError", "InvalidStateError"].includes(e.name)
)
return;
downloadImage(blob, fileName);
}
} else {
downloadImage(blob, fileName);
}
};
Loading

0 comments on commit f39c613

Please sign in to comment.