gymmonk-schema 0.60.0 → 0.62.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -74,14 +74,14 @@ export declare const gymRegistrationBodySchema: z.ZodObject<{
74
74
  registrationNumber: z.ZodPreprocess<z.ZodOptional<z.ZodString>>;
75
75
  email: z.ZodPreprocess<z.ZodOptional<z.ZodEmail>>;
76
76
  website: z.ZodPreprocess<z.ZodOptional<z.ZodString>>;
77
- socials: z.ZodObject<{
77
+ socials: z.ZodOptional<z.ZodObject<{
78
78
  jansathi: z.ZodPreprocess<z.ZodOptional<z.ZodString>>;
79
79
  youtube: z.ZodPreprocess<z.ZodOptional<z.ZodString>>;
80
80
  instagram: z.ZodPreprocess<z.ZodOptional<z.ZodString>>;
81
81
  facebook: z.ZodPreprocess<z.ZodOptional<z.ZodString>>;
82
- }, z.core.$strip>;
82
+ }, z.core.$strip>>;
83
83
  upiId: z.ZodOptional<z.ZodPreprocess<z.ZodUnion<readonly [z.ZodLiteral<"">, z.ZodString]>>>;
84
- numberOfCenters: z.ZodNumber;
84
+ numberOfCenters: z.ZodOptional<z.ZodNumber>;
85
85
  }, z.core.$strip>;
86
86
  center: z.ZodObject<{
87
87
  checkInRadiusM: z.ZodOptional<z.ZodNumber>;
@@ -196,10 +196,10 @@ export declare const gymRegistrationBodySchema: z.ZodObject<{
196
196
  }, z.core.$strip>;
197
197
  photos: z.ZodDefault<z.ZodArray<z.ZodString>>;
198
198
  }, z.core.$strip>;
199
- subscription: z.ZodObject<{
199
+ subscription: z.ZodOptional<z.ZodObject<{
200
200
  planId: z.ZodString;
201
201
  tenureId: z.ZodNullable<z.ZodString>;
202
- }, z.core.$strip>;
202
+ }, z.core.$strip>>;
203
203
  }, z.core.$strip>;
204
204
  export type GymRegistrationBody = z.infer<typeof gymRegistrationBodySchema>;
