From c1f87ad14df1b9e52e0439d67f7a4ae193f37303 Mon Sep 17 00:00:00 2001 From: Luka Pajukanta Date: Fri, 12 Jun 2026 23:38:58 +0300 Subject: [PATCH 01/10] feat(tickets_v2): self-service order cancellation Finnish consumer protection law requires webshops to offer a self-service cancellation function as of June 2026. Customers can now cancel paid orders themselves within a per-event cancellation period (TicketsV2EventMeta.cancellation_period_days, default 0 = disabled; capped at event start). Cancellation is confirmed via a one-time link sent to the email address of the order, after which an automated refund is initiated via the payment provider. Paid orders that cannot be automatically refunded (eg. marked as paid manually) direct the customer to contact ticket sales instead. Backend: - Add cancellation_period_days to TicketsV2EventMeta - Add OrderCancellationToken (one-time code, no Person FK required) - Add Order.cancellation_deadline and can_be_cancelled_by_customer - Add RequestOrderCancellation, ConfirmOrderCancellation and UpdateTicketsPreferences GraphQL mutations - Add cancellation link and deadline to email receipts - Expose canRequestCancellation and cancellationDeadline in the optimized server order API - Expire the event caches of the receipt worker and the optimized server on a 5 minute TTL so admin settings changes take effect Frontend: - New anonymous order cancellation and confirmation pages - Cancel button links on the order page and the profile order page - New tickets admin preferences page (contact email, T&C URLs, cancellation period) with a Settings tab - SubmitButton now shows a spinner and disables while submitting Co-Authored-By: Claude Fable 5 --- kompassi-v2-frontend/src/__generated__/gql.ts | 30 +- .../src/__generated__/graphql.ts | 156 ++++++++- .../orders/[orderId]/cancel/[code]/page.tsx | 82 +++++ .../orders/[orderId]/cancel/actions.ts | 87 +++++ .../orders/[orderId]/cancel/page.tsx | 94 ++++++ .../[eventSlug]/orders/[orderId]/page.tsx | 24 ++ .../tickets-preferences/actions.ts | 47 +++ .../[eventSlug]/tickets-preferences/page.tsx | 159 ++++++++++ .../orders/[eventSlug]/[orderId]/page.tsx | 21 ++ .../src/components/forms/SubmitButton.tsx | 7 + .../components/tickets/TicketsAdminTabs.tsx | 6 + kompassi-v2-frontend/src/services/tickets.ts | 2 + kompassi-v2-frontend/src/translations/en.tsx | 109 +++++++ kompassi-v2-frontend/src/translations/fi.tsx | 109 +++++++ kompassi-v2-frontend/src/translations/sv.tsx | 111 +++++++ kompassi/graphql_api/schema.py | 7 + kompassi/tickets_v2/event_log_entry_types.py | 5 + kompassi/tickets_v2/graphql/meta.py | 9 +- .../mutations/confirm_order_cancellation.py | 71 +++++ .../mutations/request_order_cancellation.py | 64 ++++ .../mutations/update_tickets_preferences.py | 72 +++++ kompassi/tickets_v2/graphql/order_profile.py | 26 ++ ...tmeta_cancellation_period_days_and_more.py | 53 ++++ kompassi/tickets_v2/models/__init__.py | 1 + kompassi/tickets_v2/models/enums.py | 1 + kompassi/tickets_v2/models/meta.py | 9 + kompassi/tickets_v2/models/order.py | 37 +++ .../models/order_cancellation_token.py | 153 +++++++++ kompassi/tickets_v2/models/receipt.py | 67 +++- kompassi/tickets_v2/optimized_server/app.py | 2 + .../optimized_server/models/event.py | 16 +- .../optimized_server/models/order.py | 53 +++- .../models/sql/get_events.sql | 4 +- .../optimized_server/models/sql/get_order.sql | 11 +- .../tickets_v2_cancellation_request_en.eml | 19 ++ .../tickets_v2_cancellation_request_fi.eml | 18 ++ .../templates/tickets_v2_receipt_en.eml | 7 +- .../templates/tickets_v2_receipt_fi.eml | 7 +- kompassi/tickets_v2/tests.py | 300 +++++++++++++++++- 39 files changed, 2037 insertions(+), 19 deletions(-) create mode 100644 kompassi-v2-frontend/src/app/[locale]/[eventSlug]/orders/[orderId]/cancel/[code]/page.tsx create mode 100644 kompassi-v2-frontend/src/app/[locale]/[eventSlug]/orders/[orderId]/cancel/actions.ts create mode 100644 kompassi-v2-frontend/src/app/[locale]/[eventSlug]/orders/[orderId]/cancel/page.tsx create mode 100644 kompassi-v2-frontend/src/app/[locale]/[eventSlug]/tickets-preferences/actions.ts create mode 100644 kompassi-v2-frontend/src/app/[locale]/[eventSlug]/tickets-preferences/page.tsx create mode 100644 kompassi/tickets_v2/graphql/mutations/confirm_order_cancellation.py create mode 100644 kompassi/tickets_v2/graphql/mutations/request_order_cancellation.py create mode 100644 kompassi/tickets_v2/graphql/mutations/update_tickets_preferences.py create mode 100644 kompassi/tickets_v2/migrations/0009_ticketsv2eventmeta_cancellation_period_days_and_more.py create mode 100644 kompassi/tickets_v2/models/order_cancellation_token.py create mode 100644 kompassi/tickets_v2/templates/tickets_v2_cancellation_request_en.eml create mode 100644 kompassi/tickets_v2/templates/tickets_v2_cancellation_request_fi.eml diff --git a/kompassi-v2-frontend/src/__generated__/gql.ts b/kompassi-v2-frontend/src/__generated__/gql.ts index 061d8cda2..3565a2fbc 100644 --- a/kompassi-v2-frontend/src/__generated__/gql.ts +++ b/kompassi-v2-frontend/src/__generated__/gql.ts @@ -44,6 +44,8 @@ type Documents = { "\n fragment ProductChoice on FullProductType {\n id\n title\n }\n": typeof types.ProductChoiceFragmentDoc, "\n query AdminOrderListWithOrders(\n $eventSlug: String!\n $filters: [DimensionFilterInput!]\n $search: String\n $returnNone: Boolean = false\n ) {\n event(slug: $eventSlug) {\n name\n slug\n\n tickets {\n products {\n ...ProductChoice\n }\n\n orders(filters: $filters, search: $search, returnNone: $returnNone) {\n ...OrderList\n }\n\n countTotalOrders\n }\n }\n }\n": typeof types.AdminOrderListWithOrdersDocument, "\n mutation CancelOwnOrder($input: CancelOwnUnpaidOrderInput!) {\n cancelOwnUnpaidOrder(input: $input) {\n order {\n id\n }\n }\n }\n": typeof types.CancelOwnOrderDocument, + "\n mutation RequestOrderCancellation($input: RequestOrderCancellationInput!) {\n requestOrderCancellation(input: $input) {\n success\n }\n }\n": typeof types.RequestOrderCancellationDocument, + "\n mutation ConfirmOrderCancellation($input: ConfirmOrderCancellationInput!) {\n confirmOrderCancellation(input: $input) {\n success\n }\n }\n": typeof types.ConfirmOrderCancellationDocument, "\n fragment InvolvedPersonDetailInvolvement on LimitedInvolvementType {\n id\n type\n title\n adminLink\n isActive\n cachedDimensions\n cachedAnnotations\n }\n": typeof types.InvolvedPersonDetailInvolvementFragmentDoc, "\n fragment InvolvedPersonDetail on ProfileWithInvolvementType {\n id\n firstName\n lastName\n nick\n email\n phoneNumber\n discordHandle\n fullName\n\n profileFieldSelector {\n ...FullProfileFieldSelector\n }\n\n isActive\n\n involvements {\n ...InvolvedPersonDetailInvolvement\n }\n }\n": typeof types.InvolvedPersonDetailFragmentDoc, "\n query PersonPage($eventSlug: String!, $locale: String, $personId: Int!) {\n event(slug: $eventSlug) {\n slug\n name\n timezone\n\n involvement {\n dimensions(publicOnly: false) {\n ...CachedDimensionsBadges\n ...DimensionValueSelect\n\n isKeyDimension\n isShownInDetail\n }\n\n annotations(publicOnly: false, perksOnly: true) {\n ...AnnotationsFormAnnotation\n }\n\n person(id: $personId) {\n ...InvolvedPersonDetail\n }\n }\n }\n }\n": typeof types.PersonPageDocument, @@ -175,12 +177,14 @@ type Documents = { "\n fragment Survey on FullSurveyType {\n slug\n title(lang: $locale)\n isActive\n activeFrom\n activeUntil\n countResponses\n\n languages {\n language\n }\n }\n": typeof types.SurveyFragmentDoc, "\n fragment ProfileSurvey on FullSurveyType {\n event {\n slug\n name\n }\n slug\n title(lang: $locale)\n }\n": typeof types.ProfileSurveyFragmentDoc, "\n query Surveys($eventSlug: String!, $locale: String) {\n profile {\n forms {\n surveys(relation: ACCESSIBLE) {\n ...ProfileSurvey\n }\n }\n }\n\n event(slug: $eventSlug) {\n name\n\n forms {\n surveys(includeInactive: true, app: FORMS) {\n ...Survey\n }\n }\n }\n }\n": typeof types.SurveysDocument, + "\n mutation UpdateTicketsPreferences($input: UpdateTicketsPreferencesInput!) {\n updateTicketsPreferences(input: $input) {\n preferences {\n contactEmail\n termsAndConditionsUrlEn\n termsAndConditionsUrlFi\n termsAndConditionsUrlSv\n cancellationPeriodDays\n }\n }\n }\n": typeof types.UpdateTicketsPreferencesDocument, + "\n query TicketsPreferences($eventSlug: String!) {\n event(slug: $eventSlug) {\n name\n slug\n\n tickets {\n contactEmail\n termsAndConditionsUrlEn\n termsAndConditionsUrlFi\n termsAndConditionsUrlSv\n cancellationPeriodDays\n }\n }\n }\n": typeof types.TicketsPreferencesDocument, "\n query TicketsAdminReportsPage($eventSlug: String!, $locale: String) {\n event(slug: $eventSlug) {\n name\n slug\n timezone\n\n tickets {\n reports(lang: $locale) {\n ...Report\n }\n }\n }\n }\n": typeof types.TicketsAdminReportsPageDocument, "\n mutation GenerateKeyPair($password: String!) {\n generateKeyPair(password: $password) {\n id\n }\n }\n": typeof types.GenerateKeyPairDocument, "\n mutation RevokeKeyPair($id: String!) {\n revokeKeyPair(id: $id) {\n id\n }\n }\n": typeof types.RevokeKeyPairDocument, "\n fragment ProfileEncryptionKeys on KeyPairType {\n id\n createdAt\n }\n": typeof types.ProfileEncryptionKeysFragmentDoc, "\n query ProfileEncryptionKeys {\n profile {\n keypairs {\n ...ProfileEncryptionKeys\n }\n }\n }\n": typeof types.ProfileEncryptionKeysDocument, - "\n query ProfileOrderDetail($eventSlug: String!, $orderId: String!) {\n profile {\n tickets {\n order(eventSlug: $eventSlug, id: $orderId) {\n id\n formattedOrderNumber\n createdAt\n totalPrice\n status\n eticketsLink\n canPay\n canCancel\n ticketsContactEmail\n products {\n title\n quantity\n price\n vatPercentage\n }\n\n event {\n slug\n name\n organization {\n name\n businessId\n }\n }\n }\n }\n }\n }\n": typeof types.ProfileOrderDetailDocument, + "\n query ProfileOrderDetail($eventSlug: String!, $orderId: String!) {\n profile {\n tickets {\n order(eventSlug: $eventSlug, id: $orderId) {\n id\n formattedOrderNumber\n createdAt\n totalPrice\n status\n eticketsLink\n canPay\n canCancel\n canRequestCancellation\n ticketsContactEmail\n products {\n title\n quantity\n price\n vatPercentage\n }\n\n event {\n slug\n name\n organization {\n name\n businessId\n }\n }\n }\n }\n }\n }\n": typeof types.ProfileOrderDetailDocument, "\n mutation ConfirmEmail($input: ConfirmEmailInput!) {\n confirmEmail(input: $input) {\n user {\n email\n }\n }\n }\n": typeof types.ConfirmEmailDocument, "\n fragment ProfileOrder on ProfileOrderType {\n id\n formattedOrderNumber\n createdAt\n totalPrice\n status\n eticketsLink\n canPay\n canCancel\n\n event {\n slug\n name\n }\n }\n": typeof types.ProfileOrderFragmentDoc, "\n query ProfileOrders {\n profile {\n tickets {\n orders {\n ...ProfileOrder\n }\n\n haveUnlinkedOrders\n }\n }\n }\n": typeof types.ProfileOrdersDocument, @@ -243,6 +247,8 @@ const documents: Documents = { "\n fragment ProductChoice on FullProductType {\n id\n title\n }\n": types.ProductChoiceFragmentDoc, "\n query AdminOrderListWithOrders(\n $eventSlug: String!\n $filters: [DimensionFilterInput!]\n $search: String\n $returnNone: Boolean = false\n ) {\n event(slug: $eventSlug) {\n name\n slug\n\n tickets {\n products {\n ...ProductChoice\n }\n\n orders(filters: $filters, search: $search, returnNone: $returnNone) {\n ...OrderList\n }\n\n countTotalOrders\n }\n }\n }\n": types.AdminOrderListWithOrdersDocument, "\n mutation CancelOwnOrder($input: CancelOwnUnpaidOrderInput!) {\n cancelOwnUnpaidOrder(input: $input) {\n order {\n id\n }\n }\n }\n": types.CancelOwnOrderDocument, + "\n mutation RequestOrderCancellation($input: RequestOrderCancellationInput!) {\n requestOrderCancellation(input: $input) {\n success\n }\n }\n": types.RequestOrderCancellationDocument, + "\n mutation ConfirmOrderCancellation($input: ConfirmOrderCancellationInput!) {\n confirmOrderCancellation(input: $input) {\n success\n }\n }\n": types.ConfirmOrderCancellationDocument, "\n fragment InvolvedPersonDetailInvolvement on LimitedInvolvementType {\n id\n type\n title\n adminLink\n isActive\n cachedDimensions\n cachedAnnotations\n }\n": types.InvolvedPersonDetailInvolvementFragmentDoc, "\n fragment InvolvedPersonDetail on ProfileWithInvolvementType {\n id\n firstName\n lastName\n nick\n email\n phoneNumber\n discordHandle\n fullName\n\n profileFieldSelector {\n ...FullProfileFieldSelector\n }\n\n isActive\n\n involvements {\n ...InvolvedPersonDetailInvolvement\n }\n }\n": types.InvolvedPersonDetailFragmentDoc, "\n query PersonPage($eventSlug: String!, $locale: String, $personId: Int!) {\n event(slug: $eventSlug) {\n slug\n name\n timezone\n\n involvement {\n dimensions(publicOnly: false) {\n ...CachedDimensionsBadges\n ...DimensionValueSelect\n\n isKeyDimension\n isShownInDetail\n }\n\n annotations(publicOnly: false, perksOnly: true) {\n ...AnnotationsFormAnnotation\n }\n\n person(id: $personId) {\n ...InvolvedPersonDetail\n }\n }\n }\n }\n": types.PersonPageDocument, @@ -374,12 +380,14 @@ const documents: Documents = { "\n fragment Survey on FullSurveyType {\n slug\n title(lang: $locale)\n isActive\n activeFrom\n activeUntil\n countResponses\n\n languages {\n language\n }\n }\n": types.SurveyFragmentDoc, "\n fragment ProfileSurvey on FullSurveyType {\n event {\n slug\n name\n }\n slug\n title(lang: $locale)\n }\n": types.ProfileSurveyFragmentDoc, "\n query Surveys($eventSlug: String!, $locale: String) {\n profile {\n forms {\n surveys(relation: ACCESSIBLE) {\n ...ProfileSurvey\n }\n }\n }\n\n event(slug: $eventSlug) {\n name\n\n forms {\n surveys(includeInactive: true, app: FORMS) {\n ...Survey\n }\n }\n }\n }\n": types.SurveysDocument, + "\n mutation UpdateTicketsPreferences($input: UpdateTicketsPreferencesInput!) {\n updateTicketsPreferences(input: $input) {\n preferences {\n contactEmail\n termsAndConditionsUrlEn\n termsAndConditionsUrlFi\n termsAndConditionsUrlSv\n cancellationPeriodDays\n }\n }\n }\n": types.UpdateTicketsPreferencesDocument, + "\n query TicketsPreferences($eventSlug: String!) {\n event(slug: $eventSlug) {\n name\n slug\n\n tickets {\n contactEmail\n termsAndConditionsUrlEn\n termsAndConditionsUrlFi\n termsAndConditionsUrlSv\n cancellationPeriodDays\n }\n }\n }\n": types.TicketsPreferencesDocument, "\n query TicketsAdminReportsPage($eventSlug: String!, $locale: String) {\n event(slug: $eventSlug) {\n name\n slug\n timezone\n\n tickets {\n reports(lang: $locale) {\n ...Report\n }\n }\n }\n }\n": types.TicketsAdminReportsPageDocument, "\n mutation GenerateKeyPair($password: String!) {\n generateKeyPair(password: $password) {\n id\n }\n }\n": types.GenerateKeyPairDocument, "\n mutation RevokeKeyPair($id: String!) {\n revokeKeyPair(id: $id) {\n id\n }\n }\n": types.RevokeKeyPairDocument, "\n fragment ProfileEncryptionKeys on KeyPairType {\n id\n createdAt\n }\n": types.ProfileEncryptionKeysFragmentDoc, "\n query ProfileEncryptionKeys {\n profile {\n keypairs {\n ...ProfileEncryptionKeys\n }\n }\n }\n": types.ProfileEncryptionKeysDocument, - "\n query ProfileOrderDetail($eventSlug: String!, $orderId: String!) {\n profile {\n tickets {\n order(eventSlug: $eventSlug, id: $orderId) {\n id\n formattedOrderNumber\n createdAt\n totalPrice\n status\n eticketsLink\n canPay\n canCancel\n ticketsContactEmail\n products {\n title\n quantity\n price\n vatPercentage\n }\n\n event {\n slug\n name\n organization {\n name\n businessId\n }\n }\n }\n }\n }\n }\n": types.ProfileOrderDetailDocument, + "\n query ProfileOrderDetail($eventSlug: String!, $orderId: String!) {\n profile {\n tickets {\n order(eventSlug: $eventSlug, id: $orderId) {\n id\n formattedOrderNumber\n createdAt\n totalPrice\n status\n eticketsLink\n canPay\n canCancel\n canRequestCancellation\n ticketsContactEmail\n products {\n title\n quantity\n price\n vatPercentage\n }\n\n event {\n slug\n name\n organization {\n name\n businessId\n }\n }\n }\n }\n }\n }\n": types.ProfileOrderDetailDocument, "\n mutation ConfirmEmail($input: ConfirmEmailInput!) {\n confirmEmail(input: $input) {\n user {\n email\n }\n }\n }\n": types.ConfirmEmailDocument, "\n fragment ProfileOrder on ProfileOrderType {\n id\n formattedOrderNumber\n createdAt\n totalPrice\n status\n eticketsLink\n canPay\n canCancel\n\n event {\n slug\n name\n }\n }\n": types.ProfileOrderFragmentDoc, "\n query ProfileOrders {\n profile {\n tickets {\n orders {\n ...ProfileOrder\n }\n\n haveUnlinkedOrders\n }\n }\n }\n": types.ProfileOrdersDocument, @@ -546,6 +554,14 @@ export function graphql(source: "\n query AdminOrderListWithOrders(\n $event * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ export function graphql(source: "\n mutation CancelOwnOrder($input: CancelOwnUnpaidOrderInput!) {\n cancelOwnUnpaidOrder(input: $input) {\n order {\n id\n }\n }\n }\n"): (typeof documents)["\n mutation CancelOwnOrder($input: CancelOwnUnpaidOrderInput!) {\n cancelOwnUnpaidOrder(input: $input) {\n order {\n id\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: "\n mutation RequestOrderCancellation($input: RequestOrderCancellationInput!) {\n requestOrderCancellation(input: $input) {\n success\n }\n }\n"): (typeof documents)["\n mutation RequestOrderCancellation($input: RequestOrderCancellationInput!) {\n requestOrderCancellation(input: $input) {\n success\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: "\n mutation ConfirmOrderCancellation($input: ConfirmOrderCancellationInput!) {\n confirmOrderCancellation(input: $input) {\n success\n }\n }\n"): (typeof documents)["\n mutation ConfirmOrderCancellation($input: ConfirmOrderCancellationInput!) {\n confirmOrderCancellation(input: $input) {\n success\n }\n }\n"]; /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ @@ -1070,6 +1086,14 @@ export function graphql(source: "\n fragment ProfileSurvey on FullSurveyType {\ * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ export function graphql(source: "\n query Surveys($eventSlug: String!, $locale: String) {\n profile {\n forms {\n surveys(relation: ACCESSIBLE) {\n ...ProfileSurvey\n }\n }\n }\n\n event(slug: $eventSlug) {\n name\n\n forms {\n surveys(includeInactive: true, app: FORMS) {\n ...Survey\n }\n }\n }\n }\n"): (typeof documents)["\n query Surveys($eventSlug: String!, $locale: String) {\n profile {\n forms {\n surveys(relation: ACCESSIBLE) {\n ...ProfileSurvey\n }\n }\n }\n\n event(slug: $eventSlug) {\n name\n\n forms {\n surveys(includeInactive: true, app: FORMS) {\n ...Survey\n }\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: "\n mutation UpdateTicketsPreferences($input: UpdateTicketsPreferencesInput!) {\n updateTicketsPreferences(input: $input) {\n preferences {\n contactEmail\n termsAndConditionsUrlEn\n termsAndConditionsUrlFi\n termsAndConditionsUrlSv\n cancellationPeriodDays\n }\n }\n }\n"): (typeof documents)["\n mutation UpdateTicketsPreferences($input: UpdateTicketsPreferencesInput!) {\n updateTicketsPreferences(input: $input) {\n preferences {\n contactEmail\n termsAndConditionsUrlEn\n termsAndConditionsUrlFi\n termsAndConditionsUrlSv\n cancellationPeriodDays\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: "\n query TicketsPreferences($eventSlug: String!) {\n event(slug: $eventSlug) {\n name\n slug\n\n tickets {\n contactEmail\n termsAndConditionsUrlEn\n termsAndConditionsUrlFi\n termsAndConditionsUrlSv\n cancellationPeriodDays\n }\n }\n }\n"): (typeof documents)["\n query TicketsPreferences($eventSlug: String!) {\n event(slug: $eventSlug) {\n name\n slug\n\n tickets {\n contactEmail\n termsAndConditionsUrlEn\n termsAndConditionsUrlFi\n termsAndConditionsUrlSv\n cancellationPeriodDays\n }\n }\n }\n"]; /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ @@ -1093,7 +1117,7 @@ export function graphql(source: "\n query ProfileEncryptionKeys {\n profile /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ -export function graphql(source: "\n query ProfileOrderDetail($eventSlug: String!, $orderId: String!) {\n profile {\n tickets {\n order(eventSlug: $eventSlug, id: $orderId) {\n id\n formattedOrderNumber\n createdAt\n totalPrice\n status\n eticketsLink\n canPay\n canCancel\n ticketsContactEmail\n products {\n title\n quantity\n price\n vatPercentage\n }\n\n event {\n slug\n name\n organization {\n name\n businessId\n }\n }\n }\n }\n }\n }\n"): (typeof documents)["\n query ProfileOrderDetail($eventSlug: String!, $orderId: String!) {\n profile {\n tickets {\n order(eventSlug: $eventSlug, id: $orderId) {\n id\n formattedOrderNumber\n createdAt\n totalPrice\n status\n eticketsLink\n canPay\n canCancel\n ticketsContactEmail\n products {\n title\n quantity\n price\n vatPercentage\n }\n\n event {\n slug\n name\n organization {\n name\n businessId\n }\n }\n }\n }\n }\n }\n"]; +export function graphql(source: "\n query ProfileOrderDetail($eventSlug: String!, $orderId: String!) {\n profile {\n tickets {\n order(eventSlug: $eventSlug, id: $orderId) {\n id\n formattedOrderNumber\n createdAt\n totalPrice\n status\n eticketsLink\n canPay\n canCancel\n canRequestCancellation\n ticketsContactEmail\n products {\n title\n quantity\n price\n vatPercentage\n }\n\n event {\n slug\n name\n organization {\n name\n businessId\n }\n }\n }\n }\n }\n }\n"): (typeof documents)["\n query ProfileOrderDetail($eventSlug: String!, $orderId: String!) {\n profile {\n tickets {\n order(eventSlug: $eventSlug, id: $orderId) {\n id\n formattedOrderNumber\n createdAt\n totalPrice\n status\n eticketsLink\n canPay\n canCancel\n canRequestCancellation\n ticketsContactEmail\n products {\n title\n quantity\n price\n vatPercentage\n }\n\n event {\n slug\n name\n organization {\n name\n businessId\n }\n }\n }\n }\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/kompassi-v2-frontend/src/__generated__/graphql.ts b/kompassi-v2-frontend/src/__generated__/graphql.ts index 791117428..0cbf7800e 100644 --- a/kompassi-v2-frontend/src/__generated__/graphql.ts +++ b/kompassi-v2-frontend/src/__generated__/graphql.ts @@ -187,6 +187,31 @@ export type ConfirmEmailInput = { locale: Scalars['String']['input']; }; +/** + * Customer self-service cancellation, step 2 of 2: consume the one-time code + * from the confirmation email and cancel the order, initiating an automated + * refund via the payment provider if money was paid. + * + * May be called without authentication: the one-time code proves control of + * the email address of the order. + * + * If the provider refund request fails after the code is consumed, the order + * is left in REFUND_FAILED state for ticket sales to resolve with the + * existing admin refund tooling. + * + * NOTE: Must not return any PII (the caller may be anonymous). + */ +export type ConfirmOrderCancellation = { + __typename?: 'ConfirmOrderCancellation'; + success: Scalars['Boolean']['output']; +}; + +export type ConfirmOrderCancellationInput = { + code: Scalars['String']['input']; + eventSlug: Scalars['String']['input']; + orderId: Scalars['String']['input']; +}; + export type CreateOrder = { __typename?: 'CreateOrder'; order?: Maybe; @@ -1573,6 +1598,21 @@ export type Mutation = { cancelProgram?: Maybe; cancelProgramOffer?: Maybe; confirmEmail?: Maybe; + /** + * Customer self-service cancellation, step 2 of 2: consume the one-time code + * from the confirmation email and cancel the order, initiating an automated + * refund via the payment provider if money was paid. + * + * May be called without authentication: the one-time code proves control of + * the email address of the order. + * + * If the provider refund request fails after the code is consumed, the order + * is left in REFUND_FAILED state for ticket sales to resolve with the + * existing admin refund tooling. + * + * NOTE: Must not return any PII (the caller may be anonymous). + */ + confirmOrderCancellation?: Maybe; createOrder?: Maybe; createProduct?: Maybe; createProgram?: Maybe; @@ -1612,6 +1652,17 @@ export type Mutation = { putScheduleItem?: Maybe; putUniverseAnnotation?: Maybe; reorderProducts?: Maybe; + /** + * Customer self-service cancellation, step 1 of 2: send a confirmation link + * to the email address of the order. + * + * May be called without authentication: possession of the order UUID is considered + * sufficient proof of being party to the order (same trust model as the anonymous + * order page), and the confirmation email closes the loop. + * + * NOTE: Must not return any PII (the caller may be anonymous). + */ + requestOrderCancellation?: Maybe; resendInvitation?: Maybe; resendOrderConfirmation?: Maybe; /** Restore a program item that was previously cancelled. */ @@ -1637,6 +1688,11 @@ export type Mutation = { updateResponseDimensions?: Maybe; updateSurvey?: Maybe; updateSurveyDefaultDimensions?: Maybe; + /** + * Updates the tickets settings that are exposed to event admins. + * NOTE: provider_id is deliberately not settable here (super admin only). + */ + updateTicketsPreferences?: Maybe; }; @@ -1675,6 +1731,11 @@ export type MutationConfirmEmailArgs = { }; +export type MutationConfirmOrderCancellationArgs = { + input: ConfirmOrderCancellationInput; +}; + + export type MutationCreateOrderArgs = { input: CreateOrderInput; }; @@ -1835,6 +1896,11 @@ export type MutationReorderProductsArgs = { }; +export type MutationRequestOrderCancellationArgs = { + input: RequestOrderCancellationInput; +}; + + export type MutationResendInvitationArgs = { input: ResendInvitationInput; }; @@ -1949,6 +2015,11 @@ export type MutationUpdateSurveyDefaultDimensionsArgs = { input: UpdateSurveyDefaultDimensionsInput; }; + +export type MutationUpdateTicketsPreferencesArgs = { + input: UpdateTicketsPreferencesInput; +}; + export type OrderProductInput = { productId: Scalars['Int']['input']; quantity: Scalars['Int']['input']; @@ -2042,6 +2113,10 @@ export type ProfileOrderType = { __typename?: 'ProfileOrderType'; canCancel: Scalars['Boolean']['output']; canPay: Scalars['Boolean']['output']; + /** Returns true if the customer can cancel this order themselves via the email confirmed cancellation flow. */ + canRequestCancellation: Scalars['Boolean']['output']; + /** The customer may cancel their order themselves until this deadline. Null if customer self-service cancellation is not enabled for the event. */ + cancellationDeadline?: Maybe; createdAt: Scalars['DateTime']['output']; displayName: Scalars['String']['output']; email: Scalars['String']['output']; @@ -2544,6 +2619,26 @@ export type ReportTypeTitleArgs = { lang?: InputMaybe; }; +/** + * Customer self-service cancellation, step 1 of 2: send a confirmation link + * to the email address of the order. + * + * May be called without authentication: possession of the order UUID is considered + * sufficient proof of being party to the order (same trust model as the anonymous + * order page), and the confirmation email closes the loop. + * + * NOTE: Must not return any PII (the caller may be anonymous). + */ +export type RequestOrderCancellation = { + __typename?: 'RequestOrderCancellation'; + success: Scalars['Boolean']['output']; +}; + +export type RequestOrderCancellationInput = { + eventSlug: Scalars['String']['input']; + orderId: Scalars['String']['input']; +}; + export type ResendInvitation = { __typename?: 'ResendInvitation'; invitation?: Maybe; @@ -2647,6 +2742,10 @@ export enum SurveyRelation { export type TicketsV2EventMetaType = { __typename?: 'TicketsV2EventMetaType'; + /** Number of days from order creation during which the customer can cancel a paid order themselves. The period is further capped at event start. 0 = customer self-service cancellation disabled. */ + cancellationPeriodDays: Scalars['Int']['output']; + /** Foo Bar <foo.bar@example.com> */ + contactEmail: Scalars['String']['output']; /** Returns the total number of orders made to this event. Admin oriented view; customers will access order information through `profile.tickets`. */ countTotalOrders: Scalars['Int']['output']; /** Returns orders made to this event. Admin oriented view; customers will access order information through `profile.tickets`. */ @@ -2665,6 +2764,9 @@ export type TicketsV2EventMetaType = { report?: Maybe; /** Get all the reports. */ reports: Array; + termsAndConditionsUrlEn: Scalars['String']['output']; + termsAndConditionsUrlFi: Scalars['String']['output']; + termsAndConditionsUrlSv: Scalars['String']['output']; }; @@ -2928,6 +3030,24 @@ export type UpdateSurveyInput = { surveySlug: Scalars['String']['input']; }; +/** + * Updates the tickets settings that are exposed to event admins. + * NOTE: provider_id is deliberately not settable here (super admin only). + */ +export type UpdateTicketsPreferences = { + __typename?: 'UpdateTicketsPreferences'; + preferences?: Maybe; +}; + +export type UpdateTicketsPreferencesInput = { + cancellationPeriodDays?: InputMaybe; + contactEmail?: InputMaybe; + eventSlug: Scalars['String']['input']; + termsAndConditionsUrlEn?: InputMaybe; + termsAndConditionsUrlFi?: InputMaybe; + termsAndConditionsUrlSv?: InputMaybe; +}; + export type CreateSurveyResponseMutationVariables = Exact<{ input: CreateSurveyResponseInput; }>; @@ -3115,6 +3235,20 @@ export type CancelOwnOrderMutationVariables = Exact<{ export type CancelOwnOrderMutation = { __typename?: 'Mutation', cancelOwnUnpaidOrder?: { __typename?: 'CancelOwnUnpaidOrder', order?: { __typename?: 'LimitedOrderType', id: string } | null } | null }; +export type RequestOrderCancellationMutationVariables = Exact<{ + input: RequestOrderCancellationInput; +}>; + + +export type RequestOrderCancellationMutation = { __typename?: 'Mutation', requestOrderCancellation?: { __typename?: 'RequestOrderCancellation', success: boolean } | null }; + +export type ConfirmOrderCancellationMutationVariables = Exact<{ + input: ConfirmOrderCancellationInput; +}>; + + +export type ConfirmOrderCancellationMutation = { __typename?: 'Mutation', confirmOrderCancellation?: { __typename?: 'ConfirmOrderCancellation', success: boolean } | null }; + export type InvolvedPersonDetailInvolvementFragment = { __typename?: 'LimitedInvolvementType', id: string, type: InvolvementType, title: string, adminLink?: string | null, isActive: boolean, cachedDimensions: unknown, cachedAnnotations: unknown }; export type InvolvedPersonDetailFragment = { __typename?: 'ProfileWithInvolvementType', id: number, firstName: string, lastName: string, nick: string, email: string, phoneNumber: string, discordHandle: string, fullName: string, isActive: boolean, profileFieldSelector: { __typename?: 'ProfileFieldSelectorType', firstName: boolean, lastName: boolean, nick: boolean, email: boolean, phoneNumber: boolean, discordHandle: boolean }, involvements: Array<{ __typename?: 'LimitedInvolvementType', id: string, type: InvolvementType, title: string, adminLink?: string | null, isActive: boolean, cachedDimensions: unknown, cachedAnnotations: unknown }> }; @@ -3934,6 +4068,20 @@ export type SurveysQueryVariables = Exact<{ export type SurveysQuery = { __typename?: 'Query', profile?: { __typename?: 'OwnProfileType', forms: { __typename?: 'FormsProfileMetaType', surveys: Array<{ __typename?: 'FullSurveyType', slug: string, title?: string | null, event: { __typename?: 'LimitedEventType', slug: string, name: string } }> } } | null, event?: { __typename?: 'FullEventType', name: string, forms?: { __typename?: 'FormsEventMetaType', surveys: Array<{ __typename?: 'FullSurveyType', slug: string, title?: string | null, isActive: boolean, activeFrom?: string | null, activeUntil?: string | null, countResponses: number, languages: Array<{ __typename?: 'FormType', language: FormsFormLanguageChoices }> }> } | null } | null }; +export type UpdateTicketsPreferencesMutationVariables = Exact<{ + input: UpdateTicketsPreferencesInput; +}>; + + +export type UpdateTicketsPreferencesMutation = { __typename?: 'Mutation', updateTicketsPreferences?: { __typename?: 'UpdateTicketsPreferences', preferences?: { __typename?: 'TicketsV2EventMetaType', contactEmail: string, termsAndConditionsUrlEn: string, termsAndConditionsUrlFi: string, termsAndConditionsUrlSv: string, cancellationPeriodDays: number } | null } | null }; + +export type TicketsPreferencesQueryVariables = Exact<{ + eventSlug: Scalars['String']['input']; +}>; + + +export type TicketsPreferencesQuery = { __typename?: 'Query', event?: { __typename?: 'FullEventType', name: string, slug: string, tickets?: { __typename?: 'TicketsV2EventMetaType', contactEmail: string, termsAndConditionsUrlEn: string, termsAndConditionsUrlFi: string, termsAndConditionsUrlSv: string, cancellationPeriodDays: number } | null } | null }; + export type TicketsAdminReportsPageQueryVariables = Exact<{ eventSlug: Scalars['String']['input']; locale?: InputMaybe; @@ -3969,7 +4117,7 @@ export type ProfileOrderDetailQueryVariables = Exact<{ }>; -export type ProfileOrderDetailQuery = { __typename?: 'Query', profile?: { __typename?: 'OwnProfileType', tickets: { __typename?: 'TicketsV2ProfileMetaType', order?: { __typename?: 'ProfileOrderType', id: string, formattedOrderNumber: string, createdAt: string, totalPrice: any, status: PaymentStatus, eticketsLink?: string | null, canPay: boolean, canCancel: boolean, ticketsContactEmail: string, products: Array<{ __typename?: 'OrderProductType', title: string, quantity: number, price: any, vatPercentage: any }>, event: { __typename?: 'LimitedEventType', slug: string, name: string, organization: { __typename?: 'LimitedOrganizationType', name: string, businessId: string } } } | null } } | null }; +export type ProfileOrderDetailQuery = { __typename?: 'Query', profile?: { __typename?: 'OwnProfileType', tickets: { __typename?: 'TicketsV2ProfileMetaType', order?: { __typename?: 'ProfileOrderType', id: string, formattedOrderNumber: string, createdAt: string, totalPrice: any, status: PaymentStatus, eticketsLink?: string | null, canPay: boolean, canCancel: boolean, canRequestCancellation: boolean, ticketsContactEmail: string, products: Array<{ __typename?: 'OrderProductType', title: string, quantity: number, price: any, vatPercentage: any }>, event: { __typename?: 'LimitedEventType', slug: string, name: string, organization: { __typename?: 'LimitedOrganizationType', name: string, businessId: string } } } | null } } | null }; export type ConfirmEmailMutationVariables = Exact<{ input: ConfirmEmailInput; @@ -4161,6 +4309,8 @@ export const AdminCreateOrderDocument = {"kind":"Document","definitions":[{"kind export const NewOrderPageDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"NewOrderPage"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"eventSlug"}},"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":"slug"},"value":{"kind":"Variable","name":{"kind":"Name","value":"eventSlug"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"tickets"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"products"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"NewOrderProduct"}}]}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"NewOrderProduct"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"FullProductType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"price"}},{"kind":"Field","name":{"kind":"Name","value":"vatPercentage"}},{"kind":"Field","name":{"kind":"Name","value":"isAvailable"}},{"kind":"Field","name":{"kind":"Name","value":"availableFrom"}},{"kind":"Field","name":{"kind":"Name","value":"availableUntil"}},{"kind":"Field","name":{"kind":"Name","value":"countPaid"}},{"kind":"Field","name":{"kind":"Name","value":"countReserved"}},{"kind":"Field","name":{"kind":"Name","value":"countAvailable"}},{"kind":"Field","name":{"kind":"Name","value":"maxPerOrder"}}]}}]} as unknown as DocumentNode; export const AdminOrderListWithOrdersDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"AdminOrderListWithOrders"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"eventSlug"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"filters"}},"type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"DimensionFilterInput"}}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"search"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"returnNone"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}},"defaultValue":{"kind":"BooleanValue","value":false}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"event"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"slug"},"value":{"kind":"Variable","name":{"kind":"Name","value":"eventSlug"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"tickets"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"products"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProductChoice"}}]}},{"kind":"Field","name":{"kind":"Name","value":"orders"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"filters"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filters"}}},{"kind":"Argument","name":{"kind":"Name","value":"search"},"value":{"kind":"Variable","name":{"kind":"Name","value":"search"}}},{"kind":"Argument","name":{"kind":"Name","value":"returnNone"},"value":{"kind":"Variable","name":{"kind":"Name","value":"returnNone"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"OrderList"}}]}},{"kind":"Field","name":{"kind":"Name","value":"countTotalOrders"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProductChoice"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"FullProductType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"title"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"OrderList"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"FullOrderType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"formattedOrderNumber"}},{"kind":"Field","name":{"kind":"Name","value":"displayName"}},{"kind":"Field","name":{"kind":"Name","value":"email"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"totalPrice"}},{"kind":"Field","name":{"kind":"Name","value":"status"}}]}}]} as unknown as DocumentNode; export const CancelOwnOrderDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CancelOwnOrder"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"CancelOwnUnpaidOrderInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"cancelOwnUnpaidOrder"},"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":"order"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}}]} as unknown as DocumentNode; +export const RequestOrderCancellationDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"RequestOrderCancellation"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"RequestOrderCancellationInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"requestOrderCancellation"},"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":"success"}}]}}]}}]} as unknown as DocumentNode; +export const ConfirmOrderCancellationDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"ConfirmOrderCancellation"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ConfirmOrderCancellationInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"confirmOrderCancellation"},"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":"success"}}]}}]}}]} as unknown as DocumentNode; export const PersonPageDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"PersonPage"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"eventSlug"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"locale"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"personId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"event"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"slug"},"value":{"kind":"Variable","name":{"kind":"Name","value":"eventSlug"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"timezone"}},{"kind":"Field","name":{"kind":"Name","value":"involvement"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"dimensions"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"publicOnly"},"value":{"kind":"BooleanValue","value":false}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CachedDimensionsBadges"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"DimensionValueSelect"}},{"kind":"Field","name":{"kind":"Name","value":"isKeyDimension"}},{"kind":"Field","name":{"kind":"Name","value":"isShownInDetail"}}]}},{"kind":"Field","name":{"kind":"Name","value":"annotations"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"publicOnly"},"value":{"kind":"BooleanValue","value":false}},{"kind":"Argument","name":{"kind":"Name","value":"perksOnly"},"value":{"kind":"BooleanValue","value":true}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"AnnotationsFormAnnotation"}}]}},{"kind":"Field","name":{"kind":"Name","value":"person"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"personId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"InvolvedPersonDetail"}}]}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"FullProfileFieldSelector"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"ProfileFieldSelectorType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}},{"kind":"Field","name":{"kind":"Name","value":"nick"}},{"kind":"Field","name":{"kind":"Name","value":"email"}},{"kind":"Field","name":{"kind":"Name","value":"phoneNumber"}},{"kind":"Field","name":{"kind":"Name","value":"discordHandle"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"InvolvedPersonDetailInvolvement"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"LimitedInvolvementType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"adminLink"}},{"kind":"Field","name":{"kind":"Name","value":"isActive"}},{"kind":"Field","name":{"kind":"Name","value":"cachedDimensions"}},{"kind":"Field","name":{"kind":"Name","value":"cachedAnnotations"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"CachedDimensionsBadges"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"FullDimensionType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}}]},{"kind":"Field","name":{"kind":"Name","value":"values"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}}]},{"kind":"Field","name":{"kind":"Name","value":"color"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"DimensionValueSelect"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"FullDimensionType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}}]},{"kind":"Field","name":{"kind":"Name","value":"isTechnical"}},{"kind":"Field","name":{"kind":"Name","value":"isMultiValue"}},{"kind":"Field","name":{"kind":"Name","value":"values"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}}]}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"AnnotationsFormAnnotation"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"AnnotationType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}}]},{"kind":"Field","name":{"kind":"Name","value":"description"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}}]},{"kind":"Field","name":{"kind":"Name","value":"isComputed"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"InvolvedPersonDetail"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"ProfileWithInvolvementType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}},{"kind":"Field","name":{"kind":"Name","value":"nick"}},{"kind":"Field","name":{"kind":"Name","value":"email"}},{"kind":"Field","name":{"kind":"Name","value":"phoneNumber"}},{"kind":"Field","name":{"kind":"Name","value":"discordHandle"}},{"kind":"Field","name":{"kind":"Name","value":"fullName"}},{"kind":"Field","name":{"kind":"Name","value":"profileFieldSelector"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"FullProfileFieldSelector"}}]}},{"kind":"Field","name":{"kind":"Name","value":"isActive"}},{"kind":"Field","name":{"kind":"Name","value":"involvements"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"InvolvedPersonDetailInvolvement"}}]}}]}}]} as unknown as DocumentNode; export const PeoplePageDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"PeoplePage"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"eventSlug"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"filters"}},"type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"DimensionFilterInput"}}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"locale"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"search"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"returnNone"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}},"defaultValue":{"kind":"BooleanValue","value":false}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"event"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"slug"},"value":{"kind":"Variable","name":{"kind":"Name","value":"eventSlug"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"timezone"}},{"kind":"Field","name":{"kind":"Name","value":"involvement"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"dimensions"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"publicOnly"},"value":{"kind":"BooleanValue","value":false}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"DimensionFilter"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"CachedDimensionsBadges"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"DimensionValueSelect"}}]}},{"kind":"Field","name":{"kind":"Name","value":"people"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"filters"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filters"}}},{"kind":"Argument","name":{"kind":"Name","value":"search"},"value":{"kind":"Variable","name":{"kind":"Name","value":"search"}}},{"kind":"Argument","name":{"kind":"Name","value":"returnNone"},"value":{"kind":"Variable","name":{"kind":"Name","value":"returnNone"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"InvolvedPerson"}}]}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"DimensionFilterValue"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"DimensionValueType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}}]}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"InvolvedPersonInvolvement"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"LimitedInvolvementType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"adminLink"}},{"kind":"Field","name":{"kind":"Name","value":"isActive"}},{"kind":"Field","name":{"kind":"Name","value":"cachedDimensions"}},{"kind":"Field","name":{"kind":"Name","value":"cachedAnnotations"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"DimensionFilter"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"FullDimensionType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}}]},{"kind":"Field","name":{"kind":"Name","value":"isMultiValue"}},{"kind":"Field","name":{"kind":"Name","value":"isListFilter"}},{"kind":"Field","name":{"kind":"Name","value":"isKeyDimension"}},{"kind":"Field","name":{"kind":"Name","value":"values"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"DimensionFilterValue"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"CachedDimensionsBadges"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"FullDimensionType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}}]},{"kind":"Field","name":{"kind":"Name","value":"values"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}}]},{"kind":"Field","name":{"kind":"Name","value":"color"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"DimensionValueSelect"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"FullDimensionType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}}]},{"kind":"Field","name":{"kind":"Name","value":"isTechnical"}},{"kind":"Field","name":{"kind":"Name","value":"isMultiValue"}},{"kind":"Field","name":{"kind":"Name","value":"values"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}}]}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"InvolvedPerson"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"ProfileWithInvolvementType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}},{"kind":"Field","name":{"kind":"Name","value":"nick"}},{"kind":"Field","name":{"kind":"Name","value":"isActive"}},{"kind":"Field","name":{"kind":"Name","value":"involvements"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"InvolvedPersonInvolvement"}}]}}]}}]} as unknown as DocumentNode; export const UpdateProductDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateProduct"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UpdateProductInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"updateProduct"},"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":"product"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}}]} as unknown as DocumentNode; @@ -4258,11 +4408,13 @@ export const FormResponsesDocument = {"kind":"Document","definitions":[{"kind":" export const SurveySummaryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"SurveySummary"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"eventSlug"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"surveySlug"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"locale"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"filters"}},"type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"DimensionFilterInput"}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"event"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"slug"},"value":{"kind":"Variable","name":{"kind":"Name","value":"eventSlug"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"forms"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"survey"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"slug"},"value":{"kind":"Variable","name":{"kind":"Name","value":"surveySlug"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}}]},{"kind":"Field","name":{"kind":"Name","value":"fields"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}}]},{"kind":"Field","name":{"kind":"Name","value":"summary"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"filters"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filters"}}}]},{"kind":"Field","alias":{"kind":"Name","value":"countFilteredResponses"},"name":{"kind":"Name","value":"countResponses"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"filters"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filters"}}}]},{"kind":"Field","name":{"kind":"Name","value":"countResponses"}},{"kind":"Field","name":{"kind":"Name","value":"dimensions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"DimensionFilter"}}]}}]}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"DimensionFilterValue"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"DimensionValueType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}}]}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"DimensionFilter"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"FullDimensionType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}}]},{"kind":"Field","name":{"kind":"Name","value":"isMultiValue"}},{"kind":"Field","name":{"kind":"Name","value":"isListFilter"}},{"kind":"Field","name":{"kind":"Name","value":"isKeyDimension"}},{"kind":"Field","name":{"kind":"Name","value":"values"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"DimensionFilterValue"}}]}}]}}]} as unknown as DocumentNode; export const CreateSurveyDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateSurvey"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"CreateSurveyInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"createSurvey"},"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":"survey"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}}]}}]}}]}}]} as unknown as DocumentNode; export const SurveysDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"Surveys"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"eventSlug"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"locale"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"profile"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"forms"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"surveys"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"relation"},"value":{"kind":"EnumValue","value":"ACCESSIBLE"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProfileSurvey"}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"event"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"slug"},"value":{"kind":"Variable","name":{"kind":"Name","value":"eventSlug"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"forms"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"surveys"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"includeInactive"},"value":{"kind":"BooleanValue","value":true}},{"kind":"Argument","name":{"kind":"Name","value":"app"},"value":{"kind":"EnumValue","value":"FORMS"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Survey"}}]}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProfileSurvey"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"FullSurveyType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"event"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}}]}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Survey"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"FullSurveyType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}}]},{"kind":"Field","name":{"kind":"Name","value":"isActive"}},{"kind":"Field","name":{"kind":"Name","value":"activeFrom"}},{"kind":"Field","name":{"kind":"Name","value":"activeUntil"}},{"kind":"Field","name":{"kind":"Name","value":"countResponses"}},{"kind":"Field","name":{"kind":"Name","value":"languages"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"language"}}]}}]}}]} as unknown as DocumentNode; +export const UpdateTicketsPreferencesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateTicketsPreferences"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UpdateTicketsPreferencesInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"updateTicketsPreferences"},"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":"preferences"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"contactEmail"}},{"kind":"Field","name":{"kind":"Name","value":"termsAndConditionsUrlEn"}},{"kind":"Field","name":{"kind":"Name","value":"termsAndConditionsUrlFi"}},{"kind":"Field","name":{"kind":"Name","value":"termsAndConditionsUrlSv"}},{"kind":"Field","name":{"kind":"Name","value":"cancellationPeriodDays"}}]}}]}}]}}]} as unknown as DocumentNode; +export const TicketsPreferencesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"TicketsPreferences"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"eventSlug"}},"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":"slug"},"value":{"kind":"Variable","name":{"kind":"Name","value":"eventSlug"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"tickets"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"contactEmail"}},{"kind":"Field","name":{"kind":"Name","value":"termsAndConditionsUrlEn"}},{"kind":"Field","name":{"kind":"Name","value":"termsAndConditionsUrlFi"}},{"kind":"Field","name":{"kind":"Name","value":"termsAndConditionsUrlSv"}},{"kind":"Field","name":{"kind":"Name","value":"cancellationPeriodDays"}}]}}]}}]}}]} as unknown as DocumentNode; export const TicketsAdminReportsPageDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"TicketsAdminReportsPage"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"eventSlug"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"locale"}},"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":"slug"},"value":{"kind":"Variable","name":{"kind":"Name","value":"eventSlug"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"timezone"}},{"kind":"Field","name":{"kind":"Name","value":"tickets"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"reports"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Report"}}]}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Report"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"ReportType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}}]},{"kind":"Field","name":{"kind":"Name","value":"footer"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}}]},{"kind":"Field","name":{"kind":"Name","value":"columns"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}}]},{"kind":"Field","name":{"kind":"Name","value":"type"}}]}},{"kind":"Field","name":{"kind":"Name","value":"rows"}},{"kind":"Field","name":{"kind":"Name","value":"totalRow"}}]}}]} as unknown as DocumentNode; export const GenerateKeyPairDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"GenerateKeyPair"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"password"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"generateKeyPair"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"password"},"value":{"kind":"Variable","name":{"kind":"Name","value":"password"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]} as unknown as DocumentNode; export const RevokeKeyPairDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"RevokeKeyPair"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"revokeKeyPair"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]} as unknown as DocumentNode; export const ProfileEncryptionKeysDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ProfileEncryptionKeys"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"profile"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"keypairs"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProfileEncryptionKeys"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProfileEncryptionKeys"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"KeyPairType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}}]}}]} as unknown as DocumentNode; -export const ProfileOrderDetailDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ProfileOrderDetail"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"eventSlug"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"orderId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"profile"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"tickets"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"order"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"eventSlug"},"value":{"kind":"Variable","name":{"kind":"Name","value":"eventSlug"}}},{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"orderId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"formattedOrderNumber"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"totalPrice"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"eticketsLink"}},{"kind":"Field","name":{"kind":"Name","value":"canPay"}},{"kind":"Field","name":{"kind":"Name","value":"canCancel"}},{"kind":"Field","name":{"kind":"Name","value":"ticketsContactEmail"}},{"kind":"Field","name":{"kind":"Name","value":"products"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"quantity"}},{"kind":"Field","name":{"kind":"Name","value":"price"}},{"kind":"Field","name":{"kind":"Name","value":"vatPercentage"}}]}},{"kind":"Field","name":{"kind":"Name","value":"event"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"organization"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"businessId"}}]}}]}}]}}]}}]}}]}}]} as unknown as DocumentNode; +export const ProfileOrderDetailDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ProfileOrderDetail"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"eventSlug"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"orderId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"profile"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"tickets"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"order"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"eventSlug"},"value":{"kind":"Variable","name":{"kind":"Name","value":"eventSlug"}}},{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"orderId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"formattedOrderNumber"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"totalPrice"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"eticketsLink"}},{"kind":"Field","name":{"kind":"Name","value":"canPay"}},{"kind":"Field","name":{"kind":"Name","value":"canCancel"}},{"kind":"Field","name":{"kind":"Name","value":"canRequestCancellation"}},{"kind":"Field","name":{"kind":"Name","value":"ticketsContactEmail"}},{"kind":"Field","name":{"kind":"Name","value":"products"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"quantity"}},{"kind":"Field","name":{"kind":"Name","value":"price"}},{"kind":"Field","name":{"kind":"Name","value":"vatPercentage"}}]}},{"kind":"Field","name":{"kind":"Name","value":"event"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"organization"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"businessId"}}]}}]}}]}}]}}]}}]}}]} as unknown as DocumentNode; export const ConfirmEmailDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"ConfirmEmail"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ConfirmEmailInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"confirmEmail"},"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":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"email"}}]}}]}}]}}]} as unknown as DocumentNode; export const ProfileOrdersDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ProfileOrders"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"profile"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"tickets"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"orders"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProfileOrder"}}]}},{"kind":"Field","name":{"kind":"Name","value":"haveUnlinkedOrders"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProfileOrder"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"ProfileOrderType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"formattedOrderNumber"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"totalPrice"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"eticketsLink"}},{"kind":"Field","name":{"kind":"Name","value":"canPay"}},{"kind":"Field","name":{"kind":"Name","value":"canCancel"}},{"kind":"Field","name":{"kind":"Name","value":"event"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]} as unknown as DocumentNode; export const ProfileProgramItemListDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ProfileProgramItemList"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"locale"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"profile"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"program"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"programs"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"userRelation"},"value":{"kind":"EnumValue","value":"HOSTING"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProfileProgramItem"}}]}},{"kind":"Field","name":{"kind":"Name","value":"programOffers"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"filters"},"value":{"kind":"ListValue","values":[{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"dimension"},"value":{"kind":"StringValue","value":"state","block":false}},{"kind":"ObjectField","name":{"kind":"Name","value":"values"},"value":{"kind":"StringValue","value":"new","block":false}}]}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProfileResponsesTableRow"}}]}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProfileProgramItem"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"FullProgramType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"event"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"timezone"}}]}},{"kind":"Field","name":{"kind":"Name","value":"scheduleItems"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"startTime"}},{"kind":"Field","name":{"kind":"Name","value":"endTime"}},{"kind":"Field","name":{"kind":"Name","value":"durationMinutes"}},{"kind":"Field","name":{"kind":"Name","value":"location"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}}]},{"kind":"Field","name":{"kind":"Name","value":"subtitle"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProfileResponsesTableRow"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"ProfileResponseType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"revisionCreatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"canEdit"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"mode"},"value":{"kind":"EnumValue","value":"OWNER"}}]},{"kind":"Field","name":{"kind":"Name","value":"values"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"keyFieldsOnly"},"value":{"kind":"BooleanValue","value":true}}]},{"kind":"Field","name":{"kind":"Name","value":"dimensions"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"keyDimensionsOnly"},"value":{"kind":"BooleanValue","value":true}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"dimension"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}}]}]}},{"kind":"Field","name":{"kind":"Name","value":"value"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"title"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lang"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locale"}}}]},{"kind":"Field","name":{"kind":"Name","value":"color"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"form"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"event"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"survey"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}}]}}]}}]}}]} as unknown as DocumentNode; diff --git a/kompassi-v2-frontend/src/app/[locale]/[eventSlug]/orders/[orderId]/cancel/[code]/page.tsx b/kompassi-v2-frontend/src/app/[locale]/[eventSlug]/orders/[orderId]/cancel/[code]/page.tsx new file mode 100644 index 000000000..a0c80823e --- /dev/null +++ b/kompassi-v2-frontend/src/app/[locale]/[eventSlug]/orders/[orderId]/cancel/[code]/page.tsx @@ -0,0 +1,82 @@ +import Link from "next/link"; + +import { confirmOrderCancellation } from "../actions"; +import { PaymentStatus } from "@/__generated__/graphql"; +import Messages from "@/components/errors/Messages"; +import SubmitButton from "@/components/forms/SubmitButton"; +import ViewContainer from "@/components/ViewContainer"; +import ViewHeading from "@/components/ViewHeading"; +import { getOrder } from "@/services/tickets"; +import { getTranslations } from "@/translations"; + +interface Props { + params: Promise<{ + locale: string; + eventSlug: string; + orderId: string; + code: string; + }>; + searchParams: Promise>; +} + +export const revalidate = 0; + +/// Order cancellation confirmation page, reached via the link in the confirmation email. +/// NOTE: This page can be accessed without authentication (ie. we don't know the accessor +/// is the person who ordered) so absolutely no PII. +export default async function OrderCancellationConfirmationPage(props: Props) { + const { locale, eventSlug, orderId, code } = await props.params; + const searchParams = await props.searchParams; + const { order, event, seller } = await getOrder(eventSlug, orderId); + const translations = getTranslations(locale); + const t = translations.Tickets.Order; + const confirmT = t.cancelPage.confirm; + + return ( + + + {confirmT.title} + + {t.singleTitle( + order.formattedOrderNumber, + t.attributes.status.choices[order.status].shortTitle, + )} + {", "} + {event.name} + + + + + + {order.canRequestCancellation ? ( + <> + {confirmT.warning} + +
+
+ + {confirmT.actions.cancelOrder} + +
+
+ + ) : order.status === PaymentStatus.Paid ? ( +

{t.actions.requestCancellation.contactTicketSales(seller.email)}

+ ) : ( +

{t.cancelPage.notCancellable}

+ )} + + + {t.cancelPage.actions.returnToOrderPage} + +
+ ); +} diff --git a/kompassi-v2-frontend/src/app/[locale]/[eventSlug]/orders/[orderId]/cancel/actions.ts b/kompassi-v2-frontend/src/app/[locale]/[eventSlug]/orders/[orderId]/cancel/actions.ts new file mode 100644 index 000000000..ebe975ac3 --- /dev/null +++ b/kompassi-v2-frontend/src/app/[locale]/[eventSlug]/orders/[orderId]/cancel/actions.ts @@ -0,0 +1,87 @@ +"use server"; + +import { revalidatePath } from "next/cache"; +import { redirect } from "next/navigation"; +import { graphql } from "@/__generated__/gql"; +import { getClient } from "@/apolloClient"; + +const requestOrderCancellationMutation = graphql(` + mutation RequestOrderCancellation($input: RequestOrderCancellationInput!) { + requestOrderCancellation(input: $input) { + success + } + } +`); + +export async function requestOrderCancellation( + locale: string, + eventSlug: string, + orderId: string, +) { + let success = false; + try { + const response = await getClient().mutate({ + mutation: requestOrderCancellationMutation, + variables: { + input: { + eventSlug, + orderId, + }, + }, + }); + success = !!response.data?.requestOrderCancellation?.success; + } catch (error) { + console.error("requestOrderCancellation failed", error); + } + + if (success) { + return void redirect( + `/${eventSlug}/orders/${orderId}/cancel?success=cancellationRequested`, + ); + } else { + return void redirect( + `/${eventSlug}/orders/${orderId}/cancel?error=cancellationRequestFailed`, + ); + } +} + +const confirmOrderCancellationMutation = graphql(` + mutation ConfirmOrderCancellation($input: ConfirmOrderCancellationInput!) { + confirmOrderCancellation(input: $input) { + success + } + } +`); + +export async function confirmOrderCancellation( + locale: string, + eventSlug: string, + orderId: string, + code: string, +) { + let success = false; + try { + const response = await getClient().mutate({ + mutation: confirmOrderCancellationMutation, + variables: { + input: { + eventSlug, + orderId, + code, + }, + }, + }); + success = !!response.data?.confirmOrderCancellation?.success; + } catch (error) { + console.error("confirmOrderCancellation failed", error); + } + + if (success) { + revalidatePath(`/${locale}/${eventSlug}/orders/${orderId}`); + return void redirect(`/${eventSlug}/orders/${orderId}?success=cancelled`); + } else { + return void redirect( + `/${eventSlug}/orders/${orderId}/cancel/${code}?error=cancellationFailed`, + ); + } +} diff --git a/kompassi-v2-frontend/src/app/[locale]/[eventSlug]/orders/[orderId]/cancel/page.tsx b/kompassi-v2-frontend/src/app/[locale]/[eventSlug]/orders/[orderId]/cancel/page.tsx new file mode 100644 index 000000000..567bed01d --- /dev/null +++ b/kompassi-v2-frontend/src/app/[locale]/[eventSlug]/orders/[orderId]/cancel/page.tsx @@ -0,0 +1,94 @@ +import Link from "next/link"; + +import { requestOrderCancellation } from "./actions"; +import { PaymentStatus } from "@/__generated__/graphql"; +import Messages from "@/components/errors/Messages"; +import FormattedDateTime from "@/components/FormattedDateTime"; +import SubmitButton from "@/components/forms/SubmitButton"; +import ViewContainer from "@/components/ViewContainer"; +import ViewHeading from "@/components/ViewHeading"; +import { getOrder } from "@/services/tickets"; +import { getTranslations } from "@/translations"; + +interface Props { + params: Promise<{ + locale: string; + eventSlug: string; + orderId: string; + }>; + searchParams: Promise>; +} + +export const revalidate = 0; + +/// NOTE: This page can be accessed without authentication (ie. we don't know the accessor +/// is the person who ordered) so absolutely no PII. In particular, the email address of +/// the order must not be shown. +export default async function OrderCancellationPage(props: Props) { + const { locale, eventSlug, orderId } = await props.params; + const searchParams = await props.searchParams; + const { order, event, seller } = await getOrder(eventSlug, orderId); + const translations = getTranslations(locale); + const t = translations.Tickets.Order; + const cancelT = t.cancelPage; + + return ( + + + {cancelT.title} + + {t.singleTitle( + order.formattedOrderNumber, + t.attributes.status.choices[order.status].shortTitle, + )} + {", "} + {event.name} + + + + + + {order.canRequestCancellation ? ( + <> + {cancelT.explanation} + + {order.cancellationDeadline && ( +

