Skip to content

Commit

Permalink
better UX for tickets + bug squashing
Browse files Browse the repository at this point in the history
  • Loading branch information
quick007 committed Nov 16, 2023
1 parent e3745cf commit b5d7841
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 73 deletions.
2 changes: 1 addition & 1 deletion components/faq/questions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export const faqs: FAQ[] = [
},
{
q: "Can users register after my event has started?",
a: "By default, users can sign up before the event has started or an hour after starting. You can change this in your event settings.",
a: "By default, users can sign up before the event and a few minutes into it. You can change this in your event settings.",
},
];

Expand Down
2 changes: 1 addition & 1 deletion islands/events/viewing/register.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@ export const Contact = ({ email }: { email: string }) => {
return (
<>
<button
className="flex items-center select-none font-medium hover:bg-gray-200/75 hover:text-gray-900 transition text-sm mx-auto mt-4 rounded-md bg-white/25 backdrop-blur-xl border px-1.5 py-0.5"
className="flex items-center select-none font-medium hover:bg-gray-200/75 hover:text-gray-900 transition text-sm mt-4 rounded-md bg-white/25 backdrop-blur-xl border px-1.5 py-0.5"
onClick={() => setOpen(true)}
>
Contact Organizer
Expand Down
144 changes: 75 additions & 69 deletions routes/events/[id]/(no-layout)/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import Calender from "$tabler/calendar.tsx";

import EventRegister, { Contact } from "@/islands/events/viewing/register.tsx";
import Footer from "@/components/layout/footer.tsx";
import { fmtDate, fmtTime, happened } from "@/utils/dates.ts";
import { fmtDate, fmtTime, getTimeZone, happened } from "@/utils/dates.ts";
import { Avalibility } from "@/islands/events/viewing/availability.tsx";
import { ShowTimes } from "@/islands/events/viewing/showtimes.tsx";
import { acquired, getTicketID } from "@/utils/tickets.ts";
Expand All @@ -21,6 +21,10 @@ export default defineRoute((req, ctx: RouteContext<void, EventContext>) => {
acquired(user?.data, eventID, time.id),
).length;

const booked =
event.showTimes.every((time) => happened(time.startDate, time.startTime)) ||
event.showTimes.every((time) => time.soldTickets == time.maxTickets);

const banner = () => {
if (imagekit && event.banner.path) {
const getURL = (width: number) =>
Expand Down Expand Up @@ -89,20 +93,34 @@ export default defineRoute((req, ctx: RouteContext<void, EventContext>) => {
<p class="mb-4">{event.summary}</p>
<h2 className="font-semibold mb-1 text-sm">Event Description</h2>
<p class=" whitespace-pre-line">{event.description}</p>
{event.venue && (
<>
<h2 className="font-semibold mt-4 text-sm">Venue</h2>
<p>{event.venue}</p>
</>
)}
{event.showTimes.length == 1 && event.showTimes[0].lastPurchaseDate && (
<p class="text-xs text-gray-600 text-center mt-2">
The last day to get tickets is{" "}
{fmtDate(new Date(event.showTimes[0].lastPurchaseDate))}
The last day to get tickets is {fmtDate(new Date(event.showTimes[0].lastPurchaseDate))} at Midnight (
{getTimeZone(new Date(event.showTimes[0].lastPurchaseDate))})

</p>
)}
{event.venue && (
<>
<h2 className="font-semibold mt-4 mb-1 text-sm">Venue</h2>
<p class="mb-4">{event.venue}</p>
</>
</div>
<div class="flex flex-col-reverse md:flex-row gap-4 justify-center items-center">
<Contact email={event.supportEmail} />
{(!user ||
(tickets < event.showTimes.length &&
event.showTimes.length !== 1 &&
tickets >= 1)) && (
<a
class="flex items-center select-none font-medium hover:bg-gray-200/75 hover:text-gray-900 transition text-sm mt-4 rounded-md bg-white/25 backdrop-blur-xl border px-1.5 py-0.5"
href={user ? "/events/attending" : "/login?attending=true"}
>
{user ? "See Acquired Tickets" : "Log in to view acquired tickets"}
</a>
)}
</div>
<Contact email={event.supportEmail} />
</>
);

Expand Down Expand Up @@ -219,79 +237,67 @@ export default defineRoute((req, ctx: RouteContext<void, EventContext>) => {
<div className="max-w-2xl mx-auto w-full mb-36 md:mb-16 mt-4 md:-mt-28 flex flex-col px-4 static grow">
<Header />
<ShowTimes data={ctx.state.data} />
{event.showTimes.every((time) =>
happened(time.startDate, time.startTime),
) ||
event.showTimes.every(
(time) => time.soldTickets == time.maxTickets,
) ? (
{booked && (
<div class="text-center mt-10 mb-4 mx-auto">
<p>
This event is either fully booked or prefermances have ended.
</p>
<p>Contact the organizer if you belive this is incorrect.</p>
</div>
) : (
<>
{event.showTimes.length === 1 && tickets === 1 ? (
<div className="mx-auto flex flex-col items-center mt-14">
<p class="font-semibold mb-4 text-center">
You're already registered for this event! Edit or view
ticket below.
</p>
<a
href={`/events/${eventID}/tickets/${getTicketID(
user?.data,
eventID,
event.showTimes[0].id,
)}`}
>
<CTA btnType="secondary">View Ticket</CTA>
</a>
</div>
) : (
)}
<>
{event.showTimes.length === 1 && tickets === 1 ? (
<div className="mx-auto flex flex-col items-center mt-14">
<p class="font-semibold mb-4 text-center">
You're already registered for this event! Edit or view ticket
below.
</p>
<a
href={`/events/${eventID}/tickets/${getTicketID(
user?.data,
eventID,
event.showTimes[0].id,
)}`}
>
<CTA btnType="secondary">View Ticket</CTA>
</a>
</div>
) : (
!booked &&
clientShowTimes.length > 0 && (
<EventRegister
eventID={eventID}
showTimes={clientShowTimes}
email={user?.data.email}
additionalFields={event.additionalFields}
user={user?.data}
/>
)}
{tickets < event.showTimes.length &&
event.showTimes.length !== 1 &&
tickets >= 1 && (
<a
class="text-center mt-1 text-sm font-medium underline"
href="/events/attending"
>
See Acquired Tickets
</a>
)}
{event.showTimes.length === 1 && (
<div class="mx-auto mt-2 text-sm text-center">
<Avalibility
acquired={acquired(
user?.data,
eventID,
event.showTimes[0].id,
)}
tickets={event.showTimes[0].soldTickets}
maxTickets={event.showTimes[0].maxTickets}
happened={happened(
event.showTimes[0].startDate,
event.showTimes[0].startTime,
)}
windowClosed={
event.showTimes[0].lastPurchaseDate != undefined
? happened(event.showTimes[0].lastPurchaseDate)
: false
}
/>
</div>
)}
</>
)}
)
)}

{event.showTimes.length === 1 && (
<div class="mx-auto mt-2 text-sm text-center">
<Avalibility
acquired={acquired(
user?.data,
eventID,
event.showTimes[0].id,
)}
tickets={event.showTimes[0].soldTickets}
maxTickets={event.showTimes[0].maxTickets}
happened={happened(
event.showTimes[0].startDate,
event.showTimes[0].startTime,
)}
windowClosed={
event.showTimes[0].lastPurchaseDate != undefined
? happened(event.showTimes[0].lastPurchaseDate)
: false
}
/>
</div>
)}
</>
</div>
<p class="text-center max-w-sm mx-auto mb-4 text-sm px-4">
This event was made with{" "}
Expand Down
2 changes: 1 addition & 1 deletion static/output.css

Large diffs are not rendered by default.

7 changes: 6 additions & 1 deletion utils/dates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,15 @@ const timeFmt = new Intl.DateTimeFormat("en-US", {
hour: "numeric",
minute: "2-digit",
});
const timezoneFmt = new Intl.DateTimeFormat("en-US", {
timeZoneName: "short",
});

export const happened = (startDate: string, startTime?: string) => {
const date = new Date(startDate);

if (startTime) {
// 5 min buffer for tickets
// 5 min buffer for tickets if someone arrives late
date.setMinutes(new Date(startTime).getMinutes() + 5);
} else {
date.setDate(date.getDate() + 1);
Expand All @@ -29,3 +32,5 @@ export const happened = (startDate: string, startTime?: string) => {
export const fmtDate = (date: Date) => dateFmt.format(date);
export const fmtHour = (date: Date) => hourFmt.format(date);
export const fmtTime = (date: Date) => timeFmt.format(date);
// not an ideal solution
export const getTimeZone = (date: Date) => timezoneFmt.format(date).split(", ")[1];

0 comments on commit b5d7841

Please sign in to comment.