205
205
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"gym-registration.d.ts","sourceRoot":"","sources":["../src/gym-registration.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAQxB,sEAAsE;AACtE,eAAO,MAAM,sBAAsB;;;iBAGjC,CAAC;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEtE,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAIpC,CAAC;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAI5E;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,0BAA0B,wCAAoC,CAAC;AAC5E,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAE9E;;;;;GAKG;AACH,eAAO,MAAM,6BAA6B;;;iBAGxC,CAAC;AACH,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAC;AAEpF,2EAA2E;AAC3E,eAAO,MAAM,mCAAmC;;;iBAKpC,CAAC;AACb,MAAM,MAAM,6BAA6B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mCAAmC,CAAC,CAAC"}
1
+ {"version":3,"file":"gym-registration.d.ts","sourceRoot":"","sources":["../src/gym-registration.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAQxB,sEAAsE;AACtE,eAAO,MAAM,sBAAsB;;;iBAGjC,CAAC;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEtE,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAmBpC,CAAC;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAI5E;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,0BAA0B,wCAAoC,CAAC;AAC5E,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAE9E;;;;;GAKG;AACH,eAAO,MAAM,6BAA6B;;;iBAGxC,CAAC;AACH,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAC;AAEpF,2EAA2E;AAC3E,eAAO,MAAM,mCAAmC;;;iBAKpC,CAAC;AACb,MAAM,MAAM,6BAA6B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mCAAmC,CAAC,CAAC"}
@@ -36,7 +36,22 @@ export const gymPlanSelectionSchema = z.object({
36
36
  export const gymRegistrationBodySchema = z.object({
37
37
  organisation: createOrganisationBodySchema,
38
38
  center: createCenterBodySchema,
39
- subscription: gymPlanSelectionSchema,
39
+ /**
40
+ * OPTIONAL, and no longer sent.
41
+ *
42
+ * The wizard'''s pricing carousel is gone. It was never honoured anyway —
43
+ * `registerGym` starts EVERY new gym on a Pro trial whatever was picked,
44
+ * because there is no Razorpay plan behind any tier yet, so the screen asked
45
+ * a question whose answer was thrown away. The owner chooses and changes a
46
+ * plan from the console'''s subscription screen, which is where they would
47
+ * go to change one later regardless.
48
+ *
49
+ * Kept on the contract rather than deleted: an older client cached in
50
+ * somebody'''s PWA still sends it, and an optional key it may ignore is the
51
+ * difference between that client working and 422-ing on submit. When billing
52
+ * lands this becomes the selection a completed payment carries.
53
+ */
54
+ subscription: gymPlanSelectionSchema.optional(),
40
55
  });
41
56
  // ─── Resume: the per-step draft ──────────────────────────────────────────────
42
57
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"gym-registration.js","sourceRoot":"","sources":["../src/gym-registration.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AACrD,gFAAgF;AAChF,+EAA+E;AAC/E,0CAA0C;AAC1C,OAAO,EAAE,4BAA4B,EAAE,MAAM,sBAAsB,CAAC;AACpE,OAAO,EAAE,4BAA4B,EAAE,MAAM,mBAAmB,CAAC;AAEjE,sEAAsE;AACtE,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC7C,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAChC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;CAC9C,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,CAAC,MAAM,CAAC;IAChD,YAAY,EAAE,4BAA4B;IAC1C,MAAM,EAAE,sBAAsB;IAC9B,YAAY,EAAE,sBAAsB;CACrC,CAAC,CAAC;AAGH,gFAAgF;AAEhF;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;AAG5E;;;;;GAKG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAC,CAAC,MAAM,CAAC;IACpD,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,4BAA4B,CAAC;IAC/D,KAAK,EAAE,0BAA0B,CAAC,QAAQ,EAAE;CAC7C,CAAC,CAAC;AAGH,2EAA2E;AAC3E,MAAM,CAAC,MAAM,mCAAmC,GAAG,CAAC;KACjD,MAAM,CAAC;IACN,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,4BAA4B,CAAC;IAC/D,KAAK,EAAE,0BAA0B;CAClC,CAAC;KACD,OAAO,EAAE,CAAC","sourcesContent":["/**\n * gymmonk-schema — Gym registration\n * =================================\n * \"List your gym on GymMonk\" — the payload a signed-in MEMBER submits to create\n * the business they run.\n *\n * This used to be owner onboarding, a fork taken before the user had seen\n * anything. It is now an ordinary action taken from the Me tab by somebody who\n * already has an account, and that changes what it has to ask for:\n *\n * - NO personal details. Name, gender, date of birth, phone and photo were\n * all captured at onboarding. Asking again would be asking the same person\n * the same questions twice and then having two answers to keep in step.\n * - NO automatic membership of their own gym. Owning a gym and training at\n * one are separate things — an owner keeps the single member identity they\n * registered with, and is free to be a paying member of somebody else's gym.\n *\n * The submitted organisation starts `pending` and is invisible in the member\n * gym directory until a superadmin or platform manager approves it\n * (`organisationApprovalStatusSchema`).\n *\n * @module gymmonk-schema/gym-registration\n */\n\nimport { z } from 'zod';\nimport { createCenterBodySchema } from './center.js';\n// The wizard's own step count, so the resume cursor below cannot be capped at a\n// number the wizard has outgrown. `onboarding-form` imports nothing from here,\n// so this is a one-way edge, not a cycle.\nimport { GYM_REGISTRATION_TOTAL_STEPS } from './onboarding-form.js';\nimport { createOrganisationBodySchema } from './organisation.js';\n\n/** The SaaS plan the owner selects at the final registration step. */\nexport const gymPlanSelectionSchema = z.object({\n planId: z.string().trim().min(1),\n tenureId: z.string().trim().min(1).nullable(),\n});\nexport type GymPlanSelection = z.infer<typeof gymPlanSelectionSchema>;\n\nexport const gymRegistrationBodySchema = z.object({\n organisation: createOrganisationBodySchema,\n center: createCenterBodySchema,\n subscription: gymPlanSelectionSchema,\n});\nexport type GymRegistrationBody = z.infer<typeof gymRegistrationBodySchema>;\n\n// ─── Resume: the per-step draft ──────────────────────────────────────────────\n\n/**\n * The wizard's UI-shaped, partially-filled form, persisted a STEP AT A TIME.\n *\n * Opaque to the backend by design — the client owns the form shape, and what is\n * stored here is re-validated strictly by `gymRegistrationBodySchema` at submit.\n * Keys are form field names; the backend caps the stored size.\n *\n * ── Why the wizard needs its own cursor ─────────────────────────────────────\n * Not the onboarding cursor. That one belongs to onboarding, a flow this user\n * finished long ago and can no longer enter, and writing a `step` into it would\n * move the resume target of a different wizard. This is a separate record with\n * its own lifecycle: it starts when somebody begins describing their gym, and\n * it is retired the moment the gym is actually submitted.\n */\nexport const gymRegistrationDraftSchema = z.record(z.string(), z.unknown());\nexport type GymRegistrationDraft = z.infer<typeof gymRegistrationDraftSchema>;\n\n/**\n * `GET /gym-registration/draft` — how far the caller got and what they typed.\n *\n * `step: 0` with no draft is the ordinary \"never started\" answer, so the client\n * has one shape to read rather than a null to branch on.\n */\nexport const gymRegistrationProgressSchema = z.object({\n step: z.number().int().min(0).max(GYM_REGISTRATION_TOTAL_STEPS),\n draft: gymRegistrationDraftSchema.optional(),\n});\nexport type GymRegistrationProgress = z.infer<typeof gymRegistrationProgressSchema>;\n\n/** `PUT /gym-registration/draft` body — any subset, merged server-side. */\nexport const gymRegistrationProgressUpdateSchema = z\n .object({\n step: z.number().int().min(0).max(GYM_REGISTRATION_TOTAL_STEPS),\n draft: gymRegistrationDraftSchema,\n })\n .partial();\nexport type GymRegistrationProgressUpdate = z.infer<typeof gymRegistrationProgressUpdateSchema>;\n"]}
1
+ {"version":3,"file":"gym-registration.js","sourceRoot":"","sources":["../src/gym-registration.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AACrD,gFAAgF;AAChF,+EAA+E;AAC/E,0CAA0C;AAC1C,OAAO,EAAE,4BAA4B,EAAE,MAAM,sBAAsB,CAAC;AACpE,OAAO,EAAE,4BAA4B,EAAE,MAAM,mBAAmB,CAAC;AAEjE,sEAAsE;AACtE,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC7C,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAChC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;CAC9C,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,CAAC,MAAM,CAAC;IAChD,YAAY,EAAE,4BAA4B;IAC1C,MAAM,EAAE,sBAAsB;IAC9B;;;;;;;;;;;;;;OAcG;IACH,YAAY,EAAE,sBAAsB,CAAC,QAAQ,EAAE;CAChD,CAAC,CAAC;AAGH,gFAAgF;AAEhF;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;AAG5E;;;;;GAKG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAC,CAAC,MAAM,CAAC;IACpD,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,4BAA4B,CAAC;IAC/D,KAAK,EAAE,0BAA0B,CAAC,QAAQ,EAAE;CAC7C,CAAC,CAAC;AAGH,2EAA2E;AAC3E,MAAM,CAAC,MAAM,mCAAmC,GAAG,CAAC;KACjD,MAAM,CAAC;IACN,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,4BAA4B,CAAC;IAC/D,KAAK,EAAE,0BAA0B;CAClC,CAAC;KACD,OAAO,EAAE,CAAC","sourcesContent":["/**\n * gymmonk-schema — Gym registration\n * =================================\n * \"List your gym on GymMonk\" — the payload a signed-in MEMBER submits to create\n * the business they run.\n *\n * This used to be owner onboarding, a fork taken before the user had seen\n * anything. It is now an ordinary action taken from the Me tab by somebody who\n * already has an account, and that changes what it has to ask for:\n *\n * - NO personal details. Name, gender, date of birth, phone and photo were\n * all captured at onboarding. Asking again would be asking the same person\n * the same questions twice and then having two answers to keep in step.\n * - NO automatic membership of their own gym. Owning a gym and training at\n * one are separate things — an owner keeps the single member identity they\n * registered with, and is free to be a paying member of somebody else's gym.\n *\n * The submitted organisation starts `pending` and is invisible in the member\n * gym directory until a superadmin or platform manager approves it\n * (`organisationApprovalStatusSchema`).\n *\n * @module gymmonk-schema/gym-registration\n */\n\nimport { z } from 'zod';\nimport { createCenterBodySchema } from './center.js';\n// The wizard's own step count, so the resume cursor below cannot be capped at a\n// number the wizard has outgrown. `onboarding-form` imports nothing from here,\n// so this is a one-way edge, not a cycle.\nimport { GYM_REGISTRATION_TOTAL_STEPS } from './onboarding-form.js';\nimport { createOrganisationBodySchema } from './organisation.js';\n\n/** The SaaS plan the owner selects at the final registration step. */\nexport const gymPlanSelectionSchema = z.object({\n planId: z.string().trim().min(1),\n tenureId: z.string().trim().min(1).nullable(),\n});\nexport type GymPlanSelection = z.infer<typeof gymPlanSelectionSchema>;\n\nexport const gymRegistrationBodySchema = z.object({\n organisation: createOrganisationBodySchema,\n center: createCenterBodySchema,\n /**\n * OPTIONAL, and no longer sent.\n *\n * The wizard'''s pricing carousel is gone. It was never honoured anyway —\n * `registerGym` starts EVERY new gym on a Pro trial whatever was picked,\n * because there is no Razorpay plan behind any tier yet, so the screen asked\n * a question whose answer was thrown away. The owner chooses and changes a\n * plan from the console'''s subscription screen, which is where they would\n * go to change one later regardless.\n *\n * Kept on the contract rather than deleted: an older client cached in\n * somebody'''s PWA still sends it, and an optional key it may ignore is the\n * difference between that client working and 422-ing on submit. When billing\n * lands this becomes the selection a completed payment carries.\n */\n subscription: gymPlanSelectionSchema.optional(),\n});\nexport type GymRegistrationBody = z.infer<typeof gymRegistrationBodySchema>;\n\n// ─── Resume: the per-step draft ──────────────────────────────────────────────\n\n/**\n * The wizard's UI-shaped, partially-filled form, persisted a STEP AT A TIME.\n *\n * Opaque to the backend by design — the client owns the form shape, and what is\n * stored here is re-validated strictly by `gymRegistrationBodySchema` at submit.\n * Keys are form field names; the backend caps the stored size.\n *\n * ── Why the wizard needs its own cursor ─────────────────────────────────────\n * Not the onboarding cursor. That one belongs to onboarding, a flow this user\n * finished long ago and can no longer enter, and writing a `step` into it would\n * move the resume target of a different wizard. This is a separate record with\n * its own lifecycle: it starts when somebody begins describing their gym, and\n * it is retired the moment the gym is actually submitted.\n */\nexport const gymRegistrationDraftSchema = z.record(z.string(), z.unknown());\nexport type GymRegistrationDraft = z.infer<typeof gymRegistrationDraftSchema>;\n\n/**\n * `GET /gym-registration/draft` — how far the caller got and what they typed.\n *\n * `step: 0` with no draft is the ordinary \"never started\" answer, so the client\n * has one shape to read rather than a null to branch on.\n */\nexport const gymRegistrationProgressSchema = z.object({\n step: z.number().int().min(0).max(GYM_REGISTRATION_TOTAL_STEPS),\n draft: gymRegistrationDraftSchema.optional(),\n});\nexport type GymRegistrationProgress = z.infer<typeof gymRegistrationProgressSchema>;\n\n/** `PUT /gym-registration/draft` body — any subset, merged server-side. */\nexport const gymRegistrationProgressUpdateSchema = z\n .object({\n step: z.number().int().min(0).max(GYM_REGISTRATION_TOTAL_STEPS),\n draft: gymRegistrationDraftSchema,\n })\n .partial();\nexport type GymRegistrationProgressUpdate = z.infer<typeof gymRegistrationProgressUpdateSchema>;\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../src/messages.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAIH;;;;GAIG;AACH,eAAO,MAAM,UAAU;;;;;;;;;;;;;;IAsBrB;;;;;;;;;;;;;OAaG;;IAGH;;;;;;;;;OASG;;IAGH;;;;;;;OAOG;;;CAKK,CAAC;AAEX,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,OAAO,UAAU,CAAC,CAAC;AAIrE,wEAAwE;AACxE,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAID;;;GAGG;AACH,eAAO,MAAM,eAAe;;;;;;;;;IAU1B,sEAAsE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA8DtE;;;;OAIG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAwCH;;;;;OAKG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+E6C,CAAC;AAEnD,MAAM,MAAM,iBAAiB,GAAG,MAAM,OAAO,eAAe,CAAC;AAE7D,0DAA0D;AAC1D,eAAO,MAAM,mBAAmB;iCACV,MAAM,KAAG,aAAa;gCAIvB,MAAM,KAAG,aAAa;sCAIhB,MAAM,KAAG,aAAa;uCAIrB,MAAM,KAAG,aAAa;uCAGtB,MAAM,KAAG,aAAa;uCAItB,MAAM,KAAG,aAAa;CAIxC,CAAC;AAIX;;;;GAIG;AACH,eAAO,MAAM,aAAa;;;;;;;;;;IAiBxB;;;;;OAKG;;IAGH;;;;;;;OAOG;;IAGH;;;;;;OAMG;;IAGH,4EAA4E;;IAE5E,+EAA+E;;IAE/E,gFAAgF;;IAGhF,iDAAiD;;;IAKjD,kDAAkD;;IAElD;;;;OAIG;;IAEH;;;;OAIG;;IAEH,qEAAqE;;IAErE,2EAA2E;;IAE3E,wEAAwE;;;;;;;IASxE,gEAAgE;;;;;;;;;IAkBhE,8DAA8D;;IAE9D;;;;OAIG;;IAEH;;;;OAIG;;IAEH;;;;OAIG;;IAGH;;;;;OAKG;;;;IAOH,2EAA2E;;;IAI3E;;;OAGG;;;IAIH;;;;OAIG;;IAGH;;;;OAIG;;IAEH;;;;;OAKG;;IAGH;;;OAGG;;IAGH,mEAAmE;;;;;IAKnE,8EAA8E;;IAE9E,uEAAuE;;;;;;;;;;;;;IAgBvE;;;OAGG;;;;IAMH,wEAAwE;;IAExE,uEAAuE;;IAEvE,yEAAyE;;IAEzE,8EAA8E;;IAE9E,0DAA0D;;;IAG1D;;;;OAIG;;IAIH,4EAA4E;;IAG5E,6DAA6D;;IAE7D,kDAAkD;;IAElD,+DAA+D;;IAE/D,sEAAsE;;;IAItE,kEAAkE;;;IAGlE,qEAAqE;;IAErE;;;;;;OAMG;;IAEH,wDAAwD;;;IAGxD,uEAAuE;;IAEvE,8EAA8E;;;IAI9E;;;;;;;;;;;;;OAaG;;;;;IAMH;;;;;;OAMG;;;;;;;;;;;;CAkBsC,CAAC;AAE5C,MAAM,MAAM,eAAe,GAAG,MAAM,OAAO,aAAa,CAAC;AAEzD,iDAAiD;AACjD,eAAO,MAAM,iBAAiB;8BACX,MAAM,KAAG,MAAM;IAChC;;;;;;;;OAQG;gDACgC,MAAM,KAAG,MAAM;IAElD,2DAA2D;sCAClC,MAAM,KAAG,MAAM;CAEhC,CAAC"}
1
+ {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../src/messages.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAIH;;;;GAIG;AACH,eAAO,MAAM,UAAU;;;;;;;;;;;;;;IAsBrB;;;;;;;;;;;;;OAaG;;IAGH;;;;;;;;;OASG;;IAGH;;;;;;;OAOG;;;CAKK,CAAC;AAEX,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,OAAO,UAAU,CAAC,CAAC;AAIrE,wEAAwE;AACxE,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAID;;;GAGG;AACH,eAAO,MAAM,eAAe;;;;;;;;;IAU1B,sEAAsE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA8DtE;;;;OAIG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAwCH;;;;;OAKG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+E6C,CAAC;AAEnD,MAAM,MAAM,iBAAiB,GAAG,MAAM,OAAO,eAAe,CAAC;AAE7D,0DAA0D;AAC1D,eAAO,MAAM,mBAAmB;iCACV,MAAM,KAAG,aAAa;gCAIvB,MAAM,KAAG,aAAa;sCAIhB,MAAM,KAAG,aAAa;uCAIrB,MAAM,KAAG,aAAa;uCAGtB,MAAM,KAAG,aAAa;uCAItB,MAAM,KAAG,aAAa;CAIxC,CAAC;AAIX;;;;GAIG;AACH,eAAO,MAAM,aAAa;;;;;;;;;;IAiBxB;;;;;OAKG;;IAGH;;;;;;;OAOG;;IAGH;;;;;;OAMG;;IAGH,4EAA4E;;IAE5E,+EAA+E;;IAE/E,gFAAgF;;IAGhF,iDAAiD;;;IAKjD,kDAAkD;;IAElD;;;;OAIG;;IAEH;;;;OAIG;;IAEH,qEAAqE;;IAErE,2EAA2E;;IAE3E,wEAAwE;;;;;;;IASxE,gEAAgE;;;;;;;;;IAkBhE,8DAA8D;;IAE9D;;;;OAIG;;IAEH;;;;OAIG;;IAEH;;;;OAIG;;IAGH;;;;;OAKG;;;;IAMH,2EAA2E;;;IAI3E;;;OAGG;;;IAIH;;;;OAIG;;IAGH;;;;OAIG;;IAEH;;;;;OAKG;;IAGH;;;OAGG;;IAGH,mEAAmE;;;;;IAKnE,8EAA8E;;IAE9E,uEAAuE;;;;;;;;;;;;;IAgBvE;;;OAGG;;;;IAMH,wEAAwE;;IAExE,uEAAuE;;IAEvE,yEAAyE;;IAEzE,8EAA8E;;IAE9E,0DAA0D;;;IAG1D;;;;OAIG;;IAIH,4EAA4E;;IAG5E,6DAA6D;;IAE7D,kDAAkD;;IAElD,+DAA+D;;IAE/D,sEAAsE;;;IAItE,kEAAkE;;;IAGlE,qEAAqE;;IAErE;;;;;;OAMG;;IAEH,wDAAwD;;;IAGxD,uEAAuE;;IAEvE,8EAA8E;;;IAI9E;;;;;;;;;;;;;OAaG;;;;;IAMH;;;;;;OAMG;;;;;;;;;;;;CAkBsC,CAAC;AAE5C,MAAM,MAAM,eAAe,GAAG,MAAM,OAAO,aAAa,CAAC;AAEzD,iDAAiD;AACjD,eAAO,MAAM,iBAAiB;8BACX,MAAM,KAAG,MAAM;IAChC;;;;;;;;OAQG;gDACgC,MAAM,KAAG,MAAM;IAElD,2DAA2D;sCAClC,MAAM,KAAG,MAAM;CAEhC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"messages.js","sourceRoot":"","sources":["../src/messages.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * gymmonk-schema — API result messages\n * ====================================\n * Single source of truth for every user-facing SUCCESS and ERROR message the\n * product shows, plus the API error codes both sides key off.\n *\n * Why it lives here: the schema package is already the SSOT for data shapes,\n * types and validation. Result copy is part of that contract — the backend\n * raises a message, the client shows it, and neither should invent its own\n * wording. Both repos import from here, so copy changes land in one place and\n * can never drift between server and client.\n *\n * Usage:\n * backend → `throw new BadRequestError(ERROR_MESSAGE.centerAddressRequired)`\n * frontend → `showSuccess(...toast(SUCCESS_MESSAGE.profileUpdated))`\n *\n * @module gymmonk-schema/messages\n */\n\n// ─── API error codes ─────────────────────────────────────────────────────────\n\n/**\n * Machine-readable error codes returned in the API envelope\n * (`{ success: false, error: { code, message } }`). The client can branch on a\n * code; the message is what a human reads.\n */\nexport const ERROR_CODE = {\n // General\n INTERNAL_ERROR: 'INTERNAL_ERROR',\n VALIDATION_ERROR: 'VALIDATION_ERROR',\n NOT_FOUND: 'NOT_FOUND',\n\n // Auth\n INVALID_TOKEN: 'INVALID_TOKEN',\n TOKEN_EXPIRED: 'TOKEN_EXPIRED',\n UNAUTHORIZED: 'UNAUTHORIZED',\n FORBIDDEN: 'FORBIDDEN',\n SESSION_INVALIDATED: 'SESSION_INVALIDATED',\n\n // User\n USER_NOT_FOUND: 'USER_NOT_FOUND',\n USER_ALREADY_EXISTS: 'USER_ALREADY_EXISTS',\n INVALID_ROLE: 'INVALID_ROLE',\n\n // Rate limiting\n RATE_LIMITED: 'RATE_LIMITED',\n RATE_LIMIT_EXCEEDED: 'RATE_LIMIT_EXCEEDED',\n\n /**\n * The caller MAY do this — their subscription simply does not stretch to it.\n *\n * Deliberately NOT `FORBIDDEN`, and the distinction is load-bearing on the\n * client. A role denial means \"this is not yours\"; the answer is to go away.\n * A plan denial means \"this costs money\"; the answer is an upgrade prompt with\n * the price on it. A client that cannot tell them apart either shows an\n * upgrade sheet to a trainer who will never be allowed to buy one, or shows a\n * bare 403 to an owner who would happily have paid.\n *\n * Always accompanied by `details`: `{ feature, currentPlan, requiredPlan,\n * current?, limit? }` — enough for the prompt to name the feature, the tier\n * that unlocks it, and how full the current allowance is.\n */\n PLAN_LIMIT_EXCEEDED: 'PLAN_LIMIT_EXCEEDED',\n\n /**\n * That phone number already belongs to somebody else's account.\n *\n * A code of its own rather than a bare `USER_ALREADY_EXISTS`, because the\n * phone is the join key between an app account and a gym's member record, and\n * the client has to act on this rather than merely print it: onboarding puts\n * the message on the phone FIELD so the person can edit it in place, and the\n * desk adding a member needs to know the number is spoken for before it mints\n * an invite that can never be claimed.\n */\n PHONE_ALREADY_IN_USE: 'PHONE_ALREADY_IN_USE',\n\n /**\n * An already-registered member opened an invite issued to a DIFFERENT number.\n *\n * Not a refusal — a question. The claim stops and asks which number is\n * theirs, and the client re-sends with `phoneChoice`. It carries `details`:\n * `{ gymPhone, myPhone }`, both MASKED, enough to recognise a number without\n * publishing one.\n */\n INVITE_PHONE_MISMATCH: 'INVITE_PHONE_MISMATCH',\n\n // Upstream / dependency unavailable\n SERVICE_UNAVAILABLE: 'SERVICE_UNAVAILABLE',\n} as const;\n\nexport type ErrorCode = (typeof ERROR_CODE)[keyof typeof ERROR_CODE];\n\n// ─── Message shape ───────────────────────────────────────────────────────────\n\n/** A result message: a headline and an optional quieter second line. */\nexport interface ResultMessage {\n title: string;\n description?: string;\n}\n\n// ─── Success messages ────────────────────────────────────────────────────────\n\n/**\n * Confirmation shown after a write succeeds, keyed by action. Interpolating\n * entries are functions so the caller supplies the value without re-wording.\n */\nexport const SUCCESS_MESSAGE = {\n // Onboarding\n memberOnboardingComplete: {\n title: \"You're all set\",\n description: 'Welcome to GymMonk.',\n },\n ownerOnboardingComplete: {\n title: 'Your gym is ready',\n description: 'Welcome to GymMonk.',\n },\n /** Each wizard step is persisted on its own, so each one confirms. */\n onboardingStepSaved: { title: 'Saved' },\n\n // Identity & profile\n profileUpdated: { title: 'Profile updated' },\n organisationUpdated: { title: 'Organisation updated' },\n\n // Gym structure\n centerAdded: { title: 'Center added' },\n centerUpdated: { title: 'Center updated' },\n membershipPlanCreated: { title: 'Membership plan created' },\n membershipPlanUpdated: { title: 'Membership plan updated' },\n equipmentSaved: { title: 'Equipment updated' },\n\n // Membership (member-side)\n membershipUpdated: { title: 'Membership updated' },\n membershipRenewed: { title: 'Membership renewed' },\n membershipCancelled: { title: 'Membership cancelled' },\n membershipPauseRequested: {\n title: 'Pause request sent',\n description: 'Your gym will confirm the pause.',\n },\n\n // Owner SaaS subscription\n subscriptionUpdated: { title: 'Subscription updated' },\n\n // Training\n workoutPlanCreated: { title: 'Workout plan created' },\n workoutPlanUpdated: { title: 'Workout plan saved' },\n workoutPlanDeleted: {\n title: 'Workout plan deleted',\n description: 'Members on this plan no longer have one.',\n },\n workoutCreated: { title: 'Workout created' },\n workoutUpdated: { title: 'Workout saved' },\n workoutDeleted: { title: 'Workout removed' },\n workoutPlanAssigned: { title: 'Workout plan assigned' },\n\n // Diet — the counterparts of the training messages above.\n dietChartCreated: { title: 'Diet chart created' },\n dietChartUpdated: { title: 'Diet chart saved' },\n dietChartDeleted: {\n title: 'Diet chart deleted',\n description: 'Members on this chart no longer have one.',\n },\n dietChartAssigned: { title: 'Diet chart assigned' },\n dietChartCleared: { title: 'Diet chart removed' },\n foodCreated: { title: 'Food added' },\n foodUpdated: { title: 'Food saved' },\n foodDeleted: {\n title: 'Food removed',\n description: 'It no longer appears in any chart that used it.',\n },\n\n // Roster (owner console)\n attendanceMarked: { title: 'Attendance saved' },\n memberMarkedInactive: {\n title: 'Member marked inactive',\n description: 'They can no longer check in.',\n },\n memberMarkedActive: { title: 'Member reactivated' },\n memberDeleted: { title: 'Member removed' },\n /**\n * Says what actually happened. Assigning a plan no longer starts it —\n * nothing does until the payment is marked done — so a bare \"Plan\n * updated\" would send the owner away believing the member could train.\n */\n memberPlanAssigned: {\n title: 'Plan assigned',\n description: 'It starts once you mark the payment done.',\n },\n memberMembershipPaused: { title: 'Membership paused' },\n memberMembershipCancelled: { title: 'Membership cancelled' },\n paymentCollected: { title: 'Payment recorded' },\n\n // Sessions\n checkedIn: { title: 'Checked in', description: 'Your session has started.' },\n checkedOut: { title: 'Checked out', description: 'Session saved.' },\n checkInQrRotated: {\n title: 'New QR generated',\n description: 'Print it and replace the old poster.',\n },\n\n // Membership join requests\n membershipRequestSent: {\n title: 'Request sent',\n description: 'The gym will review it shortly.',\n },\n membershipRequestApproved: {\n title: 'Member approved',\n description: 'They can now check in at your gym.',\n },\n membershipRequestRejected: {\n title: 'Request declined',\n description: 'The member has been told.',\n },\n\n // Membership payment confirmation\n membershipRequested: {\n title: 'Plan requested',\n description: 'It starts once your gym confirms the payment.',\n },\n membershipRequestWithdrawn: {\n title: 'Request withdrawn',\n description: 'Pick another plan whenever you are ready.',\n },\n /**\n * Says the gym can SEE it, not that the plan has started. The member has just\n * done the only thing left to them and the temptation is to congratulate them\n * with something that sounds like confirmation; the next move is still the\n * gym's, and the screen they are looking at says so.\n */\n membershipProofAttached: {\n title: 'Screenshot sent',\n description: 'Your gym can see it now.',\n },\n membershipPaymentConfirmed: {\n title: 'Payment confirmed',\n description: 'The plan is now active for this member.',\n },\n membershipPaymentRejected: {\n title: 'Payment turned down',\n description: 'The member has been told and can send it again.',\n },\n\n // Gym registration + platform review\n gymRegistered: {\n title: 'Gym submitted',\n description: 'Our team will review it and let you know.',\n },\n gymApproved: {\n title: 'Gym approved',\n description: 'It is now listed for members to find.',\n },\n gymRejected: {\n title: 'Gym rejected',\n description: 'The owner has been told.',\n },\n\n // Engagement\n feedbackSubmitted: {\n title: 'Feedback sent',\n description: 'Thank you for helping us improve.',\n },\n complaintSubmitted: {\n title: 'Complaint submitted',\n description: 'Your gym will look into it.',\n },\n announcementSent: { title: 'Announcement sent' },\n announcementScheduled: { title: 'Announcement scheduled' },\n announcementDraftSaved: { title: 'Draft saved' },\n announcementDeleted: { title: 'Announcement deleted' },\n announcementCancelled: {\n title: 'Announcement cancelled',\n description: 'It will not be sent.',\n },\n\n // Notification feed\n notificationHidden: { title: 'Notification hidden' },\n notificationRestored: { title: 'Notification restored' },\n allNotificationsRead: { title: 'All caught up' },\n\n // Security (role-switch PIN)\n mpinSet: { title: 'PIN set' },\n mpinReset: { title: 'Your PIN has been reset.' },\n mpinResetLinkSent: {\n title: \"We've emailed you a reset link\",\n description: 'Check your inbox.',\n },\n\n // ── Platform console (superadmin / platform manager) ────────────────────────\n platformRolesUpdated: { title: 'Platform roles updated' },\n platformUserSuspended: {\n title: 'Account suspended',\n description: 'They can no longer sign in.',\n },\n platformUserReinstated: { title: 'Account reinstated' },\n platformUserDeleted: {\n title: 'Account deleted',\n description: 'It is hidden everywhere but can still be restored.',\n },\n platformUserRestored: { title: 'Account restored' },\n platformGymDeleted: {\n title: 'Gym deleted',\n description: 'It is hidden everywhere but can still be restored.',\n },\n platformGymRestored: {\n title: 'Gym restored',\n description: 'It is back in the directory and its owner has the console again.',\n },\n} as const satisfies Record<string, ResultMessage>;\n\nexport type SuccessMessageKey = keyof typeof SUCCESS_MESSAGE;\n\n/** Success messages that name the thing they acted on. */\nexport const SUCCESS_MESSAGE_FOR = {\n memberAdded: (name: string): ResultMessage => ({\n title: 'Member added',\n description: `Share the invite with ${name}.`,\n }),\n staffAdded: (name: string): ResultMessage => ({\n title: 'Staff added',\n description: `Share the invite with ${name}.`,\n }),\n inviteClaimed: (gymName: string): ResultMessage => ({\n title: \"You're all set\",\n description: `Your account is linked to ${gymName}.`,\n }),\n roleSwitched: (roleLabel: string): ResultMessage => ({\n title: `Switched to ${roleLabel}`,\n }),\n gymApprovedFor: (gymName: string): ResultMessage => ({\n title: 'Gym approved',\n description: `${gymName} is now live on GymMonk.`,\n }),\n gymRejectedFor: (gymName: string): ResultMessage => ({\n title: 'Gym rejected',\n description: `The owner of ${gymName} has been told why.`,\n }),\n} as const;\n\n// ─── Error messages ──────────────────────────────────────────────────────────\n\n/**\n * Failure copy. Transport entries describe a request that never reached the\n * API; the rest are domain rules the backend enforces and the client can also\n * check up-front — same wording either way.\n */\nexport const ERROR_MESSAGE = {\n // Transport / generic\n generic: 'Something went wrong. Please try again.',\n network: 'Network error. Check your connection and try again.',\n timeout: 'That took too long. Please try again.',\n sessionExpired: 'Your session expired. Please sign in again.',\n\n // Client-side validation\n formInvalid: 'Please check the highlighted fields.',\n\n // Onboarding\n roleRequired: 'Choose a role to continue',\n ownerOnboardingFailed: 'We could not create your gym. Please try again.',\n memberOnboardingFailed: 'We could not save your details. Please try again.',\n\n // ── Gym registration (\"list your gym\") ─────────────────────────────────────\n gymRegistrationFailed: 'We could not register your gym. Please try again.',\n /**\n * The wizard could not read what the owner had already saved.\n *\n * It refuses to open on a blank form rather than risk the next Continue\n * overwriting a real draft, so this is the whole screen, not a toast.\n */\n gymRegistrationDraftLoadFailed:\n 'We could not open your saved gym details. Check your connection and try again.',\n /**\n * The step the wizard tried to save is implausibly large.\n *\n * A guard against a client sending something absurd rather than a limit the\n * real form approaches, but it is raised by the SERVER and shown verbatim in\n * the step-save toast — so the wording lives here with the rest of the copy,\n * not as a hand-written string at the throw site.\n */\n gymRegistrationDraftTooLarge:\n 'Those gym details are too large to save. Please shorten the descriptions and try again.',\n /**\n * \"Near me\" found nothing inside the radius.\n *\n * Deliberately not the same as `gymSearchNoResults`: this member searched\n * nowhere in particular, so telling them to refine their search would be\n * advice they cannot act on. What helps is a different place or a gym id.\n */\n gymSearchNoneNearby:\n 'No gyms within 50 km of you yet. Try a different location, or enter a gym id if you have one.',\n /** One organisation per account — registering a second is not supported. */\n gymAlreadyRegistered: 'You have already registered a gym on this account.',\n /** Registering a gym is something a MEMBER does, so the profile must exist. */\n gymRegistrationNeedsProfile: 'Finish setting up your profile before registering a gym.',\n /** Every owner action other than editing their own details, before approval. */\n gymAwaitingApproval:\n 'Your gym is waiting for approval. You can manage it once our team has reviewed it.',\n /** The reviewer turned the registration down. */\n gymRegistrationRejected: 'Your gym registration was not approved.',\n organisationNotFound: 'That gym could not be found.',\n\n // ── Platform console ────────────────────────────────────────────────────────\n /** The account is gone, or was already erased. */\n platformUserNotFound: 'That account could not be found.',\n /**\n * An admin acting on their OWN row. Suspending or deleting yourself takes away\n * the access needed to undo it, so the console refuses rather than letting one\n * mis-tap lock the platform's last superadmin out of it.\n */\n platformCannotActOnSelf: 'You cannot do that to your own account.',\n /**\n * Removing the last superadmin. `manage GymApproval` is held by nobody else,\n * so the gym review queue would become unreachable with no way back in short\n * of a database edit.\n */\n platformLastSuperadmin: 'The platform must keep at least one superadmin.',\n /** The typed confirmation did not match the record being deleted. */\n platformConfirmationMismatch: 'That did not match. Nothing was changed.',\n /** Two reviewers acting on the same registration; the second one loses. */\n organisationAlreadyDecided: 'Someone has already reviewed this gym.',\n /** A step failed to persist — the user stays put so nothing is lost. */\n onboardingStepSaveFailed: 'We could not save this step. Please try again.',\n\n // Gym structure prerequisites\n centerRequiredForPlan: 'Pick the center this plan belongs to.',\n planVariantRequired: 'Add at least one pricing variant before saving the plan.',\n planNameTaken: 'This center already has a plan with that name. Pick another name.',\n planVariantDurationRequired: 'Enter how long this variant runs for',\n planVariantPriceRequired: 'Enter the price for this variant',\n /** A \"discount\" that raises the price is a typo, every time. */\n planFinalPriceAboveOriginal: 'The final price cannot be more than the original price',\n centerAddressRequired: 'Add the center address before creating it.',\n noCenterForPlans: 'No gym center found. Add a center before creating plans.',\n noCenterForWorkouts: 'No gym center found. Add a center before creating workouts.',\n noCenterForAnnouncements: 'No gym center found. Add a center before sending announcements.',\n announcementAlreadySent: 'That announcement has already gone out, so it cannot be cancelled.',\n\n // Notification feed\n notificationHideFailed: 'Could not hide that notification.',\n notificationRestoreFailed: 'Could not restore that notification.',\n\n // ── Phone, the join key ────────────────────────────────────────────────────\n //\n // The phone number is what ties an app account to a gym's member record, and\n // it is unique in BOTH stores independently. These are the three places a\n // number can collide, and each says what the person can actually do next.\n\n /** Onboarding, or the profile editor: pick another number. */\n phoneAlreadyTaken: 'This phone number is already taken, please enter a different phone number.',\n /**\n * The DESK adding a member. Deliberately different wording from the member's:\n * the desk cannot \"choose another number\", because the number is a fact about\n * a person standing in front of them. What it can do is check it.\n */\n phoneOnThisRoster: 'A member with this phone number is already on your roster.',\n /**\n * Not an error. The number belongs to an existing GymMonk account, which is\n * exactly what makes the invite link work — so this is INFORMATION for the\n * desk, and the create still succeeds.\n */\n phoneHasAccount: 'This number already has a GymMonk account. The invite will link to it.',\n /**\n * The rare third-account case at claim: they asked to take the gym's number,\n * and that number is somebody else's account. Never move a number off another\n * account to satisfy this one.\n */\n phoneOnAnotherAccount:\n 'That number belongs to another GymMonk account. Ask your gym to correct it, or keep your current number.',\n /**\n * A QUESTION, not a refusal, and the copy has to carry that — nobody has done\n * anything wrong. The gym holds a different number than the account does, and\n * only the member can say which is right. The screen shows both, masked, and\n * two buttons.\n */\n invitePhoneMismatch:\n 'Your gym has a different phone number for you. Which number should we use?',\n\n // Membership\n planUnavailable: 'That plan is not available right now.',\n membershipPlanRequired: 'Choose a membership plan to continue',\n /** The member was created, but the plan the owner picked did not stick. */\n initialPlanNotAssigned:\n 'Member added, but the plan could not be assigned. Assign it from their profile.',\n noPlansToAssign: 'No membership plans yet. Create one to assign it while adding a member.',\n /**\n * Not an error the member can act on by trying harder — it is the whole\n * point of the flow, so it reads as a status rather than a refusal.\n */\n membershipAwaitingPayment:\n 'Your gym is checking your payment. The plan starts as soon as they confirm it.',\n membershipNoPendingRequest: 'There is no plan waiting for confirmation.',\n /**\n * Pausing extends the term by the paused days, so pausing something that is\n * not running would push out a date nobody is training against — and pausing\n * an already-paused membership would extend it twice for one absence.\n */\n membershipNotPausable:\n 'Only a running membership can be paused. This one has already ended or is paused.',\n /**\n * The joining date records something that has already happened, so a future\n * one is not a preference to honour — it would date the member's whole\n * billing cycle from a day that has not arrived.\n */\n joiningDateInFuture: 'A joining date cannot be in the future.',\n /**\n * The term moved between the screen being drawn and the button being\n * pressed, which in practice means a second manager confirmed one first.\n * Says which month it now covers rather than a bare \"try again\", because the\n * owner's next question is always \"then what am I paying for?\".\n */\n membershipTermMoved:\n 'Someone just confirmed a payment for this member, so the period has moved on. Reopen their profile to see the current one.',\n /**\n * The owner reached for the roster toggle on a plan that has not been paid\n * for. Points at the action that WOULD start it rather than just refusing.\n */\n membershipPendingUseConfirm:\n 'This plan is waiting for payment confirmation. Mark the payment done to start it.',\n /** Two managers opening the same request; the second one loses. */\n membershipAlreadyDecided: 'Someone has already answered this payment.',\n membershipConfirmFailed: 'Could not confirm that payment. Please try again.',\n membershipRejectFailed: 'Could not turn down that payment. Please try again.',\n membershipWithdrawFailed: 'Could not withdraw that request. Please try again.',\n /** The URL did not come from our own storage — a broken or hostile client. */\n paymentProofInvalid: 'That payment screenshot could not be attached. Upload it again.',\n /** The upload itself worked; saving it against the request did not. */\n paymentProofAttachFailed: 'Could not send that screenshot. Please try again.',\n\n // Training\n workoutPlanRequired: 'Choose a plan to assign',\n // Roster (owner console)\n attendanceMarkFailed: 'Could not save that attendance. Please try again.',\n memberStatusFailed: \"Could not change that member's status. Please try again.\",\n memberDeleteFailed: 'Could not remove that member. Please try again.',\n memberPlanAssignFailed: 'Could not update that plan. Please try again.',\n memberPauseFailed: 'Could not pause that membership. Please try again.',\n memberCancelFailed: 'Could not cancel that membership. Please try again.',\n paymentCollectFailed: 'Could not record that payment. Please try again.',\n paymentAmountRequired: 'Enter the amount collected',\n pauseDatesRequired: 'Pick both pause dates',\n pauseDatesOrder: 'The end date has to be after the start date',\n /**\n * Attendance, workout plans and payments are all keyed on the central-auth\n * user, which an invited record does not have until the person claims it.\n */\n memberNotClaimed: 'This member has not claimed their invite yet.',\n\n // Sessions\n checkInFailed: 'Could not check you in. Please try again.',\n checkOutFailed: 'Could not check you out. Please try again.',\n /** The camera decoded a QR, but it is not a gymmonk check-in poster. */\n qrNotRecognised: 'That is not a gym check-in QR. Point at the poster at the gym.',\n /** A valid gymmonk QR, but for a gym the member does not belong to. */\n qrWrongGym: 'That QR belongs to a different gym.',\n /** The scanned code matches no center — a retired or mistyped poster. */\n qrUnknown: 'This QR is no longer valid. Ask the gym for the current poster.',\n /** Checking out with a poster from somewhere other than where you started. */\n qrWrongGymForCheckOut: 'Scan the QR at the gym where you checked in.',\n /** Manual entry only accepts a full, well-formed code. */\n checkInCodeInvalid: 'Enter the 16-character code printed under the QR.',\n checkInQrRotateFailed: 'Could not generate a new QR. Please try again.',\n /**\n * Ticking an exercise off records it against a live session, so there has to\n * be one. Shown when a member opens an exercise outside a workout and taps\n * Mark As Done.\n */\n noSessionToTrack: 'Check in at your gym to track this workout.',\n\n // ── Membership join requests ───────────────────────────────────────────────\n /** Scanned a valid poster, but the gym has not accepted this member yet. */\n membershipNotApproved:\n 'Your gym has not accepted your join request yet. You can check in once they do.',\n /** Accepted, but with no live plan — check-in needs both. */\n membershipNotActive: 'Your membership plan is not active. Renew it to start checking in again.',\n /** A second request while one is already open. */\n membershipRequestPending: 'You already have a request waiting with this gym.',\n /** Requesting a gym they are already an accepted member of. */\n membershipRequestAlreadyMember: 'You are already a member of this gym.',\n /** v1 memberships are single-center — leave the current gym first. */\n membershipRequestAlreadyAtAnotherGym:\n 'You already belong to a gym. Cancel that membership before joining another.',\n membershipRequestNotFound: 'That join request no longer exists.',\n /** Two staff acting on the same request; the second one loses. */\n membershipRequestAlreadyDecided: 'Someone has already answered this request.',\n membershipRequestFailed: 'Could not send your request. Please try again.',\n /** The gym publishes plans, so joining means picking one of them. */\n membershipRequestNeedsPlan: 'Choose a membership plan to continue.',\n /**\n * A plan that belongs to a different gym, or none at all.\n *\n * ONE message for both, deliberately: telling a caller that an id is real but\n * belongs elsewhere would let anyone map another gym's catalogue by trying\n * ids against their own join request.\n */\n planNotOfferedHere: 'That plan is not offered at this gym.',\n /** The plan exists but the chosen duration does not. */\n planVariantUnknown: 'That option is not offered on this plan.',\n gymCodeUnknown: 'No gym found with that id. Check it with your gym.',\n /** Actions that only make sense once a gym has taken the member on. */\n noGymJoined: 'Join a gym first. You can find one from your Me tab.',\n /** Searching by name needs somewhere to look — see `gymSearchQuerySchema`. */\n gymSearchStateRequired: 'Pick a state to search gyms by name.',\n gymSearchNoResults: 'No gyms matched. Try a different area, or enter the gym id.',\n\n /**\n * Camera (QR scanning)\n *\n * ── THESE USED TO POINT AT A BOX THAT DOES NOT EXIST ──────────────────────\n * Two of them ended \"Enter the code printed under the QR\", and both halves of\n * that sentence were wrong: the scanner has no field to type a code into, and\n * the poster does not print the check-in code at all — it prints the gym's\n * PUBLIC join code, which cannot check anybody in. So a member whose camera\n * failed was sent looking for a box that is not there, to type a number that\n * is not printed.\n *\n * They now point at the thing that IS there: the check-in button under the\n * viewfinder, which needs no code at all.\n */\n cameraDenied:\n 'Camera access is blocked. Allow it in your browser settings, or check in without scanning.',\n cameraUnavailable: 'No camera found on this device. Check in without scanning instead.',\n cameraInsecure: 'Scanning needs a secure (https) connection.',\n cameraFailed: 'Could not start the camera. Check in without scanning instead.',\n /**\n * The member is not attached to a gym, on the codeless path.\n *\n * Its own sentence because that path reached for `qrUnknown` before it had\n * one, and that string opens \"This QR is no longer valid\" — advice about a\n * poster, given to somebody who never scanned one.\n */\n gymUnavailable: 'You are not checked in to a gym yet. Join one from the Me tab first.',\n\n // Engagement\n feedbackRatingRequired: 'Choose a rating to submit your feedback',\n complaintIssueRequired: 'Choose the issue you are reporting',\n\n // Security (role-switch PIN)\n mpinIncorrect: 'Incorrect PIN.',\n mpinVerifyFailed: \"Couldn't verify. Try again.\",\n mpinSetFailed: \"Couldn't set your PIN. Try again.\",\n mpinMismatch: \"Those didn't match. Try again.\",\n mpinResetLinkFailed: \"Couldn't send the reset link. Try again.\",\n mpinResetFailed: \"Couldn't reset your PIN. Try again.\",\n\n // Uploads\n imageUploadFailed: 'Could not upload that image. Please try again.',\n imageProcessFailed: 'Could not process that image. Please try again.',\n} as const satisfies Record<string, string>;\n\nexport type ErrorMessageKey = keyof typeof ERROR_MESSAGE;\n\n/** Error messages that name a limit or value. */\nexport const ERROR_MESSAGE_FOR = {\n maxPhotos: (max: number): string => `You can add up to ${max} photos`,\n /**\n * Refused at the door because the membership is paused and still inside its\n * window.\n *\n * Its own sentence because \"renew your plan\" is wrong advice here twice\n * over: nothing has lapsed, and paying again would not open the door a day\n * sooner. The resume date is the only thing this member wants to know, and\n * it is the reason this one takes a parameter at all.\n */\n membershipPausedUntil: (resumesOn: string): string =>\n `Your membership is paused until ${resumesOn}. You can check in again from that day.`,\n /** Role-switch PIN lockout, in whole minutes remaining. */\n mpinLockedOut: (minutes: number): string =>\n `Too many attempts. Try again in ${minutes} minute${minutes > 1 ? 's' : ''}.`,\n} as const;\n"]}
1
+ {"version":3,"file":"messages.js","sourceRoot":"","sources":["../src/messages.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * gymmonk-schema — API result messages\n * ====================================\n * Single source of truth for every user-facing SUCCESS and ERROR message the\n * product shows, plus the API error codes both sides key off.\n *\n * Why it lives here: the schema package is already the SSOT for data shapes,\n * types and validation. Result copy is part of that contract — the backend\n * raises a message, the client shows it, and neither should invent its own\n * wording. Both repos import from here, so copy changes land in one place and\n * can never drift between server and client.\n *\n * Usage:\n * backend → `throw new BadRequestError(ERROR_MESSAGE.centerAddressRequired)`\n * frontend → `showSuccess(...toast(SUCCESS_MESSAGE.profileUpdated))`\n *\n * @module gymmonk-schema/messages\n */\n\n// ─── API error codes ─────────────────────────────────────────────────────────\n\n/**\n * Machine-readable error codes returned in the API envelope\n * (`{ success: false, error: { code, message } }`). The client can branch on a\n * code; the message is what a human reads.\n */\nexport const ERROR_CODE = {\n // General\n INTERNAL_ERROR: 'INTERNAL_ERROR',\n VALIDATION_ERROR: 'VALIDATION_ERROR',\n NOT_FOUND: 'NOT_FOUND',\n\n // Auth\n INVALID_TOKEN: 'INVALID_TOKEN',\n TOKEN_EXPIRED: 'TOKEN_EXPIRED',\n UNAUTHORIZED: 'UNAUTHORIZED',\n FORBIDDEN: 'FORBIDDEN',\n SESSION_INVALIDATED: 'SESSION_INVALIDATED',\n\n // User\n USER_NOT_FOUND: 'USER_NOT_FOUND',\n USER_ALREADY_EXISTS: 'USER_ALREADY_EXISTS',\n INVALID_ROLE: 'INVALID_ROLE',\n\n // Rate limiting\n RATE_LIMITED: 'RATE_LIMITED',\n RATE_LIMIT_EXCEEDED: 'RATE_LIMIT_EXCEEDED',\n\n /**\n * The caller MAY do this — their subscription simply does not stretch to it.\n *\n * Deliberately NOT `FORBIDDEN`, and the distinction is load-bearing on the\n * client. A role denial means \"this is not yours\"; the answer is to go away.\n * A plan denial means \"this costs money\"; the answer is an upgrade prompt with\n * the price on it. A client that cannot tell them apart either shows an\n * upgrade sheet to a trainer who will never be allowed to buy one, or shows a\n * bare 403 to an owner who would happily have paid.\n *\n * Always accompanied by `details`: `{ feature, currentPlan, requiredPlan,\n * current?, limit? }` — enough for the prompt to name the feature, the tier\n * that unlocks it, and how full the current allowance is.\n */\n PLAN_LIMIT_EXCEEDED: 'PLAN_LIMIT_EXCEEDED',\n\n /**\n * That phone number already belongs to somebody else's account.\n *\n * A code of its own rather than a bare `USER_ALREADY_EXISTS`, because the\n * phone is the join key between an app account and a gym's member record, and\n * the client has to act on this rather than merely print it: onboarding puts\n * the message on the phone FIELD so the person can edit it in place, and the\n * desk adding a member needs to know the number is spoken for before it mints\n * an invite that can never be claimed.\n */\n PHONE_ALREADY_IN_USE: 'PHONE_ALREADY_IN_USE',\n\n /**\n * An already-registered member opened an invite issued to a DIFFERENT number.\n *\n * Not a refusal — a question. The claim stops and asks which number is\n * theirs, and the client re-sends with `phoneChoice`. It carries `details`:\n * `{ gymPhone, myPhone }`, both MASKED, enough to recognise a number without\n * publishing one.\n */\n INVITE_PHONE_MISMATCH: 'INVITE_PHONE_MISMATCH',\n\n // Upstream / dependency unavailable\n SERVICE_UNAVAILABLE: 'SERVICE_UNAVAILABLE',\n} as const;\n\nexport type ErrorCode = (typeof ERROR_CODE)[keyof typeof ERROR_CODE];\n\n// ─── Message shape ───────────────────────────────────────────────────────────\n\n/** A result message: a headline and an optional quieter second line. */\nexport interface ResultMessage {\n title: string;\n description?: string;\n}\n\n// ─── Success messages ────────────────────────────────────────────────────────\n\n/**\n * Confirmation shown after a write succeeds, keyed by action. Interpolating\n * entries are functions so the caller supplies the value without re-wording.\n */\nexport const SUCCESS_MESSAGE = {\n // Onboarding\n memberOnboardingComplete: {\n title: \"You're all set\",\n description: 'Welcome to GymMonk.',\n },\n ownerOnboardingComplete: {\n title: 'Your gym is ready',\n description: 'Welcome to GymMonk.',\n },\n /** Each wizard step is persisted on its own, so each one confirms. */\n onboardingStepSaved: { title: 'Saved' },\n\n // Identity & profile\n profileUpdated: { title: 'Profile updated' },\n organisationUpdated: { title: 'Organisation updated' },\n\n // Gym structure\n centerAdded: { title: 'Center added' },\n centerUpdated: { title: 'Center updated' },\n membershipPlanCreated: { title: 'Membership plan created' },\n membershipPlanUpdated: { title: 'Membership plan updated' },\n equipmentSaved: { title: 'Equipment updated' },\n\n // Membership (member-side)\n membershipUpdated: { title: 'Membership updated' },\n membershipRenewed: { title: 'Membership renewed' },\n membershipCancelled: { title: 'Membership cancelled' },\n membershipPauseRequested: {\n title: 'Pause request sent',\n description: 'Your gym will confirm the pause.',\n },\n\n // Owner SaaS subscription\n subscriptionUpdated: { title: 'Subscription updated' },\n\n // Training\n workoutPlanCreated: { title: 'Workout plan created' },\n workoutPlanUpdated: { title: 'Workout plan saved' },\n workoutPlanDeleted: {\n title: 'Workout plan deleted',\n description: 'Members on this plan no longer have one.',\n },\n workoutCreated: { title: 'Workout created' },\n workoutUpdated: { title: 'Workout saved' },\n workoutDeleted: { title: 'Workout removed' },\n workoutPlanAssigned: { title: 'Workout plan assigned' },\n\n // Diet — the counterparts of the training messages above.\n dietChartCreated: { title: 'Diet chart created' },\n dietChartUpdated: { title: 'Diet chart saved' },\n dietChartDeleted: {\n title: 'Diet chart deleted',\n description: 'Members on this chart no longer have one.',\n },\n dietChartAssigned: { title: 'Diet chart assigned' },\n dietChartCleared: { title: 'Diet chart removed' },\n foodCreated: { title: 'Food added' },\n foodUpdated: { title: 'Food saved' },\n foodDeleted: {\n title: 'Food removed',\n description: 'It no longer appears in any chart that used it.',\n },\n\n // Roster (owner console)\n attendanceMarked: { title: 'Attendance saved' },\n memberMarkedInactive: {\n title: 'Member marked inactive',\n description: 'They can no longer check in.',\n },\n memberMarkedActive: { title: 'Member reactivated' },\n memberDeleted: { title: 'Member removed' },\n /**\n * Says what actually happened. Assigning a plan no longer starts it —\n * nothing does until the payment is marked done — so a bare \"Plan\n * updated\" would send the owner away believing the member could train.\n */\n memberPlanAssigned: {\n title: 'Plan assigned',\n description: 'It starts once you mark the payment done.',\n },\n memberMembershipPaused: { title: 'Membership paused' },\n memberMembershipCancelled: { title: 'Membership cancelled' },\n paymentCollected: { title: 'Payment recorded' },\n\n // Sessions\n checkedIn: { title: 'Checked in', description: 'Your session has started.' },\n checkedOut: { title: 'Checked out', description: 'Session saved.' },\n checkInQrRotated: {\n title: 'New QR generated',\n description: 'Print it and replace the old poster.',\n },\n\n // Membership join requests\n membershipRequestSent: {\n title: 'Request sent',\n description: 'The gym will review it shortly.',\n },\n membershipRequestApproved: {\n title: 'Member approved',\n description: 'They can now check in at your gym.',\n },\n membershipRequestRejected: {\n title: 'Request declined',\n description: 'The member has been told.',\n },\n\n // Membership payment confirmation\n membershipRequested: {\n title: 'Plan requested',\n description: 'It starts once your gym confirms the payment.',\n },\n membershipRequestWithdrawn: {\n title: 'Request withdrawn',\n description: 'Pick another plan whenever you are ready.',\n },\n /**\n * Says the gym can SEE it, not that the plan has started. The member has just\n * done the only thing left to them and the temptation is to congratulate them\n * with something that sounds like confirmation; the next move is still the\n * gym's, and the screen they are looking at says so.\n */\n membershipProofAttached: {\n title: 'Screenshot sent',\n description: 'Your gym can see it now.',\n },\n membershipPaymentConfirmed: {\n title: 'Payment confirmed',\n description: 'The plan is now active for this member.',\n },\n membershipPaymentRejected: {\n title: 'Payment turned down',\n description: 'The member has been told and can send it again.',\n },\n\n // Gym registration + platform review\n gymRegistered: {\n title: 'Gym submitted',\n description: 'Our team will review it and let you know.',\n },\n gymApproved: {\n title: 'Gym approved',\n description: 'It is now listed for members to find.',\n },\n gymRejected: {\n title: 'Gym rejected',\n description: 'The owner has been told.',\n },\n\n // Engagement\n feedbackSubmitted: {\n title: 'Feedback sent',\n description: 'Thank you for helping us improve.',\n },\n complaintSubmitted: {\n title: 'Complaint submitted',\n description: 'Your gym will look into it.',\n },\n announcementSent: { title: 'Announcement sent' },\n announcementScheduled: { title: 'Announcement scheduled' },\n announcementDraftSaved: { title: 'Draft saved' },\n announcementDeleted: { title: 'Announcement deleted' },\n announcementCancelled: {\n title: 'Announcement cancelled',\n description: 'It will not be sent.',\n },\n\n // Notification feed\n notificationHidden: { title: 'Notification hidden' },\n notificationRestored: { title: 'Notification restored' },\n allNotificationsRead: { title: 'All caught up' },\n\n // Security (role-switch PIN)\n mpinSet: { title: 'PIN set' },\n mpinReset: { title: 'Your PIN has been reset.' },\n mpinResetLinkSent: {\n title: \"We've emailed you a reset link\",\n description: 'Check your inbox.',\n },\n\n // ── Platform console (superadmin / platform manager) ────────────────────────\n platformRolesUpdated: { title: 'Platform roles updated' },\n platformUserSuspended: {\n title: 'Account suspended',\n description: 'They can no longer sign in.',\n },\n platformUserReinstated: { title: 'Account reinstated' },\n platformUserDeleted: {\n title: 'Account deleted',\n description: 'It is hidden everywhere but can still be restored.',\n },\n platformUserRestored: { title: 'Account restored' },\n platformGymDeleted: {\n title: 'Gym deleted',\n description: 'It is hidden everywhere but can still be restored.',\n },\n platformGymRestored: {\n title: 'Gym restored',\n description: 'It is back in the directory and its owner has the console again.',\n },\n} as const satisfies Record<string, ResultMessage>;\n\nexport type SuccessMessageKey = keyof typeof SUCCESS_MESSAGE;\n\n/** Success messages that name the thing they acted on. */\nexport const SUCCESS_MESSAGE_FOR = {\n memberAdded: (name: string): ResultMessage => ({\n title: 'Member added',\n description: `Share the invite with ${name}.`,\n }),\n staffAdded: (name: string): ResultMessage => ({\n title: 'Staff added',\n description: `Share the invite with ${name}.`,\n }),\n inviteClaimed: (gymName: string): ResultMessage => ({\n title: \"You're all set\",\n description: `Your account is linked to ${gymName}.`,\n }),\n roleSwitched: (roleLabel: string): ResultMessage => ({\n title: `Switched to ${roleLabel}`,\n }),\n gymApprovedFor: (gymName: string): ResultMessage => ({\n title: 'Gym approved',\n description: `${gymName} is now live on GymMonk.`,\n }),\n gymRejectedFor: (gymName: string): ResultMessage => ({\n title: 'Gym rejected',\n description: `The owner of ${gymName} has been told why.`,\n }),\n} as const;\n\n// ─── Error messages ──────────────────────────────────────────────────────────\n\n/**\n * Failure copy. Transport entries describe a request that never reached the\n * API; the rest are domain rules the backend enforces and the client can also\n * check up-front — same wording either way.\n */\nexport const ERROR_MESSAGE = {\n // Transport / generic\n generic: 'Something went wrong. Please try again.',\n network: 'Network error. Check your connection and try again.',\n timeout: 'That took too long. Please try again.',\n sessionExpired: 'Your session expired. Please sign in again.',\n\n // Client-side validation\n formInvalid: 'Please check the highlighted fields.',\n\n // Onboarding\n roleRequired: 'Choose a role to continue',\n ownerOnboardingFailed: 'We could not create your gym. Please try again.',\n memberOnboardingFailed: 'We could not save your details. Please try again.',\n\n // ── Gym registration (\"list your gym\") ─────────────────────────────────────\n gymRegistrationFailed: 'We could not register your gym. Please try again.',\n /**\n * The wizard could not read what the owner had already saved.\n *\n * It refuses to open on a blank form rather than risk the next Continue\n * overwriting a real draft, so this is the whole screen, not a toast.\n */\n gymRegistrationDraftLoadFailed:\n 'We could not open your saved gym details. Check your connection and try again.',\n /**\n * The step the wizard tried to save is implausibly large.\n *\n * A guard against a client sending something absurd rather than a limit the\n * real form approaches, but it is raised by the SERVER and shown verbatim in\n * the step-save toast — so the wording lives here with the rest of the copy,\n * not as a hand-written string at the throw site.\n */\n gymRegistrationDraftTooLarge:\n 'Those gym details are too large to save. Please shorten the descriptions and try again.',\n /**\n * \"Near me\" found nothing inside the radius.\n *\n * Deliberately not the same as `gymSearchNoResults`: this member searched\n * nowhere in particular, so telling them to refine their search would be\n * advice they cannot act on. What helps is a different place or a gym id.\n */\n gymSearchNoneNearby:\n 'No gyms within 50 km of you yet. Try a different location, or enter a gym id if you have one.',\n /** One organisation per account — registering a second is not supported. */\n gymAlreadyRegistered: 'You have already registered a gym on this account.',\n /** Registering a gym is something a MEMBER does, so the profile must exist. */\n gymRegistrationNeedsProfile: 'Finish setting up your profile before registering a gym.',\n /** Every owner action other than editing their own details, before approval. */\n gymAwaitingApproval:\n 'Your gym is waiting for approval. You can manage it once our team has reviewed it.',\n /** The reviewer turned the registration down. */\n gymRegistrationRejected: 'Your gym registration was not approved.',\n organisationNotFound: 'That gym could not be found.',\n\n // ── Platform console ────────────────────────────────────────────────────────\n /** The account is gone, or was already erased. */\n platformUserNotFound: 'That account could not be found.',\n /**\n * An admin acting on their OWN row. Suspending or deleting yourself takes away\n * the access needed to undo it, so the console refuses rather than letting one\n * mis-tap lock the platform's last superadmin out of it.\n */\n platformCannotActOnSelf: 'You cannot do that to your own account.',\n /**\n * Removing the last superadmin. `manage GymApproval` is held by nobody else,\n * so the gym review queue would become unreachable with no way back in short\n * of a database edit.\n */\n platformLastSuperadmin: 'The platform must keep at least one superadmin.',\n /** The typed confirmation did not match the record being deleted. */\n platformConfirmationMismatch: 'That did not match. Nothing was changed.',\n /** Two reviewers acting on the same registration; the second one loses. */\n organisationAlreadyDecided: 'Someone has already reviewed this gym.',\n /** A step failed to persist — the user stays put so nothing is lost. */\n onboardingStepSaveFailed: 'We could not save this step. Please try again.',\n\n // Gym structure prerequisites\n centerRequiredForPlan: 'Pick the center this plan belongs to.',\n planVariantRequired: 'Add at least one pricing variant before saving the plan.',\n planNameTaken: 'This center already has a plan with that name. Pick another name.',\n planVariantDurationRequired: 'Enter how long this variant runs for',\n planVariantPriceRequired: 'Enter the price for this variant',\n /** A \"discount\" that raises the price is a typo, every time. */\n planFinalPriceAboveOriginal: 'The final price cannot be more than the original price',\n centerAddressRequired: 'Add the center address before creating it.',\n noCenterForPlans: 'No gym center found. Add a center before creating plans.',\n noCenterForWorkouts: 'No gym center found. Add a center before creating workouts.',\n noCenterForAnnouncements: 'No gym center found. Add a center before sending announcements.',\n announcementAlreadySent: 'That announcement has already gone out, so it cannot be cancelled.',\n\n // Notification feed\n notificationHideFailed: 'Could not hide that notification.',\n notificationRestoreFailed: 'Could not restore that notification.',\n\n // ── Phone, the join key ────────────────────────────────────────────────────\n //\n // The phone number is what ties an app account to a gym's member record, and\n // it is unique in BOTH stores independently. These are the three places a\n // number can collide, and each says what the person can actually do next.\n\n /** Onboarding, or the profile editor: pick another number. */\n phoneAlreadyTaken: 'This phone number is already taken, please enter a different phone number.',\n /**\n * The DESK adding a member. Deliberately different wording from the member's:\n * the desk cannot \"choose another number\", because the number is a fact about\n * a person standing in front of them. What it can do is check it.\n */\n phoneOnThisRoster: 'A member with this phone number is already on your roster.',\n /**\n * Not an error. The number belongs to an existing GymMonk account, which is\n * exactly what makes the invite link work — so this is INFORMATION for the\n * desk, and the create still succeeds.\n */\n phoneHasAccount: 'This number already has a GymMonk account. The invite will link to it.',\n /**\n * The rare third-account case at claim: they asked to take the gym's number,\n * and that number is somebody else's account. Never move a number off another\n * account to satisfy this one.\n */\n phoneOnAnotherAccount:\n 'That number belongs to another GymMonk account. Ask your gym to correct it, or keep your current number.',\n /**\n * A QUESTION, not a refusal, and the copy has to carry that — nobody has done\n * anything wrong. The gym holds a different number than the account does, and\n * only the member can say which is right. The screen shows both, masked, and\n * two buttons.\n */\n invitePhoneMismatch: 'Your gym has a different phone number for you. Which number should we use?',\n\n // Membership\n planUnavailable: 'That plan is not available right now.',\n membershipPlanRequired: 'Choose a membership plan to continue',\n /** The member was created, but the plan the owner picked did not stick. */\n initialPlanNotAssigned:\n 'Member added, but the plan could not be assigned. Assign it from their profile.',\n noPlansToAssign: 'No membership plans yet. Create one to assign it while adding a member.',\n /**\n * Not an error the member can act on by trying harder — it is the whole\n * point of the flow, so it reads as a status rather than a refusal.\n */\n membershipAwaitingPayment:\n 'Your gym is checking your payment. The plan starts as soon as they confirm it.',\n membershipNoPendingRequest: 'There is no plan waiting for confirmation.',\n /**\n * Pausing extends the term by the paused days, so pausing something that is\n * not running would push out a date nobody is training against — and pausing\n * an already-paused membership would extend it twice for one absence.\n */\n membershipNotPausable:\n 'Only a running membership can be paused. This one has already ended or is paused.',\n /**\n * The joining date records something that has already happened, so a future\n * one is not a preference to honour — it would date the member's whole\n * billing cycle from a day that has not arrived.\n */\n joiningDateInFuture: 'A joining date cannot be in the future.',\n /**\n * The term moved between the screen being drawn and the button being\n * pressed, which in practice means a second manager confirmed one first.\n * Says which month it now covers rather than a bare \"try again\", because the\n * owner's next question is always \"then what am I paying for?\".\n */\n membershipTermMoved:\n 'Someone just confirmed a payment for this member, so the period has moved on. Reopen their profile to see the current one.',\n /**\n * The owner reached for the roster toggle on a plan that has not been paid\n * for. Points at the action that WOULD start it rather than just refusing.\n */\n membershipPendingUseConfirm:\n 'This plan is waiting for payment confirmation. Mark the payment done to start it.',\n /** Two managers opening the same request; the second one loses. */\n membershipAlreadyDecided: 'Someone has already answered this payment.',\n membershipConfirmFailed: 'Could not confirm that payment. Please try again.',\n membershipRejectFailed: 'Could not turn down that payment. Please try again.',\n membershipWithdrawFailed: 'Could not withdraw that request. Please try again.',\n /** The URL did not come from our own storage — a broken or hostile client. */\n paymentProofInvalid: 'That payment screenshot could not be attached. Upload it again.',\n /** The upload itself worked; saving it against the request did not. */\n paymentProofAttachFailed: 'Could not send that screenshot. Please try again.',\n\n // Training\n workoutPlanRequired: 'Choose a plan to assign',\n // Roster (owner console)\n attendanceMarkFailed: 'Could not save that attendance. Please try again.',\n memberStatusFailed: \"Could not change that member's status. Please try again.\",\n memberDeleteFailed: 'Could not remove that member. Please try again.',\n memberPlanAssignFailed: 'Could not update that plan. Please try again.',\n memberPauseFailed: 'Could not pause that membership. Please try again.',\n memberCancelFailed: 'Could not cancel that membership. Please try again.',\n paymentCollectFailed: 'Could not record that payment. Please try again.',\n paymentAmountRequired: 'Enter the amount collected',\n pauseDatesRequired: 'Pick both pause dates',\n pauseDatesOrder: 'The end date has to be after the start date',\n /**\n * Attendance, workout plans and payments are all keyed on the central-auth\n * user, which an invited record does not have until the person claims it.\n */\n memberNotClaimed: 'This member has not claimed their invite yet.',\n\n // Sessions\n checkInFailed: 'Could not check you in. Please try again.',\n checkOutFailed: 'Could not check you out. Please try again.',\n /** The camera decoded a QR, but it is not a gymmonk check-in poster. */\n qrNotRecognised: 'That is not a gym check-in QR. Point at the poster at the gym.',\n /** A valid gymmonk QR, but for a gym the member does not belong to. */\n qrWrongGym: 'That QR belongs to a different gym.',\n /** The scanned code matches no center — a retired or mistyped poster. */\n qrUnknown: 'This QR is no longer valid. Ask the gym for the current poster.',\n /** Checking out with a poster from somewhere other than where you started. */\n qrWrongGymForCheckOut: 'Scan the QR at the gym where you checked in.',\n /** Manual entry only accepts a full, well-formed code. */\n checkInCodeInvalid: 'Enter the 16-character code printed under the QR.',\n checkInQrRotateFailed: 'Could not generate a new QR. Please try again.',\n /**\n * Ticking an exercise off records it against a live session, so there has to\n * be one. Shown when a member opens an exercise outside a workout and taps\n * Mark As Done.\n */\n noSessionToTrack: 'Check in at your gym to track this workout.',\n\n // ── Membership join requests ───────────────────────────────────────────────\n /** Scanned a valid poster, but the gym has not accepted this member yet. */\n membershipNotApproved:\n 'Your gym has not accepted your join request yet. You can check in once they do.',\n /** Accepted, but with no live plan — check-in needs both. */\n membershipNotActive: 'Your membership plan is not active. Renew it to start checking in again.',\n /** A second request while one is already open. */\n membershipRequestPending: 'You already have a request waiting with this gym.',\n /** Requesting a gym they are already an accepted member of. */\n membershipRequestAlreadyMember: 'You are already a member of this gym.',\n /** v1 memberships are single-center — leave the current gym first. */\n membershipRequestAlreadyAtAnotherGym:\n 'You already belong to a gym. Cancel that membership before joining another.',\n membershipRequestNotFound: 'That join request no longer exists.',\n /** Two staff acting on the same request; the second one loses. */\n membershipRequestAlreadyDecided: 'Someone has already answered this request.',\n membershipRequestFailed: 'Could not send your request. Please try again.',\n /** The gym publishes plans, so joining means picking one of them. */\n membershipRequestNeedsPlan: 'Choose a membership plan to continue.',\n /**\n * A plan that belongs to a different gym, or none at all.\n *\n * ONE message for both, deliberately: telling a caller that an id is real but\n * belongs elsewhere would let anyone map another gym's catalogue by trying\n * ids against their own join request.\n */\n planNotOfferedHere: 'That plan is not offered at this gym.',\n /** The plan exists but the chosen duration does not. */\n planVariantUnknown: 'That option is not offered on this plan.',\n gymCodeUnknown: 'No gym found with that id. Check it with your gym.',\n /** Actions that only make sense once a gym has taken the member on. */\n noGymJoined: 'Join a gym first. You can find one from your Me tab.',\n /** Searching by name needs somewhere to look — see `gymSearchQuerySchema`. */\n gymSearchStateRequired: 'Pick a state to search gyms by name.',\n gymSearchNoResults: 'No gyms matched. Try a different area, or enter the gym id.',\n\n /**\n * Camera (QR scanning)\n *\n * ── THESE USED TO POINT AT A BOX THAT DOES NOT EXIST ──────────────────────\n * Two of them ended \"Enter the code printed under the QR\", and both halves of\n * that sentence were wrong: the scanner has no field to type a code into, and\n * the poster does not print the check-in code at all — it prints the gym's\n * PUBLIC join code, which cannot check anybody in. So a member whose camera\n * failed was sent looking for a box that is not there, to type a number that\n * is not printed.\n *\n * They now point at the thing that IS there: the check-in button under the\n * viewfinder, which needs no code at all.\n */\n cameraDenied:\n 'Camera access is blocked. Allow it in your browser settings, or check in without scanning.',\n cameraUnavailable: 'No camera found on this device. Check in without scanning instead.',\n cameraInsecure: 'Scanning needs a secure (https) connection.',\n cameraFailed: 'Could not start the camera. Check in without scanning instead.',\n /**\n * The member is not attached to a gym, on the codeless path.\n *\n * Its own sentence because that path reached for `qrUnknown` before it had\n * one, and that string opens \"This QR is no longer valid\" — advice about a\n * poster, given to somebody who never scanned one.\n */\n gymUnavailable: 'You are not checked in to a gym yet. Join one from the Me tab first.',\n\n // Engagement\n feedbackRatingRequired: 'Choose a rating to submit your feedback',\n complaintIssueRequired: 'Choose the issue you are reporting',\n\n // Security (role-switch PIN)\n mpinIncorrect: 'Incorrect PIN.',\n mpinVerifyFailed: \"Couldn't verify. Try again.\",\n mpinSetFailed: \"Couldn't set your PIN. Try again.\",\n mpinMismatch: \"Those didn't match. Try again.\",\n mpinResetLinkFailed: \"Couldn't send the reset link. Try again.\",\n mpinResetFailed: \"Couldn't reset your PIN. Try again.\",\n\n // Uploads\n imageUploadFailed: 'Could not upload that image. Please try again.',\n imageProcessFailed: 'Could not process that image. Please try again.',\n} as const satisfies Record<string, string>;\n\nexport type ErrorMessageKey = keyof typeof ERROR_MESSAGE;\n\n/** Error messages that name a limit or value. */\nexport const ERROR_MESSAGE_FOR = {\n maxPhotos: (max: number): string => `You can add up to ${max} photos`,\n /**\n * Refused at the door because the membership is paused and still inside its\n * window.\n *\n * Its own sentence because \"renew your plan\" is wrong advice here twice\n * over: nothing has lapsed, and paying again would not open the door a day\n * sooner. The resume date is the only thing this member wants to know, and\n * it is the reason this one takes a parameter at all.\n */\n membershipPausedUntil: (resumesOn: string): string =>\n `Your membership is paused until ${resumesOn}. You can check in again from that day.`,\n /** Role-switch PIN lockout, in whole minutes remaining. */\n mpinLockedOut: (minutes: number): string =>\n `Too many attempts. Try again in ${minutes} minute${minutes > 1 ? 's' : ''}.`,\n} as const;\n"]}