From 6b8ba9e55cfcf4ca61095018a56936865ab29b92 Mon Sep 17 00:00:00 2001 From: Jose Lezama Date: Tue, 24 Sep 2024 01:57:50 -0300 Subject: [PATCH] Lego/chore/running app (#50) # Summary Update the app with everything needed to run one more time. --- app/api/gql/graphql.ts | 249 ++++++++++++++++- app/api/gql/schema.gql | 258 +++++++++++++++++- app/components/MyEvent/MyEvent.tsx | 3 +- app/components/MyEvents/MyTicketsList.tsx | 5 +- .../MyPurchaseOrders/MyPurchaseOrders.tsx | 32 ++- 5 files changed, 514 insertions(+), 33 deletions(-) diff --git a/app/api/gql/graphql.ts b/app/api/gql/graphql.ts index 20fd474..cf698c8 100644 --- a/app/api/gql/graphql.ts +++ b/app/api/gql/graphql.ts @@ -124,6 +124,10 @@ export type CreateCompanyInput = { website?: InputMaybe; }; +export type CreatePlaceholderUsersInput = { + users: Array; +}; + export type CreateSalaryInput = { amount: Scalars["Int"]["input"]; companyId: Scalars["String"]["input"]; @@ -153,16 +157,22 @@ export type EnqueueGoogleAlbumImportInput = { /** Representation of an Event (Events and Users, is what tickets are linked to) */ export type Event = { address?: Maybe; + bannerImage?: Maybe; bannerImageSanityRef?: Maybe; community?: Maybe; description?: Maybe; endDateTime?: Maybe; + galleries: Array; id: Scalars["ID"]["output"]; images: Array; latitude?: Maybe; + logoImage?: Maybe; longitude?: Maybe; meetingURL?: Maybe; + mobileBannerImage?: Maybe; name: Scalars["String"]["output"]; + previewImage?: Maybe; + schedules: Array; speakers: Array; startDateTime: Scalars["DateTime"]["output"]; status: EventStatus; @@ -254,6 +264,25 @@ export type EventsTicketsSearchInput = { redemptionStatus?: InputMaybe; }; +export type FindUserTicketSearchInput = { + approvalStatus?: InputMaybe>; + eventIds?: InputMaybe>; + paymentStatus?: InputMaybe>; + redemptionStatus?: InputMaybe>; + ticketsIds?: InputMaybe>; + userIds?: InputMaybe>; + userTicketIds?: InputMaybe>; +}; + +/** Representation of a Gallery, usually associated to an event */ +export type Gallery = { + description?: Maybe; + event?: Maybe; + id: Scalars["ID"]["output"]; + images: Array; + name: Scalars["String"]["output"]; +}; + export enum Gender { Agender = "Agender", Female = "Female", @@ -273,12 +302,35 @@ export type GeneratePaymentLinkInput = { currencyId: Scalars["String"]["input"]; }; +export type GiftTicketsToUserInput = { + allowMultipleTicketsPerUsers: Scalars["Boolean"]["input"]; + autoApproveTickets: Scalars["Boolean"]["input"]; + notifyUsers: Scalars["Boolean"]["input"]; + ticketIds: Array; + userIds: Array; +}; + +/** An image, usually associated to a gallery */ +export type Image = { + gallery?: Maybe; + hosting: ImageHostingEnum; + id: Scalars["ID"]["output"]; + url: Scalars["String"]["output"]; +}; + +export enum ImageHostingEnum { + Cloudflare = "cloudflare", + Sanity = "sanity", +} + export type Mutation = { acceptGiftedTicket: UserTicket; /** Accept the user's invitation to a team */ acceptTeamInvitation: TeamRef; /** Try to add a person to a team */ addPersonToTeam: AddUserToTeamResponseRef; + /** Apply to a waitlist */ + applyToWaitlist: UserTicket; /** Approve a ticket */ approvalUserTicket: UserTicket; /** Cancel a ticket */ @@ -293,6 +345,8 @@ export type Mutation = { createCompany: Company; /** Create an event */ createEvent: Event; + /** Create placeholder users (used for things like invitations) */ + createPlaceholderdUsers: Array; /** Create a salary */ createSalary: Salary; /** Create a team, associated to a specific event */ @@ -309,6 +363,8 @@ export type Mutation = { editTicket: Ticket; /** Enqueue images to import */ enqueueGoogleAlbumImport: Scalars["Boolean"]["output"]; + /** Gift tickets to users, allowing multiple tickets per user, and conditionally notify them */ + giftTicketsToUsers: Array; /** Create a purchase order */ payForPurchaseOrder: PurchaseOrder; /** Redeem a ticket */ @@ -317,8 +373,10 @@ export type Mutation = { rejectTeamInvitation: TeamRef; /** Kickoff the email validation flow. This flow will links an email to a user, create a company if it does not exist, and allows filling data for that email's position */ startWorkEmailValidation: WorkEmail; + triggerUserTicketApprovalReview: Array; /** Update a company */ updateCompany: Company; + updateMyUserData: User; /** Create a salary */ updateSalary: Salary; /** Updates a team information */ @@ -343,6 +401,10 @@ export type MutationAddPersonToTeamArgs = { input: AddPersonToTeamInput; }; +export type MutationApplyToWaitlistArgs = { + ticketId: Scalars["String"]["input"]; +}; + export type MutationApprovalUserTicketArgs = { userTicketId: Scalars["String"]["input"]; }; @@ -371,6 +433,10 @@ export type MutationCreateEventArgs = { input: EventCreateInput; }; +export type MutationCreatePlaceholderdUsersArgs = { + input: CreatePlaceholderUsersInput; +}; + export type MutationCreateSalaryArgs = { input: CreateSalaryInput; }; @@ -403,6 +469,10 @@ export type MutationEnqueueGoogleAlbumImportArgs = { input: EnqueueGoogleAlbumImportInput; }; +export type MutationGiftTicketsToUsersArgs = { + input: GiftTicketsToUserInput; +}; + export type MutationPayForPurchaseOrderArgs = { input: PayForPurchaseOrderInput; }; @@ -419,10 +489,19 @@ export type MutationStartWorkEmailValidationArgs = { email: Scalars["String"]["input"]; }; +export type MutationTriggerUserTicketApprovalReviewArgs = { + eventId: Scalars["String"]["input"]; + userId: Scalars["String"]["input"]; +}; + export type MutationUpdateCompanyArgs = { input: UpdateCompanyInput; }; +export type MutationUpdateMyUserDataArgs = { + input: UpdateUserDataInput; +}; + export type MutationUpdateSalaryArgs = { input: UpdateSalaryInput; }; @@ -465,6 +544,11 @@ export type PaginatedInputEventsSearchInput = { search?: InputMaybe; }; +export type PaginatedInputFindUserTicketSearchInput = { + pagination?: PaginationSearchInputParams; + search?: InputMaybe; +}; + export type PaginatedInputMyPurchaseOrdersInput = { pagination?: PaginationSearchInputParams; search?: InputMaybe; @@ -555,6 +639,17 @@ export enum PronounsEnum { TheyThem = "theyThem", } +/** Representation of the public data for a user's event attendance, used usually for public profiles or 'shareable ticket' pages */ +export type PublicEventAttendance = { + event: Event; + id: Scalars["ID"]["output"]; + userInfo: PublicUserInfo; +}; + +export type PublicEventAttendanceInfo = { + id: Scalars["String"]["input"]; +}; + /** Representation of a payment log entry */ export type PublicFinanceEntryRef = { createdAt: Scalars["DateTime"]["output"]; @@ -565,6 +660,27 @@ export type PublicFinanceEntryRef = { transactionDate?: Maybe; }; +export type PublicTicketInput = { + publicTicketId: Scalars["String"]["input"]; +}; + +/** Representation of a user's publicly accessible data, to be used in public contexts like shareable ticket UIs */ +export type PublicUserInfo = { + firstName?: Maybe; + lastName?: Maybe; + profilePicture?: Maybe; + userName: Scalars["String"]["output"]; +}; + +/** Representation of the public information of a User ticket */ +export type PublicUserTicket = { + id: Scalars["ID"]["output"]; + ticket: Ticket; + userImage?: Maybe; + userName?: Maybe; + userUsername?: Maybe; +}; + /** Representation of a Purchase Order */ export type PurchaseOrder = { createdAt?: Maybe; @@ -608,14 +724,24 @@ export type Query = { event?: Maybe; /** Get a list of images, that are attached to an event */ eventImages: Array; + /** Get a list of user tickets */ + findUserTickets: PaginatedUserTicket; + /** Get a single waitlist */ + getWaitlist: Waitlist; /** Get the current user */ me: User; /** Get a list of purchase orders for the authenticated user */ myPurchaseOrders: PaginatedPurchaseOrder; /** Get a list of tickets for the current user */ myTickets: PaginatedUserTicket; + /** Get public event attendance info */ + publicEventAttendanceInfo?: Maybe; + /** Get a list of user tickets */ + publicTicketInfo: PublicUserTicket; /** Get a list of salaries associated to the user */ salaries: Array; + /** Get a schedule by its ID */ + schedule: Schedule; /** Search a consolidated payment logs, by date, aggregated by platform and currency_id */ searchConsolidatedPaymentLogs: Array; /** Get a list of events. Filter by name, id, status or date */ @@ -666,6 +792,14 @@ export type QueryEventImagesArgs = { input: EventImageSearch; }; +export type QueryFindUserTicketsArgs = { + input: PaginatedInputFindUserTicketSearchInput; +}; + +export type QueryGetWaitlistArgs = { + ticketId: Scalars["String"]["input"]; +}; + export type QueryMyPurchaseOrdersArgs = { input: PaginatedInputMyPurchaseOrdersInput; }; @@ -674,6 +808,18 @@ export type QueryMyTicketsArgs = { input: PaginatedInputMyTicketsSearchValues; }; +export type QueryPublicEventAttendanceInfoArgs = { + input: PublicEventAttendanceInfo; +}; + +export type QueryPublicTicketInfoArgs = { + input: PublicTicketInput; +}; + +export type QueryScheduleArgs = { + scheduleId: Scalars["String"]["input"]; +}; + export type QuerySearchConsolidatedPaymentLogsArgs = { input: SearchPaymentLogsInput; }; @@ -710,6 +856,10 @@ export type QueryWorkRoleSenioritiesArgs = { input: WorkRoleSenioritiesInput; }; +export type RsvpFilterInput = { + eventIds?: InputMaybe>; +}; + export type RedeemUserTicketError = { error: Scalars["Boolean"]["output"]; errorMessage: Scalars["String"]["output"]; @@ -752,6 +902,17 @@ export type SanityAssetRef = { url: Scalars["String"]["output"]; }; +/** Representation of a Schedule */ +export type Schedule = { + description?: Maybe; + endTimestamp: Scalars["DateTime"]["output"]; + event: Event; + id: Scalars["ID"]["output"]; + sessions: Array; + startTimestamp: Scalars["DateTime"]["output"]; + title: Scalars["String"]["output"]; +}; + export type SearchCompaniesInput = { companyName?: InputMaybe; description?: InputMaybe; @@ -771,16 +932,24 @@ export enum SearchableUserTags { } export enum ServiceErrors { + AlreadyExists = "ALREADY_EXISTS", + Conflict = "CONFLICT", + FailedPrecondition = "FAILED_PRECONDITION", + Forbidden = "FORBIDDEN", + InternalServerError = "INTERNAL_SERVER_ERROR", + InvalidArgument = "INVALID_ARGUMENT", + NotFound = "NOT_FOUND", Unauthenticated = "UNAUTHENTICATED", + Unauthorized = "UNAUTHORIZED", } /** Representation of a Session */ -export type SessionRef = { +export type Session = { description?: Maybe; - endTimestamp: Scalars["Date"]["output"]; + endTimestamp: Scalars["DateTime"]["output"]; id: Scalars["ID"]["output"]; speakers: Array; - startTimestamp: Scalars["Date"]["output"]; + startTimestamp: Scalars["DateTime"]["output"]; title: Scalars["String"]["output"]; }; @@ -798,9 +967,11 @@ export type SessionSearch = { export type Speaker = { avatar?: Maybe; bio?: Maybe; + company?: Maybe; id: Scalars["ID"]["output"]; name: Scalars["String"]["output"]; - sessions: Array; + rol?: Maybe; + sessions: Array; socials: Array; }; @@ -869,6 +1040,7 @@ export type Ticket = { requiresApproval: Scalars["Boolean"]["output"]; startDateTime: Scalars["DateTime"]["output"]; status: TicketTemplateStatus; + tags: Array; visibility: TicketTemplateVisibility; }; @@ -885,8 +1057,6 @@ export enum TicketApprovalStatus { export type TicketClaimInput = { /** If this field is passed, a purchase order payment link will be generated right away */ generatePaymentLink?: InputMaybe; - /** A unique key to prevent duplicate requests, it's optional to send, but it's recommended to send it to prevent duplicate requests. If not sent, it will be created by the server. */ - idempotencyUUIDKey?: InputMaybe; purchaseOrder: Array; }; @@ -894,14 +1064,18 @@ export type TicketCreateInput = { description?: InputMaybe; endDateTime?: InputMaybe; eventId: Scalars["String"]["input"]; + externalLink?: InputMaybe; + imageLink?: InputMaybe; /** If the ticket is free, the price submitted will be ignored. */ isFree: Scalars["Boolean"]["input"]; + maxTicketsPerUser?: InputMaybe; name: Scalars["String"]["input"]; prices?: InputMaybe>; quantity?: InputMaybe; requiresApproval?: InputMaybe; startDateTime: Scalars["DateTime"]["input"]; status?: InputMaybe; + tags?: InputMaybe>; /** If provided, quantity must not be passed. This is for things like online events where there is no limit to the amount of tickets that can be sold. */ unlimitedTickets: Scalars["Boolean"]["input"]; visibility?: InputMaybe; @@ -912,7 +1086,7 @@ export type TicketEditInput = { endDateTime?: InputMaybe; eventId?: InputMaybe; name?: InputMaybe; - prices?: InputMaybe; + prices?: InputMaybe>; quantity?: InputMaybe; requiresApproval?: InputMaybe; startDateTime?: InputMaybe; @@ -1000,13 +1174,34 @@ export type User = { lastName?: Maybe; name?: Maybe; pronouns?: Maybe; + /** Get a list of user's RSVPs */ + rsvps: Array; teams: Array; + userData?: Maybe; username: Scalars["String"]["output"]; }; +/** Representation of a user */ +export type UserRsvpsArgs = { + input?: InputMaybe; +}; + +/** Representation of a user's data */ +export type UserData = { + city: Scalars["String"]["output"]; + countryOfResidence: Scalars["String"]["output"]; + emergencyPhoneNumber?: Maybe; + foodAllergies?: Maybe; + organizationName?: Maybe; + roleInOrganization?: Maybe; + rut?: Maybe; + worksInOrganization: Scalars["Boolean"]["output"]; +}; + export type UserSearchValues = { name?: InputMaybe; tags?: InputMaybe>; + userIds?: InputMaybe>; userName?: InputMaybe; }; @@ -1021,9 +1216,11 @@ export type UserTicket = { createdAt: Scalars["DateTime"]["output"]; id: Scalars["ID"]["output"]; paymentStatus?: Maybe; + publicId: Scalars["String"]["output"]; purchaseOrder?: Maybe; redemptionStatus: TicketRedemptionStatus; ticketTemplate: Ticket; + user?: Maybe; }; /** Representation of a user in a team */ @@ -1049,6 +1246,20 @@ export type ValidatedWorkEmail = { workEmail: Scalars["String"]["output"]; }; +/** Representation of a waitlist */ +export type Waitlist = { + /** The ID of the waitlist. It matches the ID of the underlying ticket */ + id: Scalars["ID"]["output"]; + myRsvp?: Maybe; + ticket: Ticket; +}; + +export enum WaitlistApprovalStatus { + Approved = "approved", + Pending = "pending", + Rejected = "rejected", +} + /** Representation of a (yet to validate) work email */ export type WorkEmail = { id: Scalars["ID"]["output"]; @@ -1080,6 +1291,30 @@ export type WorkSeniority = { name: Scalars["String"]["output"]; }; +export type PlaceHolderUsersInput = { + ciudad?: InputMaybe; + email: Scalars["String"]["input"]; + emergencyPhoneNumber?: InputMaybe; + foodAllergies?: InputMaybe; + name: Scalars["String"]["input"]; + nombreOrganizacion?: InputMaybe; + pais?: InputMaybe; + rolEnOrganizacion?: InputMaybe; + trabajasEnOrganizacion?: InputMaybe; +}; + +export type UpdateUserDataInput = { + city: Scalars["String"]["input"]; + countryOfResidence: Scalars["String"]["input"]; + emergencyPhoneNumber?: InputMaybe; + eventId: Scalars["String"]["input"]; + foodAllergies?: InputMaybe; + organizationName?: InputMaybe; + roleInOrganization?: InputMaybe; + rut?: InputMaybe; + worksInOrganization: Scalars["Boolean"]["input"]; +}; + export type UpdateUserRoleInCommunityInput = { communityId: Scalars["String"]["input"]; role: Scalars["String"]["input"]; diff --git a/app/api/gql/schema.gql b/app/api/gql/schema.gql index fa75e19..102b5d8 100644 --- a/app/api/gql/schema.gql +++ b/app/api/gql/schema.gql @@ -101,6 +101,10 @@ input CreateCompanyInput { website: String } +input CreatePlaceholderUsersInput { + users: [placeHolderUsersInput!]! +} + input CreateSalaryInput { amount: Int! companyId: String! @@ -142,16 +146,22 @@ Representation of an Event (Events and Users, is what tickets are linked to) """ type Event { address: String + bannerImage: Image bannerImageSanityRef: String community: Community description: String endDateTime: DateTime + galleries: [Gallery!]! id: ID! images: [SanityAssetRef!]! latitude: String + logoImage: Image longitude: String meetingURL: String + mobileBannerImage: Image name: String! + previewImage: Image + schedules: [Schedule!]! speakers: [Speaker!]! startDateTime: DateTime! status: EventStatus! @@ -241,6 +251,27 @@ input EventsTicketsSearchInput { redemptionStatus: TicketRedemptionStatus } +input FindUserTicketSearchInput { + approvalStatus: [TicketApprovalStatus!] + eventIds: [String!] + paymentStatus: [TicketPaymentStatus!] + redemptionStatus: [TicketRedemptionStatus!] + ticketsIds: [String!] + userIds: [String!] + userTicketIds: [String!] +} + +""" +Representation of a Gallery, usually associated to an event +""" +type Gallery { + description: String + event: Event + id: ID! + images: [Image!]! + name: String! +} + enum Gender { Agender Female @@ -260,6 +291,29 @@ input GeneratePaymentLinkInput { currencyId: String! } +input GiftTicketsToUserInput { + allowMultipleTicketsPerUsers: Boolean! + autoApproveTickets: Boolean! + notifyUsers: Boolean! + ticketIds: [String!]! + userIds: [String!]! +} + +""" +An image, usually associated to a gallery +""" +type Image { + gallery: Gallery + hosting: ImageHostingEnum! + id: ID! + url: String! +} + +enum ImageHostingEnum { + cloudflare + sanity +} + type Mutation { acceptGiftedTicket(userTicketId: String!): UserTicket! @@ -273,6 +327,11 @@ type Mutation { """ addPersonToTeam(input: AddPersonToTeamInput!): AddUserToTeamResponseRef! + """ + Apply to a waitlist + """ + applyToWaitlist(ticketId: String!): UserTicket! + """ Approve a ticket """ @@ -308,6 +367,11 @@ type Mutation { """ createEvent(input: EventCreateInput!): Event! + """ + Create placeholder users (used for things like invitations) + """ + createPlaceholderdUsers(input: CreatePlaceholderUsersInput!): [User!]! + """ Create a salary """ @@ -348,6 +412,11 @@ type Mutation { """ enqueueGoogleAlbumImport(input: EnqueueGoogleAlbumImportInput!): Boolean! + """ + Gift tickets to users, allowing multiple tickets per user, and conditionally notify them + """ + giftTicketsToUsers(input: GiftTicketsToUserInput!): [UserTicket!]! + """ Create a purchase order """ @@ -367,11 +436,16 @@ type Mutation { Kickoff the email validation flow. This flow will links an email to a user, create a company if it does not exist, and allows filling data for that email's position """ startWorkEmailValidation(email: String!): WorkEmail! + triggerUserTicketApprovalReview( + eventId: String! + userId: String! + ): [UserTicket!]! """ Update a company """ updateCompany(input: UpdateCompanyInput!): Company! + updateMyUserData(input: updateUserDataInput!): User! """ Create a salary @@ -423,6 +497,11 @@ input PaginatedInputEventsSearchInput { search: EventsSearchInput } +input PaginatedInputFindUserTicketSearchInput { + pagination: PaginationSearchInputParams! = { page: 0, pageSize: 20 } + search: FindUserTicketSearchInput +} + input PaginatedInputMyPurchaseOrdersInput { pagination: PaginationSearchInputParams! = { page: 0, pageSize: 20 } search: MyPurchaseOrdersInput @@ -530,6 +609,19 @@ enum PronounsEnum { theyThem } +""" +Representation of the public data for a user's event attendance, used usually for public profiles or 'shareable ticket' pages +""" +type PublicEventAttendance { + event: Event! + id: ID! + userInfo: PublicUserInfo! +} + +input PublicEventAttendanceInfo { + id: String! +} + """ Representation of a payment log entry """ @@ -542,6 +634,31 @@ type PublicFinanceEntryRef { transactionDate: DateTime } +input PublicTicketInput { + publicTicketId: String! +} + +""" +Representation of a user's publicly accessible data, to be used in public contexts like shareable ticket UIs +""" +type PublicUserInfo { + firstName: String + lastName: String + profilePicture: String + userName: String! +} + +""" +Representation of the public information of a User ticket +""" +type PublicUserTicket { + id: ID! + ticket: Ticket! + userImage: String + userName: String + userUsername: String +} + """ Representation of a Purchase Order """ @@ -605,6 +722,18 @@ type Query { """ eventImages(input: EventImageSearch!): [SanityAssetRef!]! + """ + Get a list of user tickets + """ + findUserTickets( + input: PaginatedInputFindUserTicketSearchInput! + ): PaginatedUserTicket! + + """ + Get a single waitlist + """ + getWaitlist(ticketId: String!): Waitlist! + """ Get the current user """ @@ -622,11 +751,28 @@ type Query { """ myTickets(input: PaginatedInputMyTicketsSearchValues!): PaginatedUserTicket! + """ + Get public event attendance info + """ + publicEventAttendanceInfo( + input: PublicEventAttendanceInfo! + ): PublicEventAttendance + + """ + Get a list of user tickets + """ + publicTicketInfo(input: PublicTicketInput!): PublicUserTicket! + """ Get a list of salaries associated to the user """ salaries: [Salary!]! + """ + Get a schedule by its ID + """ + schedule(scheduleId: String!): Schedule! + """ Search a consolidated payment logs, by date, aggregated by platform and currency_id """ @@ -682,6 +828,10 @@ type Query { workRoles: [WorkRole!]! } +input RSVPFilterInput { + eventIds: [String!] +} + type RedeemUserTicketError { error: Boolean! errorMessage: String! @@ -728,6 +878,19 @@ type SanityAssetRef { url: String! } +""" +Representation of a Schedule +""" +type Schedule { + description: String + endTimestamp: DateTime! + event: Event! + id: ID! + sessions: [Session!]! + startTimestamp: DateTime! + title: String! +} + input SearchCompaniesInput { companyName: String description: String @@ -747,18 +910,26 @@ enum SearchableUserTags { } enum ServiceErrors { + ALREADY_EXISTS + CONFLICT + FAILED_PRECONDITION + FORBIDDEN + INTERNAL_SERVER_ERROR + INVALID_ARGUMENT + NOT_FOUND UNAUTHENTICATED + UNAUTHORIZED } """ Representation of a Session """ -type SessionRef { +type Session { description: String - endTimestamp: Date! + endTimestamp: DateTime! id: ID! speakers: [Speaker!]! - startTimestamp: Date! + startTimestamp: DateTime! title: String! } @@ -778,9 +949,11 @@ Representation of a Speaker type Speaker { avatar: String bio: String + company: String id: ID! name: String! - sessions: [SessionRef!]! + rol: String + sessions: [Session!]! socials: [String!]! } @@ -864,6 +1037,7 @@ type Ticket { requiresApproval: Boolean! startDateTime: DateTime! status: TicketTemplateStatus! + tags: [String!]! visibility: TicketTemplateVisibility! } @@ -882,11 +1056,6 @@ input TicketClaimInput { If this field is passed, a purchase order payment link will be generated right away """ generatePaymentLink: GeneratePaymentLinkInput - - """ - A unique key to prevent duplicate requests, it's optional to send, but it's recommended to send it to prevent duplicate requests. If not sent, it will be created by the server. - """ - idempotencyUUIDKey: String purchaseOrder: [PurchaseOrderInput!]! } @@ -894,17 +1063,21 @@ input TicketCreateInput { description: String endDateTime: DateTime eventId: String! + externalLink: String + imageLink: String """ If the ticket is free, the price submitted will be ignored. """ isFree: Boolean! + maxTicketsPerUser: Int name: String! prices: [PricingInputField!] quantity: Int requiresApproval: Boolean startDateTime: DateTime! status: TicketTemplateStatus + tags: [String!] """ If provided, quantity must not be passed. This is for things like online events where there is no limit to the amount of tickets that can be sold. @@ -918,7 +1091,7 @@ input TicketEditInput { endDateTime: DateTime eventId: String name: String - prices: PricingInputField + prices: [PricingInputField!] quantity: Int requiresApproval: Boolean startDateTime: DateTime @@ -1011,13 +1184,34 @@ type User { lastName: String name: String pronouns: PronounsEnum + + """ + Get a list of user's RSVPs + """ + rsvps(input: RSVPFilterInput): [UserTicket!]! teams: [TeamRef!]! + userData: UserData username: String! } +""" +Representation of a user's data +""" +type UserData { + city: String! + countryOfResidence: String! + emergencyPhoneNumber: String + foodAllergies: String + organizationName: String + roleInOrganization: String + rut: String + worksInOrganization: Boolean! +} + input UserSearchValues { name: String tags: [SearchableUserTags!] + userIds: [String!] userName: String } @@ -1034,9 +1228,11 @@ type UserTicket { createdAt: DateTime! id: ID! paymentStatus: PurchaseOrderPaymentStatusEnum + publicId: String! purchaseOrder: PurchaseOrder redemptionStatus: TicketRedemptionStatus! ticketTemplate: Ticket! + user: User } """ @@ -1066,6 +1262,24 @@ type ValidatedWorkEmail { workEmail: String! } +""" +Representation of a waitlist +""" +type Waitlist { + """ + The ID of the waitlist. It matches the ID of the underlying ticket + """ + id: ID! + myRsvp: UserTicket + ticket: Ticket! +} + +enum WaitlistApprovalStatus { + approved + pending + rejected +} + """ Representation of a (yet to validate) work email """ @@ -1103,6 +1317,30 @@ type WorkSeniority { name: String! } +input placeHolderUsersInput { + ciudad: String + email: String! + emergencyPhoneNumber: String + foodAllergies: String + name: String! + nombreOrganizacion: String + pais: String + rolEnOrganizacion: String + trabajasEnOrganizacion: String +} + +input updateUserDataInput { + city: String! + countryOfResidence: String! + emergencyPhoneNumber: String + eventId: String! + foodAllergies: String + organizationName: String + roleInOrganization: String + rut: String + worksInOrganization: Boolean! +} + input updateUserRoleInCommunityInput { communityId: String! role: String! diff --git a/app/components/MyEvent/MyEvent.tsx b/app/components/MyEvent/MyEvent.tsx index 3d01045..9546fe5 100644 --- a/app/components/MyEvent/MyEvent.tsx +++ b/app/components/MyEvent/MyEvent.tsx @@ -27,7 +27,6 @@ import { TableRow, } from "~/components/ui/table"; import { formatDate, formatTime } from "~/utils/date"; -import { parseAddress, formatAddress } from "~/utils/event"; import { approvalStatusColor, approvalStatusLabel, @@ -196,7 +195,7 @@ export const MyEvent = ({ id }: { id: string }) => { const parsedDate = new Date(event.startDateTime as string); const formattedDate = formatDate(parsedDate); const formattedTime = formatTime(parsedDate); - const formatedAddress = formatAddress(parseAddress(event.address)); + const formatedAddress = event.address; // onOpenChange signature is: (open: boolean) => void // so, we can't use the setShowTicket directly cuz types inconsitency diff --git a/app/components/MyEvents/MyTicketsList.tsx b/app/components/MyEvents/MyTicketsList.tsx index 0d90e68..bd1bff3 100644 --- a/app/components/MyEvents/MyTicketsList.tsx +++ b/app/components/MyEvents/MyTicketsList.tsx @@ -10,7 +10,6 @@ import { Button } from "~/components/ui/button"; import { Card, CardDescription, CardTitle } from "~/components/ui/card"; import { Skeleton } from "~/components/ui/skeleton"; import { formatDate, formatTime } from "~/utils/date"; -import { parseAddress, formatAddress } from "~/utils/event"; import { pluralize } from "~/utils/string"; import { urls } from "~/utils/urls"; @@ -103,9 +102,7 @@ export const MyTicketsList = ({ const parsedDate = new Date(event.startDateTime as string); const formattedTime = formatTime(parsedDate); const formattedDate = formatDate(parsedDate); - const formatedAddress = formatAddress( - parseAddress(event.address), - ); + const formatedAddress = event.address; return (
diff --git a/app/components/MyPurchaseOrders/MyPurchaseOrders.tsx b/app/components/MyPurchaseOrders/MyPurchaseOrders.tsx index 6e941ec..a888d7b 100644 --- a/app/components/MyPurchaseOrders/MyPurchaseOrders.tsx +++ b/app/components/MyPurchaseOrders/MyPurchaseOrders.tsx @@ -40,13 +40,18 @@ export const MyPurchaseOrders = () => { }); const purchaseOrders = data?.myPurchaseOrders?.data ?? []; + const showedPurchasedOrders = purchaseOrders.filter( + (purchaseOrder) => purchaseOrder.tickets.length, + ); return (
- {!purchaseOrders?.length && ( -
No hay eventos
+ {!showedPurchasedOrders?.length && ( +
+ No hay Ordenes de Compra +
)} - {purchaseOrders.length ? ( + {showedPurchasedOrders.length ? ( Ordenes de Compra @@ -69,8 +74,13 @@ export const MyPurchaseOrders = () => { - {purchaseOrders.map((purchaseOrder) => { - const event = purchaseOrder.tickets[0].ticketTemplate.event; + {showedPurchasedOrders.map((purchaseOrder) => { + const event = + purchaseOrder?.tickets[0]?.ticketTemplate?.event; + + if (!event) { + return; + } return ( @@ -99,7 +109,7 @@ export const MyPurchaseOrders = () => { to={urls.myEvents.details(event.id)} className={cn( buttonVariants({ variant: "link" }), - "m-0 flex flex-row justify-start gap-1 p-0", + "m-0 flex h-full flex-row justify-start gap-1 p-0", )} >
@@ -124,10 +134,12 @@ export const MyPurchaseOrders = () => { {formatDate(purchaseOrder.createdAt as string)} - {formatCurrency( - purchaseOrder.finalPrice as number, - purchaseOrder.currency?.currency, - )} + {purchaseOrder.finalPrice + ? formatCurrency( + purchaseOrder.finalPrice, + purchaseOrder.currency?.currency, + ) + : "Gratis"} );