Skip to content

Commit

Permalink
feat(): accept transfered ticket from My Events notification
Browse files Browse the repository at this point in the history
  • Loading branch information
joseglego committed Nov 4, 2024
1 parent a325bc3 commit 773eb50
Show file tree
Hide file tree
Showing 6 changed files with 381 additions and 10 deletions.
8 changes: 8 additions & 0 deletions app/api/gql/gql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ const documents = {
types.TransferTicketDocument,
"query myEvents($input: PaginatedInputEventsSearchInput!, $userTicketSearchInput: EventsTicketsSearchInput) {\n searchEvents(input: $input) {\n data {\n id\n name\n description\n startDateTime\n address\n previewImage {\n url\n }\n community {\n id\n name\n }\n status\n usersTickets(input: $userTicketSearchInput) {\n id\n approvalStatus\n paymentStatus\n redemptionStatus\n ticketTemplate {\n description\n id\n }\n }\n }\n pagination {\n currentPage\n pageSize\n totalPages\n totalRecords\n }\n }\n}":
types.MyEventsDocument,
"query myReceivedTransfers {\n myTicketTransfers(type: RECEIVED) {\n createdAt\n expirationDate\n id\n sender {\n email\n name\n }\n status\n transferMessage\n userTicket {\n id\n ticketTemplate {\n name\n event {\n id\n name\n }\n }\n }\n }\n}":
types.MyReceivedTransfersDocument,
"query MyPurchaseOrders($input: PaginatedInputMyPurchaseOrdersInput!) {\n myPurchaseOrders(input: $input) {\n data {\n id\n finalPrice\n paymentPlatform\n createdAt\n currency {\n id\n currency\n }\n tickets {\n id\n ticketTemplate {\n id\n name\n event {\n id\n name\n }\n }\n }\n }\n }\n}":
types.MyPurchaseOrdersDocument,
"mutation AcceptTransferredTicket($transferId: String!) {\n acceptTransferredTicket(transferId: $transferId) {\n id\n status\n userTicket {\n id\n user {\n id\n }\n }\n }\n}":
Expand Down Expand Up @@ -81,6 +83,12 @@ export function graphql(
export function graphql(
source: "query myEvents($input: PaginatedInputEventsSearchInput!, $userTicketSearchInput: EventsTicketsSearchInput) {\n searchEvents(input: $input) {\n data {\n id\n name\n description\n startDateTime\n address\n previewImage {\n url\n }\n community {\n id\n name\n }\n status\n usersTickets(input: $userTicketSearchInput) {\n id\n approvalStatus\n paymentStatus\n redemptionStatus\n ticketTemplate {\n description\n id\n }\n }\n }\n pagination {\n currentPage\n pageSize\n totalPages\n totalRecords\n }\n }\n}",
): (typeof documents)["query myEvents($input: PaginatedInputEventsSearchInput!, $userTicketSearchInput: EventsTicketsSearchInput) {\n searchEvents(input: $input) {\n data {\n id\n name\n description\n startDateTime\n address\n previewImage {\n url\n }\n community {\n id\n name\n }\n status\n usersTickets(input: $userTicketSearchInput) {\n id\n approvalStatus\n paymentStatus\n redemptionStatus\n ticketTemplate {\n description\n id\n }\n }\n }\n pagination {\n currentPage\n pageSize\n totalPages\n totalRecords\n }\n }\n}"];
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
export function graphql(
source: "query myReceivedTransfers {\n myTicketTransfers(type: RECEIVED) {\n createdAt\n expirationDate\n id\n sender {\n email\n name\n }\n status\n transferMessage\n userTicket {\n id\n ticketTemplate {\n name\n event {\n id\n name\n }\n }\n }\n }\n}",
): (typeof documents)["query myReceivedTransfers {\n myTicketTransfers(type: RECEIVED) {\n createdAt\n expirationDate\n id\n sender {\n email\n name\n }\n status\n transferMessage\n userTicket {\n id\n ticketTemplate {\n name\n event {\n id\n name\n }\n }\n }\n }\n}"];
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
Expand Down
119 changes: 119 additions & 0 deletions app/api/gql/graphql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,8 @@ export type Mutation = {
approvalUserTicket: UserTicket;
/** Cancel a ticket */
cancelUserTicket: UserTicket;
/** Cancel multiple user ticket addons */
cancelUserTicketAddons: Array<UserTicketAddon>;
/** Check the status of a purchase order */
checkPurchaseOrderStatus: PurchaseOrder;
/** Attempt to claim and/or transfer tickets */
Expand Down Expand Up @@ -490,6 +492,10 @@ export type MutationCancelUserTicketArgs = {
userTicketId: Scalars["String"]["input"];
};

export type MutationCancelUserTicketAddonsArgs = {
userTicketAddonIds: Array<Scalars["String"]["input"]>;
};

export type MutationCheckPurchaseOrderStatusArgs = {
input: CheckForPurchaseOrderInput;
};
Expand Down Expand Up @@ -1674,6 +1680,23 @@ export type MyEventsQuery = {
};
};

export type MyReceivedTransfersQueryVariables = Exact<{ [key: string]: never }>;

export type MyReceivedTransfersQuery = {
myTicketTransfers: Array<{
createdAt: string;
expirationDate: string;
id: string;
status: TicketTransferAttemptStatus;
transferMessage?: string | null;
sender: { email: string; name?: string | null };
userTicket: {
id: string;
ticketTemplate: { name: string; event: { id: string; name: string } };
};
}>;
};

export type MyPurchaseOrdersQueryVariables = Exact<{
input: PaginatedInputMyPurchaseOrdersInput;
}>;
Expand Down Expand Up @@ -2625,6 +2648,102 @@ export const MyEventsDocument = {
},
],
} as unknown as DocumentNode<MyEventsQuery, MyEventsQueryVariables>;
export const MyReceivedTransfersDocument = {
kind: "Document",
definitions: [
{
kind: "OperationDefinition",
operation: "query",
name: { kind: "Name", value: "myReceivedTransfers" },
selectionSet: {
kind: "SelectionSet",
selections: [
{
kind: "Field",
name: { kind: "Name", value: "myTicketTransfers" },
arguments: [
{
kind: "Argument",
name: { kind: "Name", value: "type" },
value: { kind: "EnumValue", value: "RECEIVED" },
},
],
selectionSet: {
kind: "SelectionSet",
selections: [
{ kind: "Field", name: { kind: "Name", value: "createdAt" } },
{
kind: "Field",
name: { kind: "Name", value: "expirationDate" },
},
{ kind: "Field", name: { kind: "Name", value: "id" } },
{
kind: "Field",
name: { kind: "Name", value: "sender" },
selectionSet: {
kind: "SelectionSet",
selections: [
{ kind: "Field", name: { kind: "Name", value: "email" } },
{ kind: "Field", name: { kind: "Name", value: "name" } },
],
},
},
{ kind: "Field", name: { kind: "Name", value: "status" } },
{
kind: "Field",
name: { kind: "Name", value: "transferMessage" },
},
{
kind: "Field",
name: { kind: "Name", value: "userTicket" },
selectionSet: {
kind: "SelectionSet",
selections: [
{ kind: "Field", name: { kind: "Name", value: "id" } },
{
kind: "Field",
name: { kind: "Name", value: "ticketTemplate" },
selectionSet: {
kind: "SelectionSet",
selections: [
{
kind: "Field",
name: { kind: "Name", value: "name" },
},
{
kind: "Field",
name: { kind: "Name", value: "event" },
selectionSet: {
kind: "SelectionSet",
selections: [
{
kind: "Field",
name: { kind: "Name", value: "id" },
},
{
kind: "Field",
name: { kind: "Name", value: "name" },
},
],
},
},
],
},
},
],
},
},
],
},
},
],
},
},
],
} as unknown as DocumentNode<
MyReceivedTransfersQuery,
MyReceivedTransfersQueryVariables
>;
export const MyPurchaseOrdersDocument = {
kind: "Document",
definitions: [
Expand Down
10 changes: 10 additions & 0 deletions app/api/gql/schema.gql
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,16 @@ type Mutation {
"""
cancelUserTicket(userTicketId: String!): UserTicket!

"""
Cancel multiple user ticket addons
"""
cancelUserTicketAddons(
"""
The IDs of the user ticket addons to cancel
"""
userTicketAddonIds: [String!]!
): [UserTicketAddon!]!

"""
Check the status of a purchase order
"""
Expand Down
101 changes: 91 additions & 10 deletions app/components/MyEvents/MyTicketsList.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
import { Link } from "@remix-run/react";
import { Calendar, MapPin } from "lucide-react";
import { useMemo } from "react";
import { Bell, Calendar, MapPin } from "lucide-react";
import { useMemo, useState } from "react";
import { toast } from "sonner";

import { TicketTransferAttemptStatus } from "~/api/gql/graphql";
import {
MyEventsQuery,
useMyEventsSuspenseQuery,
} from "~/components/MyEvents/graphql/myEvents.generated";
import { useAcceptTransferredTicketMutation } from "~/components/MyTransfers/graphql/acceptTransferedTicket.generated";
import { Alert, AlertDescription, AlertTitle } from "~/components/ui/alert";
import { Badge } from "~/components/ui/badge";
import { Button, buttonVariants } from "~/components/ui/button";
import { Card, CardDescription, CardTitle } from "~/components/ui/card";
import { formatDate, formatTime } from "~/utils/date";
import { pluralize } from "~/utils/string";
import { urls } from "~/utils/urls";
import { cn } from "~/utils/utils";

import { useMyReceivedTransfersSuspenseQuery } from "./graphql/myReceivedTransfers.generated";

const EventCard = ({
event,
Expand Down Expand Up @@ -78,7 +86,7 @@ export const MyTicketsList = ({
startDateTimeTo?: string | null;
order?: string;
}) => {
const { data } = useMyEventsSuspenseQuery({
const { data, refetch: refetchMyEvents } = useMyEventsSuspenseQuery({
variables: {
input: {
search: {
Expand All @@ -97,6 +105,10 @@ export const MyTicketsList = ({
},
},
});
const { data: receivedTransfersData, refetch: refetchReceivedTransfers } =
useMyReceivedTransfersSuspenseQuery();
const [acceptTicket] = useAcceptTransferredTicketMutation();
const [isDisabled, setIsDisabled] = useState(false);

const { groupedByDate, orderedDates } = useMemo(() => {
const groupedByDate = data.searchEvents.data.reduce(
Expand Down Expand Up @@ -140,13 +152,82 @@ export const MyTicketsList = ({
groupedByDate[date].map((event) => event),
);

const myTicketTransfers =
receivedTransfersData?.myTicketTransfers.filter(
(ticketTransfer) =>
ticketTransfer.status === TicketTransferAttemptStatus.Pending,
) ?? [];
const ticketTransfer = myTicketTransfers?.[0];

const handleAcceptTransfer = async () => {
setIsDisabled(true);

await acceptTicket({
variables: {
transferId: ticketTransfer.id,
},
onCompleted(data) {
if (data.acceptTransferredTicket.id) {
setIsDisabled(false);
toast.success(
`La transferenciaha se ha confirmado exitosamente. Hemos notificado al ${ticketTransfer.sender.email}.`,
);
void refetchReceivedTransfers();
void refetchMyEvents();
} else {
setIsDisabled(false);
toast.error(
"Ocurrió un error al intentar confirmar la transferencia. Por favor intenta de nuevo.",
);
}
},
onError() {
setIsDisabled(false);
toast.error(
"Ocurrió un error al intentar confirmar la transferencia. Por favor intenta de nuevo.",
);
},
});
};

return (
<div className="mx-auto grid w-full grid-cols-1 gap-4 md:grid-cols-3">
{sorted.map((event, index) => (
<div key={`${event.id}-${index}`} className="basis-full md:basis-1/3">
<EventCard event={event} />
</div>
))}
</div>
<>
{ticketTransfer ? (
<Alert key={ticketTransfer.id}>
<Bell className="size-4" />
<AlertTitle>Te han envíado un Ticket</AlertTitle>
<AlertDescription className="flex flex-col gap-2">
<div>
Te han envíado un ticket:{" "}
{ticketTransfer.userTicket.ticketTemplate.name} para el evento:{" "}
{ticketTransfer.userTicket.ticketTemplate.event.name}.
</div>
<div className="flex flex-col justify-end gap-2 md:flex-row">
<Link
className={cn(buttonVariants({ variant: "outline" }))}
to={urls.myTransfers}
>
Ver mis Transferencia
</Link>
<Button
onClick={() => {
void handleAcceptTransfer();
}}
disabled={isDisabled}
>
Aceptar Transferencia
</Button>
</div>
</AlertDescription>
</Alert>
) : null}
<div className="mx-auto grid w-full grid-cols-1 gap-4 md:grid-cols-3">
{sorted.map((event, index) => (
<div key={`${event.id}-${index}`} className="basis-full md:basis-1/3">
<EventCard event={event} />
</div>
))}
</div>
</>
);
};
Loading

0 comments on commit 773eb50

Please sign in to comment.