+ {cancelT.deadline( + , + )} +

+ )} + +
+
+ + {cancelT.actions.sendConfirmationEmail} + +
+
+ + ) : order.status === PaymentStatus.Paid ? ( +

{t.actions.requestCancellation.contactTicketSales(seller.email)}

+ ) : ( +

{cancelT.notCancellable}

+ )} + + + {cancelT.actions.returnToOrderPage} + +
+ ); +} diff --git a/kompassi-v2-frontend/src/app/[locale]/[eventSlug]/orders/[orderId]/page.tsx b/kompassi-v2-frontend/src/app/[locale]/[eventSlug]/orders/[orderId]/page.tsx index 2751cc61a..e8ba0bd73 100644 --- a/kompassi-v2-frontend/src/app/[locale]/[eventSlug]/orders/[orderId]/page.tsx +++ b/kompassi-v2-frontend/src/app/[locale]/[eventSlug]/orders/[orderId]/page.tsx @@ -3,6 +3,7 @@ import { ReactNode } from "react"; import { payOrder } from "./actions"; import { PaymentStatus } from "@/__generated__/graphql"; +import Messages from "@/components/errors/Messages"; import Section from "@/components/Section"; import OrderHeader from "@/components/tickets/OrderHeader"; import ProductsTable from "@/components/tickets/ProductsTable"; @@ -17,6 +18,7 @@ interface Props { eventSlug: string; orderId: string; }>; + searchParams: Promise>; } export const revalidate = 0; @@ -26,6 +28,7 @@ export const revalidate = 0; /// so absolutely no PII. export default async function OrderPage(props: Props) { const params = await props.params; + const searchParams = await props.searchParams; const { locale, eventSlug, orderId } = params; const { order, event, seller } = await getOrder(eventSlug, orderId); const translations = getTranslations(locale); @@ -50,6 +53,8 @@ export default async function OrderPage(props: Props) { + + @@ -66,6 +71,25 @@ export default async function OrderPage(props: Props) { )} + {order.canRequestCancellation && ( +
+
+ + {t.Order.actions.requestCancellation.title}… + +
+
+ )} + + {!order.canRequestCancellation && order.status === PaymentStatus.Paid && ( +

+ {t.Order.actions.requestCancellation.contactTicketSales(seller.email)} +

+ )} + {showProfileMessage &&

{t.Order.profileMessage(ProfileLink)}

}
); diff --git a/kompassi-v2-frontend/src/app/[locale]/[eventSlug]/tickets-preferences/actions.ts b/kompassi-v2-frontend/src/app/[locale]/[eventSlug]/tickets-preferences/actions.ts new file mode 100644 index 000000000..b9fe5de0d --- /dev/null +++ b/kompassi-v2-frontend/src/app/[locale]/[eventSlug]/tickets-preferences/actions.ts @@ -0,0 +1,47 @@ +"use server"; + +import { revalidatePath } from "next/cache"; +import { graphql } from "@/__generated__"; +import { getClient } from "@/apolloClient"; + +const mutation = graphql(` + mutation UpdateTicketsPreferences($input: UpdateTicketsPreferencesInput!) { + updateTicketsPreferences(input: $input) { + preferences { + contactEmail + termsAndConditionsUrlEn + termsAndConditionsUrlFi + termsAndConditionsUrlSv + cancellationPeriodDays + } + } + } +`); + +export async function updateTicketsPreferences( + locale: string, + eventSlug: string, + formData: FormData, +) { + const cancellationPeriodDays = + parseInt("" + formData.get("cancellationPeriodDays"), 10) || 0; + + await getClient().mutate({ + mutation, + variables: { + input: { + eventSlug, + contactEmail: "" + (formData.get("contactEmail") ?? ""), + termsAndConditionsUrlEn: + "" + (formData.get("termsAndConditionsUrlEn") ?? ""), + termsAndConditionsUrlFi: + "" + (formData.get("termsAndConditionsUrlFi") ?? ""), + termsAndConditionsUrlSv: + "" + (formData.get("termsAndConditionsUrlSv") ?? ""), + cancellationPeriodDays, + }, + }, + }); + + revalidatePath(`/${locale}/${eventSlug}/tickets-preferences`); +} diff --git a/kompassi-v2-frontend/src/app/[locale]/[eventSlug]/tickets-preferences/page.tsx b/kompassi-v2-frontend/src/app/[locale]/[eventSlug]/tickets-preferences/page.tsx new file mode 100644 index 000000000..9269146a4 --- /dev/null +++ b/kompassi-v2-frontend/src/app/[locale]/[eventSlug]/tickets-preferences/page.tsx @@ -0,0 +1,159 @@ +import { notFound } from "next/navigation"; + +import Card from "react-bootstrap/Card"; +import CardBody from "react-bootstrap/CardBody"; +import { updateTicketsPreferences } from "./actions"; +import { graphql } from "@/__generated__"; +import { getClient } from "@/apolloClient"; +import { auth } from "@/auth"; +import SignInRequired from "@/components/errors/SignInRequired"; +import { Field } from "@/components/forms/models"; +import { SchemaForm } from "@/components/forms/SchemaForm"; +import SubmitButton from "@/components/forms/SubmitButton"; +import TicketsAdminView from "@/components/tickets/TicketsAdminView"; +import getPageTitle from "@/helpers/getPageTitle"; +import { getTranslations } from "@/translations"; + +const query = graphql(` + query TicketsPreferences($eventSlug: String!) { + event(slug: $eventSlug) { + name + slug + + tickets { + contactEmail + termsAndConditionsUrlEn + termsAndConditionsUrlFi + termsAndConditionsUrlSv + cancellationPeriodDays + } + } + } +`); + +interface Props { + params: Promise<{ + locale: string; + eventSlug: string; + }>; + searchParams: Promise>; +} + +export const revalidate = 0; + +export async function generateMetadata(props: Props) { + const params = await props.params; + const { locale, eventSlug } = params; + const translations = getTranslations(locale); + + const session = await auth(); + if (!session) { + return translations.SignInRequired.metadata; + } + + const { data } = await getClient().query({ + query, + variables: { eventSlug }, + }); + + return { + title: getPageTitle({ + translations, + event: data.event, + viewTitle: translations.Tickets.admin.preferences.title, + }), + }; +} + +export default async function TicketsPreferencesPage(props: Props) { + const params = await props.params; + const searchParams = await props.searchParams; + const { locale, eventSlug } = params; + const translations = getTranslations(locale); + const t = translations.Tickets.admin.preferences; + + const session = await auth(); + if (!session) { + return ; + } + + const { data } = await getClient().query({ + query, + variables: { eventSlug }, + }); + + const event = data.event; + const tickets = data.event?.tickets; + + if (!event || !tickets) { + notFound(); + } + + const fields: Field[] = [ + { + slug: "contactEmail", + type: "SingleLineText", + title: t.attributes.contactEmail.title, + helpText: t.attributes.contactEmail.helpText, + required: false, + }, + { + slug: "termsAndConditionsUrlEn", + type: "SingleLineText", + title: t.attributes.termsAndConditionsUrl.en, + required: false, + }, + { + slug: "termsAndConditionsUrlFi", + type: "SingleLineText", + title: t.attributes.termsAndConditionsUrl.fi, + required: false, + }, + { + slug: "termsAndConditionsUrlSv", + type: "SingleLineText", + title: t.attributes.termsAndConditionsUrl.sv, + required: false, + }, + { + slug: "cancellationPeriodDays", + type: "NumberField", + title: t.attributes.cancellationPeriodDays.title, + helpText: t.attributes.cancellationPeriodDays.helpText, + required: false, + }, + ]; + + const values = { + contactEmail: tickets.contactEmail ?? "", + termsAndConditionsUrlEn: tickets.termsAndConditionsUrlEn ?? "", + termsAndConditionsUrlFi: tickets.termsAndConditionsUrlFi ?? "", + termsAndConditionsUrlSv: tickets.termsAndConditionsUrlSv ?? "", + cancellationPeriodDays: tickets.cancellationPeriodDays, + }; + + return ( + + + +
+ + + {translations.Common.standardActions.save} + + +
+
+
+ ); +} diff --git a/kompassi-v2-frontend/src/app/[locale]/profile/orders/[eventSlug]/[orderId]/page.tsx b/kompassi-v2-frontend/src/app/[locale]/profile/orders/[eventSlug]/[orderId]/page.tsx index 88c4758d6..e4ce8a8cf 100644 --- a/kompassi-v2-frontend/src/app/[locale]/profile/orders/[eventSlug]/[orderId]/page.tsx +++ b/kompassi-v2-frontend/src/app/[locale]/profile/orders/[eventSlug]/[orderId]/page.tsx @@ -3,6 +3,7 @@ import Link from "next/link"; import { notFound } from "next/navigation"; import { payOrder } from "../../actions"; import { graphql } from "@/__generated__"; +import { PaymentStatus } from "@/__generated__/graphql"; import { getClient } from "@/apolloClient"; import { cancelOrder } from "@/app/[locale]/[eventSlug]/orders/[orderId]/actions"; import { auth } from "@/auth"; @@ -29,6 +30,7 @@ const query = graphql(` eticketsLink canPay canCancel + canRequestCancellation ticketsContactEmail products { title @@ -175,6 +177,25 @@ export default async function ProfileOrderPage(props: Props) { )} + + {order.canRequestCancellation && ( +
+ + {t.actions.requestCancellation.title}… + +
+ )} + + {!order.canRequestCancellation && order.status === PaymentStatus.Paid && ( +

+ {t.actions.requestCancellation.contactTicketSales( + order.ticketsContactEmail, + )} +

+ )} ); } diff --git a/kompassi-v2-frontend/src/components/forms/SubmitButton.tsx b/kompassi-v2-frontend/src/components/forms/SubmitButton.tsx index 294b6d608..422d41f07 100644 --- a/kompassi-v2-frontend/src/components/forms/SubmitButton.tsx +++ b/kompassi-v2-frontend/src/components/forms/SubmitButton.tsx @@ -39,6 +39,13 @@ export default function SubmitButton({ disabled={disabled || pending} onClick={confirmationMessage ? onClick : undefined} > + {pending && ( +