From c51150ce3d97aa85d5640a48c0b03ec1e2ade212 Mon Sep 17 00:00:00 2001 From: "Felipe Torres (fforres)" Date: Tue, 9 Jul 2024 20:45:07 -0700 Subject: [PATCH] v0 for mytickets (#41) image --- app/api/gql/gql.ts | 16 +- app/api/gql/graphql.ts | 574 ++++++++++++------ .../graphql/FetchExampleEvents.generated.tsx | 126 ++++ .../graphql/FetchExampleEvents.gql | 17 + app/components/MyEvents/MyTicketsList.tsx | 147 +++++ .../MyEvents/MyTicketsLoadingSkeleton.tsx | 43 ++ .../MyEvents/graphql/myEvents.generated.tsx | 153 +++++ app/components/MyEvents/graphql/myEvents.gql | 34 ++ .../MyTickets/graphql/myTickets.generated.tsx | 121 ---- .../MyTickets/graphql/myTickets.gql | 16 - app/components/Navbar/index.tsx | 8 +- app/components/Register/Register.tsx | 2 +- app/components/ui/badge.tsx | 2 +- app/root.tsx | 27 +- app/routes/_authenticated/my-events/index.tsx | 36 ++ app/routes/_authenticated/tickets/index.tsx | 9 - app/utils/urls.ts | 7 +- codegen.ts | 5 +- components.json | 2 +- package-lock.json | 10 + package.json | 1 + 21 files changed, 1016 insertions(+), 340 deletions(-) create mode 100644 app/components/LandingPageEvents/graphql/FetchExampleEvents.generated.tsx create mode 100644 app/components/LandingPageEvents/graphql/FetchExampleEvents.gql create mode 100644 app/components/MyEvents/MyTicketsList.tsx create mode 100644 app/components/MyEvents/MyTicketsLoadingSkeleton.tsx create mode 100644 app/components/MyEvents/graphql/myEvents.generated.tsx create mode 100644 app/components/MyEvents/graphql/myEvents.gql delete mode 100644 app/components/MyTickets/graphql/myTickets.generated.tsx delete mode 100644 app/components/MyTickets/graphql/myTickets.gql create mode 100644 app/routes/_authenticated/my-events/index.tsx delete mode 100644 app/routes/_authenticated/tickets/index.tsx diff --git a/app/api/gql/gql.ts b/app/api/gql/gql.ts index 243aea0..8e5819d 100644 --- a/app/api/gql/gql.ts +++ b/app/api/gql/gql.ts @@ -13,8 +13,10 @@ import type { TypedDocumentNode as DocumentNode } from "@graphql-typed-document- * Therefore it is highly recommended to use the babel or swc plugin for production. */ const documents = { - "query myTickets($input: PaginatedInputMyTicketsSearchValues!) {\n myTickets(input: $input) {\n data {\n approvalStatus\n id\n paymentStatus\n redemptionStatus\n }\n pagination {\n currentPage\n pageSize\n totalPages\n totalRecords\n }\n }\n}": - types.MyTicketsDocument, + "query FetchExampleEvents($input: PaginatedInputEventsSearchInput!) {\n searchEvents(input: $input) {\n data {\n id\n description\n community {\n id\n name\n }\n tags {\n id\n name\n description\n }\n }\n }\n}": + types.FetchExampleEventsDocument, + "query myEvents($input: PaginatedInputEventsSearchInput!, $userTicketSearchInput: EventsTicketsSearchInput) {\n searchEvents(input: $input) {\n data {\n id\n name\n description\n startDateTime\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, "mutation CheckPurchaseOrderStatus($input: CheckForPurchaseOrderInput!) {\n checkPurchaseOrderStatus(input: $input) {\n status\n tickets {\n approvalStatus\n paymentStatus\n redemptionStatus\n }\n }\n}": types.CheckPurchaseOrderStatusDocument, "mutation createPurchaseOrder($input: TicketClaimInput!) {\n claimUserTicket(input: $input) {\n __typename\n ... on PurchaseOrder {\n __typename\n id\n currency {\n id\n }\n finalPrice\n paymentLink\n status\n tickets {\n id\n approvalStatus\n redemptionStatus\n paymentStatus\n }\n }\n ... on RedeemUserTicketError {\n __typename\n error\n errorMessage\n }\n }\n}": @@ -43,8 +45,14 @@ export function graphql(source: string): unknown; * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ export function graphql( - source: "query myTickets($input: PaginatedInputMyTicketsSearchValues!) {\n myTickets(input: $input) {\n data {\n approvalStatus\n id\n paymentStatus\n redemptionStatus\n }\n pagination {\n currentPage\n pageSize\n totalPages\n totalRecords\n }\n }\n}", -): (typeof documents)["query myTickets($input: PaginatedInputMyTicketsSearchValues!) {\n myTickets(input: $input) {\n data {\n approvalStatus\n id\n paymentStatus\n redemptionStatus\n }\n pagination {\n currentPage\n pageSize\n totalPages\n totalRecords\n }\n }\n}"]; + source: "query FetchExampleEvents($input: PaginatedInputEventsSearchInput!) {\n searchEvents(input: $input) {\n data {\n id\n description\n community {\n id\n name\n }\n tags {\n id\n name\n description\n }\n }\n }\n}", +): (typeof documents)["query FetchExampleEvents($input: PaginatedInputEventsSearchInput!) {\n searchEvents(input: $input) {\n data {\n id\n description\n community {\n id\n name\n }\n tags {\n id\n name\n description\n }\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 myEvents($input: PaginatedInputEventsSearchInput!, $userTicketSearchInput: EventsTicketsSearchInput) {\n searchEvents(input: $input) {\n data {\n id\n name\n description\n startDateTime\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 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. */ diff --git a/app/api/gql/graphql.ts b/app/api/gql/graphql.ts index 7471031..7afa503 100644 --- a/app/api/gql/graphql.ts +++ b/app/api/gql/graphql.ts @@ -55,28 +55,28 @@ export enum CommnunityStatus { /** Representation of a Community */ export type Community = { - banner: Maybe; - description: Maybe; + banner?: Maybe; + description?: Maybe; events: Array; id: Scalars["String"]["output"]; - logo: Maybe; - name: Maybe; + logo?: Maybe; + name?: Maybe; status: CommnunityStatus; users: Array; }; /** Representation of a workEmail */ export type Company = { - description: Maybe; + description?: Maybe; domain: Scalars["String"]["output"]; hasBeenUpdated: Scalars["Boolean"]["output"]; id: Scalars["String"]["output"]; - logo: Maybe; - name: Maybe; + logo?: Maybe; + name?: Maybe; salarySubmissions: Scalars["Int"]["output"]; /** Not available to users */ - status: Maybe; - website: Maybe; + status?: Maybe; + website?: Maybe; }; export enum CompanyStatus { @@ -100,13 +100,13 @@ export type CreateCommunityInput = { }; export type CreateCompanyInput = { - description: InputMaybe; + description?: InputMaybe; /** The email domain of the company (What we'll use to match the company to the user on account-creation) */ domain: Scalars["String"]["input"]; - logo: InputMaybe; - name: InputMaybe; - status: InputMaybe; - website: InputMaybe; + logo?: InputMaybe; + name?: InputMaybe; + status?: InputMaybe; + website?: InputMaybe; }; export type CreateSalaryInput = { @@ -137,16 +137,16 @@ export type EnqueueGoogleAlbumImportInput = { /** Representation of an Event (Events and Users, is what tickets are linked to) */ export type Event = { - address: Maybe; - community: Maybe; - description: Maybe; - endDateTime: Maybe; + address?: Maybe; + community?: Maybe; + description?: Maybe; + endDateTime?: Maybe; id: Scalars["String"]["output"]; images: Array; - latitude: Maybe; - longitude: Maybe; - maxAttendees: Maybe; - meetingURL: Maybe; + latitude?: Maybe; + longitude?: Maybe; + maxAttendees?: Maybe; + meetingURL?: Maybe; name: Scalars["String"]["output"]; startDateTime: Scalars["DateTime"]["output"]; status: EventStatus; @@ -161,39 +161,39 @@ export type Event = { /** Representation of an Event (Events and Users, is what tickets are linked to) */ export type EventUsersTicketsArgs = { - input: InputMaybe; + input?: InputMaybe; }; export type EventCreateInput = { - address: InputMaybe; + address?: InputMaybe; communityId: Scalars["String"]["input"]; description: Scalars["String"]["input"]; - endDateTime: InputMaybe; - latitude: InputMaybe; - longitude: InputMaybe; + endDateTime?: InputMaybe; + latitude?: InputMaybe; + longitude?: InputMaybe; maxAttendees: Scalars["Int"]["input"]; - meetingURL: InputMaybe; + meetingURL?: InputMaybe; name: Scalars["String"]["input"]; startDateTime: Scalars["DateTime"]["input"]; - status: InputMaybe; - timeZone: InputMaybe; - visibility: InputMaybe; + status?: InputMaybe; + timeZone?: InputMaybe; + visibility?: InputMaybe; }; export type EventEditInput = { - address: InputMaybe; - description: InputMaybe; - endDateTime: InputMaybe; + address?: InputMaybe; + description?: InputMaybe; + endDateTime?: InputMaybe; eventId: Scalars["String"]["input"]; - latitude: InputMaybe; - longitude: InputMaybe; - maxAttendees: InputMaybe; - meetingURL: InputMaybe; - name: InputMaybe; - startDateTime: InputMaybe; - status: InputMaybe; - timeZone: InputMaybe; - visibility: InputMaybe; + latitude?: InputMaybe; + longitude?: InputMaybe; + maxAttendees?: InputMaybe; + meetingURL?: InputMaybe; + name?: InputMaybe; + startDateTime?: InputMaybe; + status?: InputMaybe; + timeZone?: InputMaybe; + visibility?: InputMaybe; }; /** Search for tags */ @@ -213,20 +213,20 @@ export enum EventVisibility { } export type EventsSearchInput = { - id: InputMaybe; - name: InputMaybe; - startDateTimeFrom: InputMaybe; - startDateTimeTo: InputMaybe; - status: InputMaybe; - userHasTickets: InputMaybe; - visibility: InputMaybe; + id?: InputMaybe; + name?: InputMaybe; + startDateTimeFrom?: InputMaybe; + startDateTimeTo?: InputMaybe; + status?: InputMaybe; + userHasTickets?: InputMaybe; + visibility?: InputMaybe; }; export type EventsTicketsSearchInput = { - approvalStatus: InputMaybe; - id: InputMaybe; - paymentStatus: InputMaybe; - redemptionStatus: InputMaybe; + approvalStatus?: InputMaybe; + id?: InputMaybe; + paymentStatus?: InputMaybe; + redemptionStatus?: InputMaybe; }; export enum Gender { @@ -377,10 +377,10 @@ export type MutationValidateWorkEmailArgs = { }; export type MyTicketsSearchValues = { - approvalStatus: InputMaybe; - eventId: InputMaybe; - paymentStatus: InputMaybe; - redemptionStatus: InputMaybe; + approvalStatus?: InputMaybe; + eventId?: InputMaybe; + paymentStatus?: InputMaybe; + redemptionStatus?: InputMaybe; }; /** Type used for querying the paginated leaves and it's paginated meta data */ @@ -390,13 +390,13 @@ export type PaginatedEvent = { }; export type PaginatedInputEventsSearchInput = { - pagination: PaginationSearchInputParams; - search: InputMaybe; + pagination?: PaginationSearchInputParams; + search?: InputMaybe; }; export type PaginatedInputMyTicketsSearchValues = { - pagination: PaginationSearchInputParams; - search: InputMaybe; + pagination?: PaginationSearchInputParams; + search?: InputMaybe; }; /** Type used for querying the paginated leaves and it's paginated meta data */ @@ -444,16 +444,16 @@ export type PublicFinanceEntryRef = { id: Scalars["String"]["output"]; platform: Scalars["String"]["output"]; transactionAmount: Scalars["Float"]["output"]; - transactionDate: Maybe; + transactionDate?: Maybe; }; /** Representation of a Purchase Order */ export type PurchaseOrder = { - currency: Maybe; - finalPrice: Maybe; + currency?: Maybe; + finalPrice?: Maybe; id: Scalars["ID"]["output"]; - paymentLink: Maybe; - status: Maybe; + paymentLink?: Maybe; + status?: Maybe; tickets: Array; }; @@ -472,13 +472,13 @@ export type Query = { /** Get a list of communities. Filter by name, id, or status */ communities: Array; /** Get a community by id */ - community: Maybe; + community?: Maybe; /** Get all available companies */ companies: Array; /** Get all available companies */ company: Company; /** Get an event by id */ - event: Maybe; + event?: Maybe; /** Get a list of images, that are attached to an event */ eventImages: Array; /** Get the current user */ @@ -511,9 +511,9 @@ export type Query = { }; export type QueryCommunitiesArgs = { - id: InputMaybe; - name: InputMaybe; - status: InputMaybe; + id?: InputMaybe; + name?: InputMaybe; + status?: InputMaybe; }; export type QueryCommunityArgs = { @@ -521,7 +521,7 @@ export type QueryCommunityArgs = { }; export type QueryCompaniesArgs = { - input: InputMaybe; + input?: InputMaybe; }; export type QueryCompanyArgs = { @@ -553,11 +553,11 @@ export type QuerySearchPaymentLogsArgs = { }; export type QueryStatusArgs = { - name: InputMaybe; + name?: InputMaybe; }; export type QueryTagsArgs = { - input: InputMaybe; + input?: InputMaybe; }; export type QueryUserSearchArgs = { @@ -585,8 +585,8 @@ export type Salary = { company: Company; countryCode: Scalars["String"]["output"]; currencyCode: Scalars["String"]["output"]; - gender: Maybe; - genderOtherText: Maybe; + gender?: Maybe; + genderOtherText?: Maybe; id: Scalars["String"]["output"]; typeOfEmployment: TypeOfEmployment; workMetodology: WorkMetodology; @@ -606,14 +606,14 @@ export type SanityAssetRef = { }; export type SearchCompaniesInput = { - companyName: InputMaybe; - description: InputMaybe; - domain: InputMaybe; - website: InputMaybe; + companyName?: InputMaybe; + description?: InputMaybe; + domain?: InputMaybe; + website?: InputMaybe; }; export type SearchPaymentLogsInput = { - endDate: InputMaybe; + endDate?: InputMaybe; startDate: Scalars["DateTime"]["input"]; }; @@ -629,22 +629,22 @@ export enum ServiceErrors { /** Representation of a tag. Tags can be associated to many things. An event, a community, etc. */ export type Tag = { - description: Maybe; + description?: Maybe; id: Scalars["String"]["output"]; - name: Maybe; + name?: Maybe; slug: Scalars["String"]["output"]; }; export type TagSearchInput = { - description: InputMaybe; - id: InputMaybe; - name: InputMaybe; + description?: InputMaybe; + id?: InputMaybe; + name?: InputMaybe; }; /** Representation of a ticket */ export type Ticket = { - description: Maybe; - endDateTime: Maybe; + description?: Maybe; + endDateTime?: Maybe; event: Event; id: Scalars["ID"]["output"]; /** Whether or not the ticket is free */ @@ -652,9 +652,9 @@ export type Ticket = { /** Whether or not the ticket has an unlimited quantity. This is reserved for things loike online events. */ isUnlimited: Scalars["Boolean"]["output"]; name: Scalars["String"]["output"]; - prices: Maybe>; + prices?: Maybe>; /** The number of tickets available for this ticket type */ - quantity: Maybe; + quantity?: Maybe; requiresApproval: Scalars["Boolean"]["output"]; startDateTime: Scalars["DateTime"]["output"]; status: TicketTemplateStatus; @@ -671,43 +671,43 @@ export enum TicketApprovalStatus { export type TicketClaimInput = { /** If this field is passed, a purchase order payment link will be generated right away */ - generatePaymentLink: InputMaybe; + 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; + idempotencyUUIDKey?: InputMaybe; purchaseOrder: Array; }; export type TicketCreateInput = { - description: InputMaybe; - endDateTime: InputMaybe; + description?: InputMaybe; + endDateTime?: InputMaybe; eventId: Scalars["String"]["input"]; /** If the ticket is free, the price submitted will be ignored. */ isFree: Scalars["Boolean"]["input"]; name: Scalars["String"]["input"]; - prices: InputMaybe>; - quantity: InputMaybe; - requiresApproval: InputMaybe; + prices?: InputMaybe>; + quantity?: InputMaybe; + requiresApproval?: InputMaybe; startDateTime: Scalars["DateTime"]["input"]; - status: InputMaybe; + status?: 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; + visibility?: InputMaybe; }; export type TicketEditInput = { - description: InputMaybe; - endDateTime: InputMaybe; - eventId: InputMaybe; - name: InputMaybe; - prices: InputMaybe; - quantity: InputMaybe; - requiresApproval: InputMaybe; - startDateTime: InputMaybe; - status: InputMaybe; + description?: InputMaybe; + endDateTime?: InputMaybe; + eventId?: InputMaybe; + name?: InputMaybe; + prices?: InputMaybe; + quantity?: InputMaybe; + requiresApproval?: InputMaybe; + startDateTime?: InputMaybe; + status?: InputMaybe; ticketId: Scalars["String"]["input"]; /** 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: InputMaybe; - visibility: InputMaybe; + unlimitedTickets?: InputMaybe; + visibility?: InputMaybe; }; export enum TicketPaymentStatus { @@ -740,45 +740,45 @@ export enum TypeOfEmployment { export type UpdateCommunityInput = { communityId: Scalars["String"]["input"]; - description: InputMaybe; - name: InputMaybe; - slug: InputMaybe; - status: InputMaybe; + description?: InputMaybe; + name?: InputMaybe; + slug?: InputMaybe; + status?: InputMaybe; }; export type UpdateCompanyInput = { companyId: Scalars["String"]["input"]; - description: InputMaybe; - domain: InputMaybe; - logo: InputMaybe; - name: InputMaybe; - website: InputMaybe; + description?: InputMaybe; + domain?: InputMaybe; + logo?: InputMaybe; + name?: InputMaybe; + website?: InputMaybe; }; export type UpdateSalaryInput = { - amount: InputMaybe; + amount?: InputMaybe; confirmationToken: Scalars["String"]["input"]; - countryCode: InputMaybe; - currencyCode: InputMaybe; - gender: InputMaybe; - genderOtherText: InputMaybe; + countryCode?: InputMaybe; + currencyCode?: InputMaybe; + gender?: InputMaybe; + genderOtherText?: InputMaybe; salaryId: Scalars["String"]["input"]; - typeOfEmployment: InputMaybe; - workMetodology: InputMaybe; - workSeniorityAndRoleId: InputMaybe; - yearsOfExperience: InputMaybe; + typeOfEmployment?: InputMaybe; + workMetodology?: InputMaybe; + workSeniorityAndRoleId?: InputMaybe; + yearsOfExperience?: InputMaybe; }; /** Representation of a user */ export type User = { - bio: Maybe; + bio?: Maybe; communities: Array; - email: Maybe; + email?: Maybe; id: Scalars["String"]["output"]; - imageUrl: Maybe; - isSuperAdmin: Maybe; - lastName: Maybe; - name: Maybe; + imageUrl?: Maybe; + isSuperAdmin?: Maybe; + lastName?: Maybe; + name?: Maybe; username: Scalars["String"]["output"]; }; @@ -787,7 +787,7 @@ export type UserTicket = { approvalStatus: TicketApprovalStatus; id: Scalars["ID"]["output"]; paymentStatus: TicketPaymentStatus; - purchaseOrder: Maybe; + purchaseOrder?: Maybe; redemptionStatus: TicketRedemptionStatus; ticketTemplate: Ticket; }; @@ -799,8 +799,8 @@ export enum ValidPaymentMethods { /** Representation of a work email associated to the current user */ export type ValidatedWorkEmail = { - company: Maybe; - confirmationDate: Maybe; + company?: Maybe; + confirmationDate?: Maybe; id: Scalars["String"]["output"]; isValidated: Scalars["Boolean"]["output"]; status: EmailStatus; @@ -821,7 +821,7 @@ export enum WorkMetodology { /** Representation of a work role */ export type WorkRole = { - description: Maybe; + description?: Maybe; id: Scalars["String"]["output"]; name: Scalars["String"]["output"]; seniorities: Array; @@ -833,7 +833,7 @@ export type WorkRoleSenioritiesInput = { /** Representation of a work seniority */ export type WorkSeniority = { - description: Maybe; + description?: Maybe; id: Scalars["String"]["output"]; name: Scalars["String"]["output"]; }; @@ -845,28 +845,57 @@ export type UpdateUserRoleInCommunityInput = { }; export type UserEditInput = { - bio: InputMaybe; + bio?: InputMaybe; id: Scalars["String"]["input"]; - lastName: InputMaybe; - name: InputMaybe; - username: InputMaybe; + lastName?: InputMaybe; + name?: InputMaybe; + username?: InputMaybe; }; export type UserSearchInput = { - tags: InputMaybe>; + tags?: InputMaybe>; }; -export type MyTicketsQueryVariables = Exact<{ - input: PaginatedInputMyTicketsSearchValues; +export type FetchExampleEventsQueryVariables = Exact<{ + input: PaginatedInputEventsSearchInput; }>; -export type MyTicketsQuery = { - myTickets: { +export type FetchExampleEventsQuery = { + searchEvents: { data: Array<{ - approvalStatus: TicketApprovalStatus; id: string; - paymentStatus: TicketPaymentStatus; - redemptionStatus: TicketRedemptionStatus; + description?: string | null; + community?: { id: string; name?: string | null } | null; + tags: Array<{ + id: string; + name?: string | null; + description?: string | null; + }>; + }>; + }; +}; + +export type MyEventsQueryVariables = Exact<{ + input: PaginatedInputEventsSearchInput; + userTicketSearchInput?: InputMaybe; +}>; + +export type MyEventsQuery = { + searchEvents: { + data: Array<{ + id: string; + name: string; + description?: string | null; + startDateTime: string; + status: EventStatus; + community?: { id: string; name?: string | null } | null; + usersTickets: Array<{ + id: string; + approvalStatus: TicketApprovalStatus; + paymentStatus: TicketPaymentStatus; + redemptionStatus: TicketRedemptionStatus; + ticketTemplate: { description?: string | null; id: string }; + }>; }>; pagination: { currentPage: number; @@ -883,7 +912,7 @@ export type CheckPurchaseOrderStatusMutationVariables = Exact<{ export type CheckPurchaseOrderStatusMutation = { checkPurchaseOrderStatus: { - status: PurchaseOrderStatusEnum | null; + status?: PurchaseOrderStatusEnum | null; tickets: Array<{ approvalStatus: TicketApprovalStatus; paymentStatus: TicketPaymentStatus; @@ -901,10 +930,10 @@ export type CreatePurchaseOrderMutation = { | { __typename: "PurchaseOrder"; id: string; - finalPrice: number | null; - paymentLink: string | null; - status: PurchaseOrderStatusEnum | null; - currency: { id: string } | null; + finalPrice?: number | null; + paymentLink?: string | null; + status?: PurchaseOrderStatusEnum | null; + currency?: { id: string } | null; tickets: Array<{ id: string; approvalStatus: TicketApprovalStatus; @@ -922,13 +951,13 @@ export type CreatePurchaseOrderMutation = { export type EventTicketFragmentFragment = { id: string; name: string; - description: string | null; - quantity: number | null; + description?: string | null; + quantity?: number | null; isFree: boolean; startDateTime: string; status: TicketTemplateStatus; isUnlimited: boolean; - prices: Array<{ + prices?: Array<{ id: string; amount: number; currency: { currency: string; id: string }; @@ -940,17 +969,17 @@ export type GetEventAndTicketsQueryVariables = Exact<{ }>; export type GetEventAndTicketsQuery = { - event: { + event?: { id: string; name: string; - address: string | null; - description: string | null; - maxAttendees: number | null; + address?: string | null; + description?: string | null; + maxAttendees?: number | null; startDateTime: string; - endDateTime: string | null; + endDateTime?: string | null; status: EventStatus; - community: { name: string | null } | null; - users: Array<{ id: string; name: string | null }>; + community?: { name?: string | null } | null; + users: Array<{ id: string; name?: string | null }>; tickets: Array<{ " $fragmentRefs"?: { EventTicketFragmentFragment: EventTicketFragmentFragment; @@ -1010,13 +1039,13 @@ export const EventTicketFragmentFragmentDoc = { }, ], } as unknown as DocumentNode; -export const MyTicketsDocument = { +export const FetchExampleEventsDocument = { kind: "Document", definitions: [ { kind: "OperationDefinition", operation: "query", - name: { kind: "Name", value: "myTickets" }, + name: { kind: "Name", value: "FetchExampleEvents" }, variableDefinitions: [ { kind: "VariableDefinition", @@ -1028,10 +1057,7 @@ export const MyTicketsDocument = { kind: "NonNullType", type: { kind: "NamedType", - name: { - kind: "Name", - value: "PaginatedInputMyTicketsSearchValues", - }, + name: { kind: "Name", value: "PaginatedInputEventsSearchInput" }, }, }, }, @@ -1041,7 +1067,7 @@ export const MyTicketsDocument = { selections: [ { kind: "Field", - name: { kind: "Name", value: "myTickets" }, + name: { kind: "Name", value: "searchEvents" }, arguments: [ { kind: "Argument", @@ -1061,18 +1087,210 @@ export const MyTicketsDocument = { selectionSet: { kind: "SelectionSet", selections: [ + { kind: "Field", name: { kind: "Name", value: "id" } }, { kind: "Field", - name: { kind: "Name", value: "approvalStatus" }, + name: { kind: "Name", value: "description" }, + }, + { + kind: "Field", + name: { kind: "Name", value: "community" }, + selectionSet: { + kind: "SelectionSet", + selections: [ + { + kind: "Field", + name: { kind: "Name", value: "id" }, + }, + { + kind: "Field", + name: { kind: "Name", value: "name" }, + }, + ], + }, }, + { + kind: "Field", + name: { kind: "Name", value: "tags" }, + selectionSet: { + kind: "SelectionSet", + selections: [ + { + kind: "Field", + name: { kind: "Name", value: "id" }, + }, + { + kind: "Field", + name: { kind: "Name", value: "name" }, + }, + { + kind: "Field", + name: { kind: "Name", value: "description" }, + }, + ], + }, + }, + ], + }, + }, + ], + }, + }, + ], + }, + }, + ], +} as unknown as DocumentNode< + FetchExampleEventsQuery, + FetchExampleEventsQueryVariables +>; +export const MyEventsDocument = { + kind: "Document", + definitions: [ + { + kind: "OperationDefinition", + operation: "query", + name: { kind: "Name", value: "myEvents" }, + variableDefinitions: [ + { + kind: "VariableDefinition", + variable: { + kind: "Variable", + name: { kind: "Name", value: "input" }, + }, + type: { + kind: "NonNullType", + type: { + kind: "NamedType", + name: { kind: "Name", value: "PaginatedInputEventsSearchInput" }, + }, + }, + }, + { + kind: "VariableDefinition", + variable: { + kind: "Variable", + name: { kind: "Name", value: "userTicketSearchInput" }, + }, + type: { + kind: "NamedType", + name: { kind: "Name", value: "EventsTicketsSearchInput" }, + }, + }, + ], + selectionSet: { + kind: "SelectionSet", + selections: [ + { + kind: "Field", + name: { kind: "Name", value: "searchEvents" }, + arguments: [ + { + kind: "Argument", + name: { kind: "Name", value: "input" }, + value: { + kind: "Variable", + name: { kind: "Name", value: "input" }, + }, + }, + ], + selectionSet: { + kind: "SelectionSet", + selections: [ + { + kind: "Field", + name: { kind: "Name", value: "data" }, + selectionSet: { + kind: "SelectionSet", + selections: [ { kind: "Field", name: { kind: "Name", value: "id" } }, + { kind: "Field", name: { kind: "Name", value: "name" } }, { kind: "Field", - name: { kind: "Name", value: "paymentStatus" }, + name: { kind: "Name", value: "description" }, }, { kind: "Field", - name: { kind: "Name", value: "redemptionStatus" }, + name: { kind: "Name", value: "startDateTime" }, + }, + { + kind: "Field", + name: { kind: "Name", value: "community" }, + selectionSet: { + kind: "SelectionSet", + selections: [ + { + kind: "Field", + name: { kind: "Name", value: "id" }, + }, + { + kind: "Field", + name: { kind: "Name", value: "name" }, + }, + ], + }, + }, + { + kind: "Field", + name: { kind: "Name", value: "status" }, + }, + { + kind: "Field", + name: { kind: "Name", value: "usersTickets" }, + arguments: [ + { + kind: "Argument", + name: { kind: "Name", value: "input" }, + value: { + kind: "Variable", + name: { + kind: "Name", + value: "userTicketSearchInput", + }, + }, + }, + ], + selectionSet: { + kind: "SelectionSet", + selections: [ + { + kind: "Field", + name: { kind: "Name", value: "id" }, + }, + { + kind: "Field", + name: { kind: "Name", value: "approvalStatus" }, + }, + { + kind: "Field", + name: { kind: "Name", value: "paymentStatus" }, + }, + { + kind: "Field", + name: { kind: "Name", value: "redemptionStatus" }, + }, + { + kind: "Field", + name: { kind: "Name", value: "ticketTemplate" }, + selectionSet: { + kind: "SelectionSet", + selections: [ + { + kind: "Field", + name: { + kind: "Name", + value: "description", + }, + }, + { + kind: "Field", + name: { kind: "Name", value: "id" }, + }, + ], + }, + }, + ], + }, }, ], }, @@ -1109,7 +1327,7 @@ export const MyTicketsDocument = { }, }, ], -} as unknown as DocumentNode; +} as unknown as DocumentNode; export const CheckPurchaseOrderStatusDocument = { kind: "Document", definitions: [ diff --git a/app/components/LandingPageEvents/graphql/FetchExampleEvents.generated.tsx b/app/components/LandingPageEvents/graphql/FetchExampleEvents.generated.tsx new file mode 100644 index 0000000..af707df --- /dev/null +++ b/app/components/LandingPageEvents/graphql/FetchExampleEvents.generated.tsx @@ -0,0 +1,126 @@ +/* eslint-disable @typescript-eslint/ban-ts-comment */ +// @ts-nocheck +/* eslint-disable */ +/* prettier-ignore */ +/* This file is automatically generated. Please do not modify it manually. */ +import * as Types from '../../../api/gql/graphql'; + +import { gql } from "graphql-tag"; +import * as Apollo from "@apollo/client"; +const defaultOptions = {} as const; +export type FetchExampleEventsQueryVariables = Types.Exact<{ + input: Types.PaginatedInputEventsSearchInput; +}>; + +export type FetchExampleEventsQuery = { + __typename?: "Query"; + searchEvents: { + __typename?: "PaginatedEvent"; + data: Array<{ + __typename?: "Event"; + id: string; + description?: string | null; + community?: { + __typename?: "Community"; + id: string; + name?: string | null; + } | null; + tags: Array<{ + __typename?: "Tag"; + id: string; + name?: string | null; + description?: string | null; + }>; + }>; + }; +}; + +export const FetchExampleEventsDocument = gql` + query FetchExampleEvents($input: PaginatedInputEventsSearchInput!) { + searchEvents(input: $input) { + data { + id + description + community { + id + name + } + tags { + id + name + description + } + } + } + } +`; + +/** + * __useFetchExampleEventsQuery__ + * + * To run a query within a React component, call `useFetchExampleEventsQuery` and pass it any options that fit your needs. + * When your component renders, `useFetchExampleEventsQuery` returns an object from Apollo Client that contains loading, error, and data properties + * you can use to render your UI. + * + * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; + * + * @example + * const { data, loading, error } = useFetchExampleEventsQuery({ + * variables: { + * input: // value for 'input' + * }, + * }); + */ +export function useFetchExampleEventsQuery( + baseOptions: Apollo.QueryHookOptions< + FetchExampleEventsQuery, + FetchExampleEventsQueryVariables + > & + ( + | { variables: FetchExampleEventsQueryVariables; skip?: boolean } + | { skip: boolean } + ), +) { + const options = { ...defaultOptions, ...baseOptions }; + return Apollo.useQuery< + FetchExampleEventsQuery, + FetchExampleEventsQueryVariables + >(FetchExampleEventsDocument, options); +} +export function useFetchExampleEventsLazyQuery( + baseOptions?: Apollo.LazyQueryHookOptions< + FetchExampleEventsQuery, + FetchExampleEventsQueryVariables + >, +) { + const options = { ...defaultOptions, ...baseOptions }; + return Apollo.useLazyQuery< + FetchExampleEventsQuery, + FetchExampleEventsQueryVariables + >(FetchExampleEventsDocument, options); +} +export function useFetchExampleEventsSuspenseQuery( + baseOptions?: Apollo.SuspenseQueryHookOptions< + FetchExampleEventsQuery, + FetchExampleEventsQueryVariables + >, +) { + const options = { ...defaultOptions, ...baseOptions }; + return Apollo.useSuspenseQuery< + FetchExampleEventsQuery, + FetchExampleEventsQueryVariables + >(FetchExampleEventsDocument, options); +} +export type FetchExampleEventsQueryHookResult = ReturnType< + typeof useFetchExampleEventsQuery +>; +export type FetchExampleEventsLazyQueryHookResult = ReturnType< + typeof useFetchExampleEventsLazyQuery +>; +export type FetchExampleEventsSuspenseQueryHookResult = ReturnType< + typeof useFetchExampleEventsSuspenseQuery +>; +export type FetchExampleEventsQueryResult = Apollo.QueryResult< + FetchExampleEventsQuery, + FetchExampleEventsQueryVariables +>; diff --git a/app/components/LandingPageEvents/graphql/FetchExampleEvents.gql b/app/components/LandingPageEvents/graphql/FetchExampleEvents.gql new file mode 100644 index 0000000..7c486ef --- /dev/null +++ b/app/components/LandingPageEvents/graphql/FetchExampleEvents.gql @@ -0,0 +1,17 @@ +query FetchExampleEvents($input: PaginatedInputEventsSearchInput!) { + searchEvents(input: $input) { + data { + id + description + community { + id + name + } + tags { + id + name + description + } + } + } +} diff --git a/app/components/MyEvents/MyTicketsList.tsx b/app/components/MyEvents/MyTicketsList.tsx new file mode 100644 index 0000000..703bd37 --- /dev/null +++ b/app/components/MyEvents/MyTicketsList.tsx @@ -0,0 +1,147 @@ +import { formatDistanceToNow, subDays, format } from "date-fns"; +import { ArrowRight } from "lucide-react"; +import { useMemo } from "react"; + +import { + MyEventsQuery, + useMyEventsSuspenseQuery, +} from "~/components/MyEvents/graphql/myEvents.generated"; +import { Badge } from "~/components/ui/badge"; +import { Button } from "~/components/ui/button"; +import { Card, CardTitle } from "~/components/ui/card"; +import { urls } from "~/utils/urls"; + +export const MyTicketsList = ({ + startDateTimeFrom = null, + startDateTimeTo = null, +}: { + startDateTimeFrom?: string | null; + startDateTimeTo?: string | null; +}) => { + const { data } = useMyEventsSuspenseQuery({ + variables: { + input: { + search: { + userHasTickets: true, + id: null, + name: null, + startDateTimeFrom: startDateTimeFrom, + startDateTimeTo: startDateTimeTo, + status: null, + visibility: null, + }, + pagination: { + page: 0, + pageSize: 10, + }, + }, + }, + }); + + const { groupedByDate, orderedDates } = useMemo(() => { + const groupedByDate = data.searchEvents.data.reduce( + (acc, event) => { + const date = event.startDateTime as string; + // const date = format(parsedDate, "cccc - d 'de' MMMM, yyyy"); + + if (!acc[date]) { + acc[date] = []; + } + + acc[date].push(event); + + return acc; + }, + {} as Record, + ); + + const orderedDates = Object.keys(groupedByDate).sort((a, b) => { + const dateA = new Date(a); + const dateB = new Date(b); + + if (dateA > dateB) { + return -1; + } + + if (dateA < dateB) { + return 1; + } + + return 0; + }); + + return { + groupedByDate, + orderedDates, + }; + }, [data.searchEvents.data]); + + // We go over the groupedByDateArray object in order + // to render the events grouped by date + + return ( +
+ {!data.searchEvents.data.length && ( +
No hay eventos
+ )} + {orderedDates.map((event) => { + return ( +
+
+ + {format(event, "d 'de' MMMM, yyyy")} + +
+ {groupedByDate[event].map((event) => { + const parsedDate = new Date(event.startDateTime as string); + const isOverAWeekFromNow = parsedDate > subDays(new Date(), 7); + const relativeDate = formatDistanceToNow(parsedDate, { + addSuffix: true, + }); + const formattedDate = format( + parsedDate, + "cccc - d 'de' MMMM, yyyy", + ); + const date = isOverAWeekFromNow ? formattedDate : relativeDate; + + const formattedTime = format(parsedDate, "hh:mm aaa"); + + return ( + +
+ {date} + {formattedTime} +
+ {event.name} +
+ +
+ + {event.community?.name} + +
+
+
+ ); + })} +
+ ); + })} +
+ ); +}; diff --git a/app/components/MyEvents/MyTicketsLoadingSkeleton.tsx b/app/components/MyEvents/MyTicketsLoadingSkeleton.tsx new file mode 100644 index 0000000..1322e1c --- /dev/null +++ b/app/components/MyEvents/MyTicketsLoadingSkeleton.tsx @@ -0,0 +1,43 @@ +import { Button } from "~/components/ui/button"; +import { Card } from "~/components/ui/card"; +import { Skeleton } from "~/components/ui/skeleton"; + +const LoadingCard = () => { + return ( + +
+ + + {/* - + + + + */} + + + + {/* - + + + + */} + +
+ +
+ +
+
+ ); +}; +export const MyTicketsLoadingSkeleton = () => { + return ( +
+ + + +
+ ); +}; diff --git a/app/components/MyEvents/graphql/myEvents.generated.tsx b/app/components/MyEvents/graphql/myEvents.generated.tsx new file mode 100644 index 0000000..c8a7d31 --- /dev/null +++ b/app/components/MyEvents/graphql/myEvents.generated.tsx @@ -0,0 +1,153 @@ +/* eslint-disable @typescript-eslint/ban-ts-comment */ +// @ts-nocheck +/* eslint-disable */ +/* prettier-ignore */ +/* This file is automatically generated. Please do not modify it manually. */ +import * as Types from '../../../api/gql/graphql'; + +import { gql } from "graphql-tag"; +import * as Apollo from "@apollo/client"; +const defaultOptions = {} as const; +export type MyEventsQueryVariables = Types.Exact<{ + input: Types.PaginatedInputEventsSearchInput; + userTicketSearchInput?: Types.InputMaybe; +}>; + +export type MyEventsQuery = { + __typename?: "Query"; + searchEvents: { + __typename?: "PaginatedEvent"; + data: Array<{ + __typename?: "Event"; + id: string; + name: string; + description?: string | null; + startDateTime: any; + status: Types.EventStatus; + community?: { + __typename?: "Community"; + id: string; + name?: string | null; + } | null; + usersTickets: Array<{ + __typename?: "UserTicket"; + id: string; + approvalStatus: Types.TicketApprovalStatus; + paymentStatus: Types.TicketPaymentStatus; + redemptionStatus: Types.TicketRedemptionStatus; + ticketTemplate: { + __typename?: "Ticket"; + description?: string | null; + id: string; + }; + }>; + }>; + pagination: { + __typename?: "Pagination"; + currentPage: number; + pageSize: number; + totalPages: number; + totalRecords: number; + }; + }; +}; + +export const MyEventsDocument = gql` + query myEvents( + $input: PaginatedInputEventsSearchInput! + $userTicketSearchInput: EventsTicketsSearchInput + ) { + searchEvents(input: $input) { + data { + id + name + description + startDateTime + community { + id + name + } + status + usersTickets(input: $userTicketSearchInput) { + id + approvalStatus + paymentStatus + redemptionStatus + ticketTemplate { + description + id + } + } + } + pagination { + currentPage + pageSize + totalPages + totalRecords + } + } + } +`; + +/** + * __useMyEventsQuery__ + * + * To run a query within a React component, call `useMyEventsQuery` and pass it any options that fit your needs. + * When your component renders, `useMyEventsQuery` returns an object from Apollo Client that contains loading, error, and data properties + * you can use to render your UI. + * + * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; + * + * @example + * const { data, loading, error } = useMyEventsQuery({ + * variables: { + * input: // value for 'input' + * userTicketSearchInput: // value for 'userTicketSearchInput' + * }, + * }); + */ +export function useMyEventsQuery( + baseOptions: Apollo.QueryHookOptions & + ({ variables: MyEventsQueryVariables; skip?: boolean } | { skip: boolean }), +) { + const options = { ...defaultOptions, ...baseOptions }; + return Apollo.useQuery( + MyEventsDocument, + options, + ); +} +export function useMyEventsLazyQuery( + baseOptions?: Apollo.LazyQueryHookOptions< + MyEventsQuery, + MyEventsQueryVariables + >, +) { + const options = { ...defaultOptions, ...baseOptions }; + return Apollo.useLazyQuery( + MyEventsDocument, + options, + ); +} +export function useMyEventsSuspenseQuery( + baseOptions?: Apollo.SuspenseQueryHookOptions< + MyEventsQuery, + MyEventsQueryVariables + >, +) { + const options = { ...defaultOptions, ...baseOptions }; + return Apollo.useSuspenseQuery( + MyEventsDocument, + options, + ); +} +export type MyEventsQueryHookResult = ReturnType; +export type MyEventsLazyQueryHookResult = ReturnType< + typeof useMyEventsLazyQuery +>; +export type MyEventsSuspenseQueryHookResult = ReturnType< + typeof useMyEventsSuspenseQuery +>; +export type MyEventsQueryResult = Apollo.QueryResult< + MyEventsQuery, + MyEventsQueryVariables +>; diff --git a/app/components/MyEvents/graphql/myEvents.gql b/app/components/MyEvents/graphql/myEvents.gql new file mode 100644 index 0000000..b27a726 --- /dev/null +++ b/app/components/MyEvents/graphql/myEvents.gql @@ -0,0 +1,34 @@ +query myEvents( + $input: PaginatedInputEventsSearchInput! + $userTicketSearchInput: EventsTicketsSearchInput +) { + searchEvents(input: $input) { + data { + id + name + description + startDateTime + community { + id + name + } + status + usersTickets(input: $userTicketSearchInput) { + id + approvalStatus + paymentStatus + redemptionStatus + ticketTemplate { + description + id + } + } + } + pagination { + currentPage + pageSize + totalPages + totalRecords + } + } +} diff --git a/app/components/MyTickets/graphql/myTickets.generated.tsx b/app/components/MyTickets/graphql/myTickets.generated.tsx deleted file mode 100644 index 8db11bf..0000000 --- a/app/components/MyTickets/graphql/myTickets.generated.tsx +++ /dev/null @@ -1,121 +0,0 @@ -/* eslint-disable @typescript-eslint/ban-ts-comment */ -// @ts-nocheck -/* eslint-disable */ -/* prettier-ignore */ -/* This file is automatically generated. Please do not modify it manually. */ -import * as Types from '../../../api/gql/graphql'; - -import { gql } from "graphql-tag"; -import * as Apollo from "@apollo/client"; -const defaultOptions = {} as const; -export type MyTicketsQueryVariables = Types.Exact<{ - input: Types.PaginatedInputMyTicketsSearchValues; -}>; - -export type MyTicketsQuery = { - __typename?: "Query"; - myTickets: { - __typename?: "PaginatedUserTicket"; - data: Array<{ - __typename?: "UserTicket"; - approvalStatus: Types.TicketApprovalStatus; - id: string; - paymentStatus: Types.TicketPaymentStatus; - redemptionStatus: Types.TicketRedemptionStatus; - }>; - pagination: { - __typename?: "Pagination"; - currentPage: number; - pageSize: number; - totalPages: number; - totalRecords: number; - }; - }; -}; - -export const MyTicketsDocument = gql` - query myTickets($input: PaginatedInputMyTicketsSearchValues!) { - myTickets(input: $input) { - data { - approvalStatus - id - paymentStatus - redemptionStatus - } - pagination { - currentPage - pageSize - totalPages - totalRecords - } - } - } -`; - -/** - * __useMyTicketsQuery__ - * - * To run a query within a React component, call `useMyTicketsQuery` and pass it any options that fit your needs. - * When your component renders, `useMyTicketsQuery` returns an object from Apollo Client that contains loading, error, and data properties - * you can use to render your UI. - * - * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; - * - * @example - * const { data, loading, error } = useMyTicketsQuery({ - * variables: { - * input: // value for 'input' - * }, - * }); - */ -export function useMyTicketsQuery( - baseOptions: Apollo.QueryHookOptions< - MyTicketsQuery, - MyTicketsQueryVariables - > & - ( - | { variables: MyTicketsQueryVariables; skip?: boolean } - | { skip: boolean } - ), -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useQuery( - MyTicketsDocument, - options, - ); -} -export function useMyTicketsLazyQuery( - baseOptions?: Apollo.LazyQueryHookOptions< - MyTicketsQuery, - MyTicketsQueryVariables - >, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useLazyQuery( - MyTicketsDocument, - options, - ); -} -export function useMyTicketsSuspenseQuery( - baseOptions?: Apollo.SuspenseQueryHookOptions< - MyTicketsQuery, - MyTicketsQueryVariables - >, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useSuspenseQuery( - MyTicketsDocument, - options, - ); -} -export type MyTicketsQueryHookResult = ReturnType; -export type MyTicketsLazyQueryHookResult = ReturnType< - typeof useMyTicketsLazyQuery ->; -export type MyTicketsSuspenseQueryHookResult = ReturnType< - typeof useMyTicketsSuspenseQuery ->; -export type MyTicketsQueryResult = Apollo.QueryResult< - MyTicketsQuery, - MyTicketsQueryVariables ->; diff --git a/app/components/MyTickets/graphql/myTickets.gql b/app/components/MyTickets/graphql/myTickets.gql deleted file mode 100644 index f7b178c..0000000 --- a/app/components/MyTickets/graphql/myTickets.gql +++ /dev/null @@ -1,16 +0,0 @@ -query myTickets($input: PaginatedInputMyTicketsSearchValues!) { - myTickets(input: $input) { - data { - approvalStatus - id - paymentStatus - redemptionStatus - } - pagination { - currentPage - pageSize - totalPages - totalRecords - } - } -} diff --git a/app/components/Navbar/index.tsx b/app/components/Navbar/index.tsx index ad70719..689bdf7 100644 --- a/app/components/Navbar/index.tsx +++ b/app/components/Navbar/index.tsx @@ -14,7 +14,7 @@ const guestItems = [ { content: "Eventos", show: true, - link: urls.eventos.root, + link: urls.events.root, }, { content: "Comunidades", @@ -33,7 +33,7 @@ export const Navbar = () => { { content: "Eventos", show: true, - link: urls.eventos.root, + link: urls.events.root, }, { content: "Comunidades", @@ -41,9 +41,9 @@ export const Navbar = () => { link: urls.comunidades, }, { - content: "Mis Tickets", + content: "Mis Eventos", show: true, - link: urls.tickets.root, + link: urls.myEvents.root, }, { content: "Perfil", diff --git a/app/components/Register/Register.tsx b/app/components/Register/Register.tsx index ceac122..8d38e83 100644 --- a/app/components/Register/Register.tsx +++ b/app/components/Register/Register.tsx @@ -25,7 +25,7 @@ export const Register = (props: { eventId: string }) => { Para registrarte, por favor haz click en el botón.

); diff --git a/app/components/ui/badge.tsx b/app/components/ui/badge.tsx index 07e5ee8..ceeba6f 100644 --- a/app/components/ui/badge.tsx +++ b/app/components/ui/badge.tsx @@ -1,5 +1,5 @@ -import * as React from "react"; import { cva, type VariantProps } from "class-variance-authority"; +import * as React from "react"; import { cn } from "~/utils/utils"; diff --git a/app/root.tsx b/app/root.tsx index b6ede27..b84df9d 100644 --- a/app/root.tsx +++ b/app/root.tsx @@ -4,14 +4,20 @@ import { Outlet, Scripts, ScrollRestoration, + useLocation, } from "@remix-run/react"; - +import { setDefaultOptions } from "date-fns"; +import { es } from "date-fns/locale"; import "./tailwind.css"; +import { AnimatePresence, motion } from "framer-motion"; + import { ApolloWrapper } from "~/api/ApolloWrapper"; import { Navbar } from "~/components/Navbar"; import { Toaster } from "~/components/ui/sonner"; import { AuthProvider } from "~/utils/supabase/AuthProvider"; +setDefaultOptions({ locale: es }); + export function Layout({ children }: { children: React.ReactNode }) { return ( @@ -30,12 +36,29 @@ export function Layout({ children }: { children: React.ReactNode }) { ); } +const variants = { + initial: { opacity: 0, scale: 0.99 }, + animate: { opacity: 1, scale: 1 }, + exit: { opacity: 0, scale: 0.99 }, +}; +const transition = { duration: 0.3 }; export default function App() { return ( - + + + + + diff --git a/app/routes/_authenticated/my-events/index.tsx b/app/routes/_authenticated/my-events/index.tsx new file mode 100644 index 0000000..bbac129 --- /dev/null +++ b/app/routes/_authenticated/my-events/index.tsx @@ -0,0 +1,36 @@ +import { cx } from "class-variance-authority"; +import { Suspense, useMemo, useState } from "react"; + +import { MyTicketsList } from "~/components/MyEvents/MyTicketsList"; +import { MyTicketsLoadingSkeleton } from "~/components/MyEvents/MyTicketsLoadingSkeleton"; +import { sharedLayoutStyle } from "~/components/sharedLayouts"; +import { Tabs, TabsList, TabsTrigger } from "~/components/ui/tabs"; + +export default function Layout() { + const [tab, setTab] = useState<"future" | "past">("future"); + const now = useMemo(() => new Date().toISOString(), []); + + return ( +
+
+

Eventos

+
+ setTab(el as "future" | "past")} + > + + Futuros + Pasados + + +
+
+ }> + {tab === "future" && } + {tab === "past" && } + +
+ ); +} diff --git a/app/routes/_authenticated/tickets/index.tsx b/app/routes/_authenticated/tickets/index.tsx deleted file mode 100644 index 5a1dd5a..0000000 --- a/app/routes/_authenticated/tickets/index.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import { sharedLayoutStyle } from "~/components/sharedLayouts"; - -export default function Layout() { - return ( -
-

Mis Tickets

-
- ); -} diff --git a/app/utils/urls.ts b/app/utils/urls.ts index 4dab974..e6e1ee5 100644 --- a/app/utils/urls.ts +++ b/app/utils/urls.ts @@ -1,10 +1,13 @@ export const urls = { home: "/", - eventos: { + events: { root: "/eventos", - evento: (id: string) => `/eventos/${id}`, tickets: (id: string) => `/eventos/${id}/tickets`, }, + myEvents: { + root: `/my-events`, + myTickets: (id: string) => `/my-events/${id}/my-tickets`, + }, ordenes: { root: "/ordenes", orden: (id: string) => `/ordenes/${id}`, diff --git a/codegen.ts b/codegen.ts index 08788b0..90fd97d 100644 --- a/codegen.ts +++ b/codegen.ts @@ -15,6 +15,9 @@ const noTypeCheckingPlugin = { }; const config = { ...defaultConfig, + hooks: { + afterOneFileWrite: ["prettier --write"], + }, ignoreNoDocuments: true, generates: { "app/api/gql/": { @@ -23,7 +26,7 @@ const config = { config: { useTypeImports: true, skipTypename: true, - avoidOptionals: true, + avoidOptionals: false, nonOptionalTypename: false, // Lamentablemente, code-gen establece "any" como predeterminado, cuando no tiene un // tipo para un "scalar". Esta opción nos obliga a definir un tipo cada vez que diff --git a/components.json b/components.json index 27135ec..1ff84e3 100644 --- a/components.json +++ b/components.json @@ -12,6 +12,6 @@ }, "aliases": { "components": "~/components", - "utils": "~/lib/utils" + "utils": "~/utils/utils" } } diff --git a/package-lock.json b/package-lock.json index c700e37..8add5e4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,6 +25,7 @@ "@supabase/supabase-js": "^2.44.2", "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", + "date-fns": "^3.6.0", "framer-motion": "^11.2.12", "graphiql": "^3.0.6", "graphql": "^16.8.1", @@ -8210,6 +8211,15 @@ "integrity": "sha512-8YnDaaf7N3k/q5HnTJVuzSyLETjoZjVmHc4AeKAzOvKHEFQKcn64OKBfzHYtE9zGjctNM7V9I0MfnUVLpi7M5g==", "dev": true }, + "node_modules/date-fns": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.6.0.tgz", + "integrity": "sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/kossnocorp" + } + }, "node_modules/debounce": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", diff --git a/package.json b/package.json index 0208ed7..b559510 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,7 @@ "@supabase/supabase-js": "^2.44.2", "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", + "date-fns": "^3.6.0", "framer-motion": "^11.2.12", "graphiql": "^3.0.6", "graphql": "^16.8.1",