diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..25fa621 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "typescript.tsdk": "node_modules/typescript/lib" +} diff --git a/app/api/ApolloClientForRSC.tsx b/app/api/ApolloClientForRSC.tsx deleted file mode 100644 index 5d8d8cf..0000000 --- a/app/api/ApolloClientForRSC.tsx +++ /dev/null @@ -1,27 +0,0 @@ -// import { ApolloClient, HttpLink, InMemoryCache } from "@apollo/client"; -// import { registerApolloClient } from "@apollo/experimental-nextjs-app-support/rsc"; -// import { cookies } from "next/headers"; - -// import { COOKIE_NAME } from "@/utils/supabase/client"; - -// const { getClient } = registerApolloClient(() => { -// const cookieValue = cookies().get(COOKIE_NAME)?.value ?? ""; -// const headers = cookieValue -// ? { -// headers: { -// cookie: `${COOKIE_NAME}=${cookieValue}`, -// }, -// } -// : {}; -// return new ApolloClient({ -// cache: new InMemoryCache(), -// link: new HttpLink({ -// // this needs to be an absolute url, as relative urls cannot be used in SSR -// uri: VITE_JSCL_API_URL, -// // fetch, -// ...headers, -// }), -// }); -// }); - -// export const getApolloClientForRSC = getClient; diff --git a/app/api/ApolloWrapper.tsx b/app/api/ApolloWrapper.tsx index 9f97ad9..811663e 100644 --- a/app/api/ApolloWrapper.tsx +++ b/app/api/ApolloWrapper.tsx @@ -10,8 +10,7 @@ import { setContext } from "@apollo/client/link/context"; import { onError } from "@apollo/client/link/error"; import { RetryLink } from "@apollo/client/link/retry"; -import { useSetTokenRef, useTokenRef } from "../utils/supabase/AuthProvider"; -import { supabaseClient } from "../utils/supabase/client"; +import { useRefreshSession, useTokenRef } from "../utils/supabase/AuthProvider"; const retryLink = new RetryLink(); @@ -62,38 +61,20 @@ const useAuthLink = () => { // Este link se encarga de manejar errores de autenticación // Si el servidor responde con un code UNAUTHENTICATED, intenta refrescar el token. const useErrorLink = () => { - const setToken = useSetTokenRef(); + const refreshSession = useRefreshSession(); return onError(({ graphQLErrors, networkError, operation, forward }) => { if (graphQLErrors) { for (const err of graphQLErrors) { - if (err.extensions.code === "UNAUTHENTICATED") { - supabaseClient.auth - .getSession() - .then(({ data, error }) => { - if (error) { - // eslint-disable-next-line no-console - console.error("Error refreshing access token", error); - - return; - } - - const newToken = data.session?.access_token; - - if (!newToken) { - // eslint-disable-next-line no-console - console.error("No access token found in session data"); - } else { - setToken(newToken); - } - + if (err.extensions.type === "UNAUTHENTICATED") { + refreshSession() + .then(() => { forward(operation); }) - .catch((error: unknown) => { + .catch(() => { // eslint-disable-next-line no-console - console.error("Error refreshing access token", error); + console.error("Error refreshing access token"); }); - // } } } } else if (networkError) { @@ -117,8 +98,7 @@ if (!import.meta.env.VITE_JSCL_API_URL) { const httpLink = new HttpLink({ // Tiene que ser una URL absoluta, ya que las URLs relativas no pueden ser usadas en SSR. uri: import.meta.env.VITE_JSCL_API_URL, - fetchOptions: { cache: "no-store", credentials: "include" }, - credentials: "include", + fetchOptions: { cache: "no-store" }, }); function useMakeClient() { diff --git a/app/api/gql/gql.ts b/app/api/gql/gql.ts index 368d125..d6012df 100644 --- a/app/api/gql/gql.ts +++ b/app/api/gql/gql.ts @@ -13,6 +13,7 @@ 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, "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}": types.CreatePurchaseOrderDocument, "fragment EventTicketFragment on Ticket {\n id\n name\n description\n quantity\n isFree\n startDateTime\n status\n isUnlimited\n prices {\n id\n amount\n currency {\n currency\n id\n }\n }\n}": types.EventTicketFragmentFragmentDoc, @@ -33,6 +34,10 @@ const documents = { */ 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}"]; /** * 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 69624fd..9ced7e4 100644 --- a/app/api/gql/graphql.ts +++ b/app/api/gql/graphql.ts @@ -880,6 +880,13 @@ export type UserSearchInput = { tags: InputMaybe>; }; +export type MyTicketsQueryVariables = Exact<{ + input: PaginatedInputMyTicketsSearchValues; +}>; + + +export type MyTicketsQuery = { myTickets: { data: Array<{ approvalStatus: TicketApprovalStatus, id: string, paymentStatus: TicketPaymentStatus, redemptionStatus: TicketRedemptionStatus }>, pagination: { currentPage: number, pageSize: number, totalPages: number, totalRecords: number } } }; + export type CheckPurchaseOrderStatusMutationVariables = Exact<{ input: CheckForPurchaseOrderInput; }>; @@ -904,6 +911,7 @@ export type GetEventAndTicketsQueryVariables = Exact<{ export type GetEventAndTicketsQuery = { event: { id: string, name: string, address: string | null, description: string | null, maxAttendees: number | null, startDateTime: string, endDateTime: string | null, status: EventStatus, community: { name: string | null } | null, users: Array<{ id: string, name: string | null }>, tickets: Array<{ ' $fragmentRefs'?: { 'EventTicketFragmentFragment': EventTicketFragmentFragment } }> } | null }; export const EventTicketFragmentFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"EventTicketFragment"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Ticket"}},"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"}},{"kind":"Field","name":{"kind":"Name","value":"quantity"}},{"kind":"Field","name":{"kind":"Name","value":"isFree"}},{"kind":"Field","name":{"kind":"Name","value":"startDateTime"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"isUnlimited"}},{"kind":"Field","name":{"kind":"Name","value":"prices"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"amount"}},{"kind":"Field","name":{"kind":"Name","value":"currency"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"currency"}},{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}}]} as unknown as DocumentNode; +export const MyTicketsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"myTickets"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"PaginatedInputMyTicketsSearchValues"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"myTickets"},"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":"approvalStatus"}},{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"paymentStatus"}},{"kind":"Field","name":{"kind":"Name","value":"redemptionStatus"}}]}},{"kind":"Field","name":{"kind":"Name","value":"pagination"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"currentPage"}},{"kind":"Field","name":{"kind":"Name","value":"pageSize"}},{"kind":"Field","name":{"kind":"Name","value":"totalPages"}},{"kind":"Field","name":{"kind":"Name","value":"totalRecords"}}]}}]}}]}}]} as unknown as DocumentNode; export const CheckPurchaseOrderStatusDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CheckPurchaseOrderStatus"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"CheckForPurchaseOrderInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"checkPurchaseOrderStatus"},"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":"status"}},{"kind":"Field","name":{"kind":"Name","value":"tickets"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"approvalStatus"}},{"kind":"Field","name":{"kind":"Name","value":"paymentStatus"}},{"kind":"Field","name":{"kind":"Name","value":"redemptionStatus"}}]}}]}}]}}]} as unknown as DocumentNode; export const CreatePurchaseOrderDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"createPurchaseOrder"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"TicketClaimInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"claimUserTicket"},"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":"__typename"}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"PurchaseOrder"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"__typename"}},{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"currency"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}},{"kind":"Field","name":{"kind":"Name","value":"finalPrice"}},{"kind":"Field","name":{"kind":"Name","value":"paymentLink"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"tickets"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"approvalStatus"}},{"kind":"Field","name":{"kind":"Name","value":"redemptionStatus"}},{"kind":"Field","name":{"kind":"Name","value":"paymentStatus"}}]}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"RedeemUserTicketError"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"__typename"}},{"kind":"Field","name":{"kind":"Name","value":"error"}},{"kind":"Field","name":{"kind":"Name","value":"errorMessage"}}]}}]}}]}}]} as unknown as DocumentNode; export const GetEventAndTicketsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"getEventAndTickets"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"event"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"address"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"maxAttendees"}},{"kind":"Field","name":{"kind":"Name","value":"startDateTime"}},{"kind":"Field","name":{"kind":"Name","value":"endDateTime"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"community"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"users"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"tickets"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"EventTicketFragment"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"EventTicketFragment"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Ticket"}},"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"}},{"kind":"Field","name":{"kind":"Name","value":"quantity"}},{"kind":"Field","name":{"kind":"Name","value":"isFree"}},{"kind":"Field","name":{"kind":"Name","value":"startDateTime"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"isUnlimited"}},{"kind":"Field","name":{"kind":"Name","value":"prices"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"amount"}},{"kind":"Field","name":{"kind":"Name","value":"currency"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"currency"}},{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}}]} as unknown as DocumentNode; \ No newline at end of file diff --git a/app/components/MyTickets/graphql/myTickets.generated.tsx b/app/components/MyTickets/graphql/myTickets.generated.tsx new file mode 100644 index 0000000..266595e --- /dev/null +++ b/app/components/MyTickets/graphql/myTickets.generated.tsx @@ -0,0 +1,69 @@ +/* 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 & ({ variables: MyTicketsQueryVariables; skip?: boolean; } | { skip: boolean; }) ) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useQuery(MyTicketsDocument, options); + } +export function useMyTicketsLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useLazyQuery(MyTicketsDocument, options); + } +export function useMyTicketsSuspenseQuery(baseOptions?: Apollo.SuspenseQueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useSuspenseQuery(MyTicketsDocument, options); + } +export type MyTicketsQueryHookResult = ReturnType; +export type MyTicketsLazyQueryHookResult = ReturnType; +export type MyTicketsSuspenseQueryHookResult = ReturnType; +export type MyTicketsQueryResult = Apollo.QueryResult; \ No newline at end of file diff --git a/app/components/MyTickets/graphql/myTickets.gql b/app/components/MyTickets/graphql/myTickets.gql new file mode 100644 index 0000000..f7b178c --- /dev/null +++ b/app/components/MyTickets/graphql/myTickets.gql @@ -0,0 +1,16 @@ +query myTickets($input: PaginatedInputMyTicketsSearchValues!) { + myTickets(input: $input) { + data { + approvalStatus + id + paymentStatus + redemptionStatus + } + pagination { + currentPage + pageSize + totalPages + totalRecords + } + } +} diff --git a/app/components/Navbar/MainNav.tsx b/app/components/Navbar/MainNav.tsx index a18e839..87cdb02 100644 --- a/app/components/Navbar/MainNav.tsx +++ b/app/components/Navbar/MainNav.tsx @@ -11,9 +11,11 @@ export function MainNav({ items }: NavBarProps) { return (