Skip to content

Commit 6552dbf

Browse files
committed
fancy tiquettas
1 parent 62ad858 commit 6552dbf

5 files changed

Lines changed: 191 additions & 131 deletions

File tree

devconnect-app/src/app/globals.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,4 +314,8 @@ svg.icon {
314314

315315
.tippy-popper {
316316
z-index: 10000000000000 !important;
317+
}
318+
319+
.gradient-background {
320+
background: linear-gradient(360deg, rgba(246, 182, 19, 0.15) 6.87%, rgba(255, 133, 166, 0.15) 14.79%, rgba(152, 148, 255, 0.15) 22.84%, rgba(116, 172, 223, 0.15) 43.68%, rgba(238, 247, 255, 0.15) 54.97%);
317321
}

devconnect-app/src/app/schedule/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export default function ProgrammePageContent() {
1212

1313
return (
1414
<PageLayout title="Ethereum World's Fair" tabs={homeTabs()}>
15-
<div className={cn('text-left touch-only:px-0 p-4', css['schedule-tab'])}>
15+
<div className={cn('text-left touch-only:px-0 p-4')}>
1616
<ScheduleLayout
1717
isCommunityCalendar={false}
1818
events={events}

devconnect-app/src/app/tickets/page.tsx

Lines changed: 185 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
'use client';
22

3-
import { useEffect, useState } from 'react';
3+
import { useState } from 'react';
44
import { fetchAuth } from '@/services/apiClient';
55
import VoxelButton from 'lib/components/voxel-button/button';
66
import { toast } from 'sonner';
7+
import TicketImage from '@/images/devconnect-arg-ticket.png';
8+
import Image from 'next/image';
79
import {
810
useAdditionalTicketEmails,
911
ensureUserData,
@@ -13,6 +15,7 @@ import { useGlobalStore } from '@/app/store.provider';
1315
import { RequiresAuthHOC } from '@/components/RequiresAuthHOC';
1416
import { homeTabs } from '../navigation';
1517
import PageLayout from '@/components/PageLayout';
18+
import cn from 'classnames';
1619

1720
const TicketWrapper = () => {
1821
return (
@@ -22,23 +25,178 @@ const TicketWrapper = () => {
2225
);
2326
};
2427

25-
const TicketTab = RequiresAuthHOC(() => {
28+
const ConnectedEmails = () => {
2629
const additionalTicketEmails = useAdditionalTicketEmails();
2730
const setUserData = useGlobalStore((state) => state.setUserData);
2831
const email = useGlobalStore((state) => state.userData?.email);
32+
const { refresh } = useTickets();
2933

30-
// Use the tickets hook from store
31-
const { tickets, loading, qrCodes, refresh } = useTickets();
32-
33-
// Additional email state
3434
const [checkYourEmail, setCheckYourEmail] = useState('');
3535
const [verificationCode, setVerificationCode] = useState('');
3636
const [verifyingCode, setVerifyingCode] = useState(false);
3737
const [loadingAdditionalEmail, setLoadingAdditionalEmail] = useState(false);
38+
39+
return (
40+
<>
41+
<div className="flex gap-4 items-center space-evenly my-4">
42+
<div className="w-auto shrink grow h-px bg-gray-300" />
43+
<p className="text-sm text-gray-600 shrink-0">
44+
Your connected email addresses
45+
</p>
46+
<div className="w-auto shrink grow h-px bg-gray-300" />
47+
</div>
48+
49+
<div className="flex flex-col text-center text-xs font-medium">
50+
<div className="">{email}</div>
51+
{additionalTicketEmails.map((email: string) => (
52+
<div key={email} className="">
53+
{email}
54+
</div>
55+
))}
56+
</div>
57+
58+
<div className="flex gap-4 items-center space-evenly mt-4">
59+
<div className="w-auto shrink grow h-px bg-gray-300" />
60+
<p className="text-sm text-gray-600 shrink-0">
61+
Is your ticket on a different email address?
62+
</p>
63+
<div className="w-auto shrink grow h-px bg-gray-300" />
64+
</div>
65+
66+
<div className="flex mt-4 flex-col sm:justify-center sm:items-center">
67+
<VoxelButton
68+
size="sm"
69+
className=""
70+
onClick={async () => {
71+
const email = prompt('Enter your email address');
72+
73+
if (email) {
74+
setLoadingAdditionalEmail(true);
75+
setVerificationCode('');
76+
setCheckYourEmail('');
77+
78+
const response = await fetchAuth<{ email: string }>(
79+
'/api/auth/tickets/attach-email',
80+
{
81+
method: 'POST',
82+
body: JSON.stringify({
83+
email,
84+
redirectTo: 'https://app.devconnect.org/wallet/tickets',
85+
}),
86+
}
87+
);
88+
89+
if (response.success) {
90+
setCheckYourEmail(email);
91+
toast.success('Check your email for a verification code.');
92+
} else {
93+
console.error('Error adding email: ' + response.error);
94+
toast.error('Something went wrong. Try again later.');
95+
}
96+
97+
setLoadingAdditionalEmail(false);
98+
}
99+
}}
100+
>
101+
{loadingAdditionalEmail
102+
? 'Preparing...'
103+
: 'Add another email address'}
104+
</VoxelButton>
105+
{checkYourEmail && (
106+
<div className="text-sm text-gray-800 mt-2 text-center mt-6 flex flex-col items-center max-w-[95%]">
107+
<div>
108+
Check <span className="font-bold">{checkYourEmail}</span> for a
109+
verification code:
110+
</div>
111+
<input
112+
type="text"
113+
className="border border-neutral-300 w-full border-[1px] outline-none p-2 px-4 mt-2 text-center"
114+
value={verificationCode}
115+
placeholder="Enter verification code"
116+
onChange={(e) => setVerificationCode(e.target.value)}
117+
/>
118+
119+
<VoxelButton
120+
size="sm"
121+
className="mt-2"
122+
color="green-1"
123+
disabled={verificationCode.length !== 6}
124+
onClick={async () => {
125+
setVerifyingCode(true);
126+
127+
const response = await fetchAuth<{ email: string }>(
128+
'/api/auth/tickets/verify-email-ownership',
129+
{
130+
method: 'POST',
131+
body: JSON.stringify({
132+
emailToVerify: checkYourEmail,
133+
verificationCode,
134+
}),
135+
}
136+
);
137+
138+
if (response.success) {
139+
toast.success('Email verified successfully!');
140+
await ensureUserData(setUserData);
141+
await refresh();
142+
} else {
143+
if (response.error) {
144+
toast.error(response.error);
145+
} else {
146+
toast.error('Something went wrong. Try again later.');
147+
}
148+
}
149+
150+
setVerifyingCode(false);
151+
}}
152+
>
153+
{verifyingCode ? 'Verifying...' : 'Verify code'}{' '}
154+
{verificationCode.length !== 6 && '(6 digits required)'}
155+
</VoxelButton>
156+
</div>
157+
)}
158+
</div>
159+
</>
160+
);
161+
};
162+
163+
const Ticket = ({ ticket, qrCodes }: { ticket: any; qrCodes: any }) => {
164+
return (
165+
<div className="relative max-w-[350px] mx-auto">
166+
<Image src={TicketImage} alt="Ticket" />
167+
<div className="absolute text-gray-600 top-[25%] left-[9%] mt-1 h-[32%] flex justify-center flex-col">
168+
<div className="flex flex-col relative items-start justify-start max-w-[80%]">
169+
<div className="font-bold text-[rgba(136,85,204,1)] bg-[rgba(252,252,252,0.7)] self-start text-2xl inline leading-tight">
170+
{ticket.attendeeName}
171+
</div>
172+
</div>
173+
174+
<div className="text-sm mt-1">
175+
Ethereum World's Fair <br /> Attendee Ticket
176+
</div>
177+
</div>
178+
179+
<img
180+
src={qrCodes[ticket.secret]}
181+
alt="Ticket QR Code"
182+
className="absolute bottom-[15%] right-[8.5%] h-[22%] aspect-square p-1 border border-solid border-gray-300 rounded-sm"
183+
/>
184+
</div>
185+
);
186+
};
187+
188+
const TicketTab = RequiresAuthHOC(() => {
189+
// Use the tickets hook from store
190+
const { tickets, loading, qrCodes } = useTickets();
38191
const hasTickets = tickets && tickets.length > 0;
39192

40193
return (
41-
<div className="w-full py-6 sm:py-8 px-4 sm:px-6 max-w-4xl mx-auto">
194+
<div
195+
className={cn(
196+
'w-full py-6 sm:py-8 px-4 sm:px-6 mx-auto',
197+
'gradient-background'
198+
)}
199+
>
42200
<div className="w-full mb-8">
43201
<div className="w-full space-y-2">
44202
{loading && !hasTickets && (
@@ -56,7 +214,25 @@ const TicketTab = RequiresAuthHOC(() => {
56214
</div>
57215
)}
58216

59-
{hasTickets &&
217+
<ConnectedEmails />
218+
219+
{hasTickets && (
220+
<div className="flex flex-col gap-8 mt-8">
221+
{tickets.map((order) => (
222+
<>
223+
{order.tickets.map((ticket, idx) => (
224+
<Ticket
225+
ticket={ticket}
226+
qrCodes={qrCodes}
227+
key={ticket.secret}
228+
/>
229+
))}
230+
</>
231+
))}
232+
</div>
233+
)}
234+
235+
{/* {hasTickets &&
60236
tickets.map((order) => (
61237
<>
62238
{order.tickets.map((ticket, idx) => (
@@ -100,126 +276,7 @@ const TicketTab = RequiresAuthHOC(() => {
100276
</div>
101277
))}
102278
</>
103-
))}
104-
105-
<div className="flex gap-4 items-center space-evenly my-4">
106-
<div className="w-auto shrink grow h-px bg-gray-300" />
107-
<p className="text-sm text-gray-600 shrink-0">
108-
Your connected email addresses
109-
</p>
110-
<div className="w-auto shrink grow h-px bg-gray-300" />
111-
</div>
112-
113-
<div className="flex flex-col text-center text-xs font-medium">
114-
<div className="">{email}</div>
115-
{additionalTicketEmails.map((email: string) => (
116-
<div key={email} className="">
117-
{email}
118-
</div>
119-
))}
120-
</div>
121-
122-
<div className="flex gap-4 items-center space-evenly mt-4">
123-
<div className="w-auto shrink grow h-px bg-gray-300" />
124-
<p className="text-sm text-gray-600 shrink-0">
125-
Is your ticket on a different email address?
126-
</p>
127-
<div className="w-auto shrink grow h-px bg-gray-300" />
128-
</div>
129-
130-
<div className="flex mt-4 flex-col sm:justify-center sm:items-center">
131-
<VoxelButton
132-
size="sm"
133-
className=""
134-
onClick={async () => {
135-
const email = prompt('Enter your email address');
136-
137-
if (email) {
138-
setLoadingAdditionalEmail(true);
139-
setVerificationCode('');
140-
setCheckYourEmail('');
141-
142-
const response = await fetchAuth<{ email: string }>(
143-
'/api/auth/tickets/attach-email',
144-
{
145-
method: 'POST',
146-
body: JSON.stringify({
147-
email,
148-
redirectTo: 'https://app.devconnect.org/wallet/tickets',
149-
}),
150-
}
151-
);
152-
153-
if (response.success) {
154-
setCheckYourEmail(email);
155-
toast.success('Check your email for a verification code.');
156-
} else {
157-
console.error('Error adding email: ' + response.error);
158-
toast.error('Something went wrong. Try again later.');
159-
}
160-
161-
setLoadingAdditionalEmail(false);
162-
}
163-
}}
164-
>
165-
{loadingAdditionalEmail
166-
? 'Preparing...'
167-
: 'Add another email address'}
168-
</VoxelButton>
169-
{checkYourEmail && (
170-
<div className="text-sm text-gray-800 mt-2 text-center mt-6 flex flex-col items-center max-w-[95%]">
171-
<div>
172-
Check <span className="font-bold">{checkYourEmail}</span> for
173-
a verification code:
174-
</div>
175-
<input
176-
type="text"
177-
className="border border-neutral-300 w-full border-[1px] outline-none p-2 px-4 mt-2 text-center"
178-
value={verificationCode}
179-
placeholder="Enter verification code"
180-
onChange={(e) => setVerificationCode(e.target.value)}
181-
/>
182-
183-
<VoxelButton
184-
size="sm"
185-
className="mt-2"
186-
color="green-1"
187-
disabled={verificationCode.length !== 6}
188-
onClick={async () => {
189-
setVerifyingCode(true);
190-
191-
const response = await fetchAuth<{ email: string }>(
192-
'/api/auth/tickets/verify-email-ownership',
193-
{
194-
method: 'POST',
195-
body: JSON.stringify({
196-
emailToVerify: checkYourEmail,
197-
verificationCode,
198-
}),
199-
}
200-
);
201-
202-
if (response.success) {
203-
toast.success('Email verified successfully!');
204-
await ensureUserData(setUserData);
205-
await refresh();
206-
} else {
207-
if (response.error) {
208-
toast.error(response.error);
209-
} else {
210-
toast.error('Something went wrong. Try again later.');
211-
}
212-
}
213-
214-
setVerifyingCode(false);
215-
}}
216-
>
217-
{verifyingCode ? 'Verifying...' : 'Verify code'}{' '}
218-
{verificationCode.length !== 6 && '(6 digits required)'}
219-
</VoxelButton>
220-
</div>
221-
)}
222-
</div>
279+
))} */}
223280
</div>
224281
</div>
225282
</div>
2.01 MB
Loading

lib/components/event-schedule-new/action-bar.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,7 @@ const ActionBar = ({
5353
hideCommunityByDefault?: boolean;
5454
favorites?: string[];
5555
}) => {
56-
const categories = venueEvents; // isCommunityCalendar ? communityEvents : venueEvents;
57-
const hasLoggedInUser = true;
56+
const categories = venueEvents;
5857

5958
return (
6059
<div

0 commit comments

Comments
 (0)