Skip to content

Commit

Permalink
feat(tickets list): add download btn
Browse files Browse the repository at this point in the history
  • Loading branch information
ororsatti committed Sep 26, 2024
1 parent b1fa189 commit a67f481
Show file tree
Hide file tree
Showing 4 changed files with 216 additions and 72 deletions.
140 changes: 77 additions & 63 deletions apps/passport-client/components/shared/PCDCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,15 @@ import { EdDSATicketPCDUI } from "@pcd/eddsa-ticket-pcd-ui";
import { PCD, PCDUI } from "@pcd/pcd-types";
import { isPODTicketPCD } from "@pcd/pod-ticket-pcd";
import { PODTicketPCDUI } from "@pcd/pod-ticket-pcd-ui";
import { memo, useCallback, useContext, useMemo, useState } from "react";
import {
ForwardedRef,
forwardRef,
memo,
useCallback,
useContext,
useMemo,
useState
} from "react";
import styled, { FlattenSimpleInterpolation, css } from "styled-components";
import { usePCDCollection, useUserIdentityPCD } from "../../src/appHooks";
import { StateContext } from "../../src/dispatch";
Expand Down Expand Up @@ -163,15 +171,14 @@ function getUI(
* of ZK proofs, and can be configured to include different URLs in their QR
* codes based on the type of ticket provided.
*/
function TicketWrapper({
pcd,
hidePadding,
newUI
}: {
pcd: EdDSATicketPCD;
hidePadding?: boolean;
newUI?: boolean;
}): JSX.Element | null {
const TicketWrapper = forwardRef<
HTMLDivElement,
{
pcd: EdDSATicketPCD;
hidePadding?: boolean;
newUI?: boolean;
}
>(({ pcd, newUI, hidePadding }, ref) => {
const Card = EdDSATicketPCDUI.renderCardBody;
const identityPCD = useUserIdentityPCD();
const ticketCategory = pcd.claim.ticket.ticketCategory;
Expand Down Expand Up @@ -212,69 +219,76 @@ function TicketWrapper({
: `${window.location.origin}/#/verify`;

return identityPCD ? (
<Card
newUI={newUI}
hidePadding={hidePadding}
pcd={pcd}
identityPCD={identityPCD}
verifyURL={verifyURL}
idBasedVerifyURL={idBasedVerifyURL}
/>
<div ref={ref}>
<Card
newUI={newUI}
hidePadding={hidePadding}
pcd={pcd}
identityPCD={identityPCD}
verifyURL={verifyURL}
idBasedVerifyURL={idBasedVerifyURL}
/>
</div>
) : null;
}
});

export function CardBody({
pcd,
isMainIdentity,
hidePadding,
newUI
}: {
type CardBodyProps = {
pcd: PCD;
isMainIdentity: boolean;
hidePadding?: boolean;
newUI?: boolean;
}): JSX.Element {
const pcdCollection = usePCDCollection();
};

if (isMainIdentity) {
return <MainIdentityCard />;
}
if (pcdCollection.hasPackage(pcd.type)) {
if (isEdDSATicketPCD(pcd)) {
return (
<TicketWrapper newUI={newUI} pcd={pcd} hidePadding={hidePadding} />
);
}
if (isPODTicketPCD(pcd)) {
const Component = PODTicketPCDUI.renderCardBody;
return (
<Component
newUI={newUI}
pcd={pcd}
idBasedVerifyURL={`${window.location.origin}/#/generic-checkin`}
/>
);
export const CardBody = forwardRef<HTMLDivElement, CardBodyProps>(
({ pcd, isMainIdentity, hidePadding, newUI }, ref) => {
const pcdCollection = usePCDCollection();

if (isMainIdentity) {
return <MainIdentityCard />;
}
const ui = getUI(pcd.type);
if (ui) {
const Component = ui.renderCardBody;
return <Component pcd={pcd} />;
} else {
console.warn(`Could not find a UI renderer for PCD type "${pcd.type}"`);
if (pcdCollection.hasPackage(pcd.type)) {
if (isEdDSATicketPCD(pcd)) {
return (
<TicketWrapper
ref={ref}
newUI={newUI}
pcd={pcd}
hidePadding={hidePadding}
/>
);
}
if (isPODTicketPCD(pcd)) {
const Component = PODTicketPCDUI.renderCardBody;
return (
<div ref={ref}>
<Component
newUI={newUI}
pcd={pcd}
idBasedVerifyURL={`${window.location.origin}/#/generic-checkin`}
/>
</div>
);
}
const ui = getUI(pcd.type);
if (ui) {
const Component = ui.renderCardBody;
return <Component pcd={pcd} />;
} else {
console.warn(`Could not find a UI renderer for PCD type "${pcd.type}"`);
}
}
}

return (
<>
<TextCenter>
{pcd.type} unsupported <br />
no implementation of a ui for this type of card found
</TextCenter>
<Spacer h={16} />
</>
);
}

return (
<>
<TextCenter>
{pcd.type} unsupported <br />
no implementation of a ui for this type of card found
</TextCenter>
<Spacer h={16} />
</>
);
}
);
export const CardContainer = styled.div`
width: 100%;
padding: 8px;
Expand Down
20 changes: 15 additions & 5 deletions apps/passport-client/new-components/screens/Home/NewHomeScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -177,10 +177,13 @@ export const NewHomeScreen = (): ReactElement => {
const [currentPos, setCurrentPos] = useState(0);
const [width, setWidth] = useState(0);
const [width2, setWidth2] = useState(0);
const [ticketHeight, setTicketHeight] = useState(0);
const scrollRef = useRef<HTMLDivElement>(null);
const pcdCardScrollRef = useRef<HTMLDivElement>(null);
const ticketRef = useRef<HTMLDivElement>(null);
const self = useSelf();
const navigate = useNavigate();

useEffect(() => {
if (!self) {
navigate("/new/login", { replace: true });
Expand All @@ -202,6 +205,9 @@ export const NewHomeScreen = (): ReactElement => {
)
);
}
if (ticketRef.current) {
setTicketHeight(ticketRef.current.clientHeight);
}
}, [setWidth, setWidth2, tickets.length]);

if (!tickets.length)
Expand All @@ -224,7 +230,6 @@ export const NewHomeScreen = (): ReactElement => {
amount={tickets.length - 1}
>
{tickets.map(([eventName, eventTickets], i) => {
console.log(eventTickets);
const eventDetails = getEventDetails(eventTickets);
return (
<TicketCard
Expand Down Expand Up @@ -282,7 +287,7 @@ export const NewHomeScreen = (): ReactElement => {
<Spacer h={20} />
<Container
elWidth={width2}
height={(TICKET_HEIGHT + TICKET_GAP) * tickets[currentPos][1].length}
height={(ticketHeight + TICKET_GAP) * tickets[currentPos][1].length}
>
<Scroller
gap={ANOTHER_GAP}
Expand All @@ -296,11 +301,16 @@ export const NewHomeScreen = (): ReactElement => {
offset={(420 - width2) / 2}
amount={tickets.length - 1}
>
{tickets.map(([_eventName, eventTickets]) => {
{tickets.map(([_eventName, eventTickets], i) => {
return (
<TicketsContainer>
{eventTickets.map((ticket) => (
<CardBody newUI={true} pcd={ticket} isMainIdentity={false} />
{eventTickets.map((ticket, j) => (
<CardBody
ref={!!i && !!j ? ticketRef : undefined}
newUI={true}
pcd={ticket}
isMainIdentity={false}
/>
))}
</TicketsContainer>
);
Expand Down
64 changes: 62 additions & 2 deletions packages/ui/eddsa-ticket-pcd-ui/src/CardBody.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,22 @@ function EdDSATicketPCDCardBody({
const ticketData = getEdDSATicketData(pcd);

const [zk, setZk] = useState<boolean>(idBasedVerifyURL === undefined);

const onToggle = useCallback(() => {
setZk(!zk);
}, [zk]);

const redact = zk && idBasedVerifyURL !== undefined;
if (newUI) {
const data = Buffer.from(
JSON.stringify(
pcd,
(_, v) => (typeof v === "bigint" ? v.toString() : v),

2
)
);
const blob = new Blob([data], { type: "plain/json" });
return (
<NEW_UI__Container>
<div
Expand Down Expand Up @@ -91,6 +101,18 @@ function EdDSATicketPCDCardBody({
<NEW_UI__ExtraInfo>{ticketData?.ticketName}</NEW_UI__ExtraInfo>
</NEW_UI__ExtraInfoContainer>
</NEW_UI__InfoContainer>
<NEW_UI__ExtraSection
onClick={() => {
const a = document.createElement("a");
a.href = URL.createObjectURL(blob);
a.download = "test.json";
a.click();
a.remove();
}}
>
<NEW_UI__ExtraSectionText>Download ticket</NEW_UI__ExtraSectionText>
<DownloadIcon />
</NEW_UI__ExtraSection>
</NEW_UI__Container>
);
}
Expand Down Expand Up @@ -227,14 +249,17 @@ const ZKMode = styled.div`
`;

const NEW_UI__Container = styled.div`
font-family: Barlow;
font-family: Rubik;
border-radius: 16px;
border: 2px solid var(--text-white, #fff);
background: var(--bg-white-transparent, rgba(255, 255, 255, 0.8));
/* shadow-sm */
box-shadow: 0px 1px 2px 0px rgba(0, 0, 0, 0.05);
padding: 16px;
display: flex;
flex-direction: column;
gap: 16px;
`;

const NEW_UI__InfoContainer = styled.div`
Expand All @@ -243,13 +268,13 @@ const NEW_UI__InfoContainer = styled.div`
justify-content: center;
align-items: flex-start;
`;

const NEW_UI__AttendeeName = styled.div`
color: #9a4ac9;
font-size: 20px;
font-style: normal;
font-weight: 800;
line-height: 135%; /* 27px */
font-family: Barlow, sans-serif;
`;

const NEW_UI__ExtraInfoContainer = styled.div`
Expand All @@ -264,3 +289,38 @@ const NEW_UI__ExtraInfo = styled.div`
font-weight: 400;
line-height: 135%; /* 18.9px */
`;

const NEW_UI__ExtraSection = styled.div`
display: flex;
flex-direction: row;
border-top: 1px solid #eee;
padding: 16px 0;
justify-content: space-between;
`;

const NEW_UI__ExtraSectionText = styled.div`
color: var(--text-primary);
font-family: Rubik;
font-size: 16px;
font-weight: 400;
line-height: 135%;
`;

const DownloadIcon = (): JSX.Element => (
<svg
width={20}
height={20}
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
strokeWidth={1.5}
stroke="var(--text-tertiary)"
className="size-6"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M13.5 6H5.25A2.25 2.25 0 0 0 3 8.25v10.5A2.25 2.25 0 0 0 5.25 21h10.5A2.25 2.25 0 0 0 18 18.75V10.5m-10.5 6L21 3m0 0h-5.25M21 3v5.25"
/>
</svg>
);
Loading

0 comments on commit a67f481

Please sign in to comment.