@dragonmastery/dragoncore-vue 0.0.20 → 0.0.21

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.
Files changed (155) hide show
  1. package/dist/{ChangePasswordPage-DBXchGfn.js → ChangePasswordPage--3XwluwE.js} +2 -2
  2. package/dist/{ChangePasswordPage-DBXchGfn.js.map → ChangePasswordPage--3XwluwE.js.map} +1 -1
  3. package/dist/ChangePasswordPage-CpDPmEml.js +6 -0
  4. package/dist/{ConsentRequired-qMNT-U2T.js → ConsentRequired-C4IRMA0c.js} +26 -17
  5. package/dist/ConsentRequired-C4IRMA0c.js.map +1 -0
  6. package/dist/CreateTeamForm-B4cIuYAf.js +35 -0
  7. package/dist/CreateTeamMemberForm-Chrw1y00.js +35 -0
  8. package/dist/{CreateUserPage-B0iHLsm5.js → CreateUserPage-DLwXeLAq.js} +2 -2
  9. package/dist/{CreateUserPage-B0iHLsm5.js.map → CreateUserPage-DLwXeLAq.js.map} +1 -1
  10. package/dist/CreateUserPage-WruMs7WP.js +6 -0
  11. package/dist/CreditBalanceDashboard-CkcsrZ_e.js +35 -0
  12. package/dist/CreditManagement-Ddvu9dMw.js +35 -0
  13. package/dist/CustomerCreateSupportTicketForm-BKperKGS.js +35 -0
  14. package/dist/{CustomerSupportTicketDetailPage-DyJTKtLU.js → CustomerSupportTicketDetailPage-BdyaKG1v.js} +7 -7
  15. package/dist/{CustomerSupportTicketDetailPage-DyJTKtLU.js.map → CustomerSupportTicketDetailPage-BdyaKG1v.js.map} +1 -1
  16. package/dist/CustomerSupportTicketList-DcbrjDa9.js +35 -0
  17. package/dist/CustomerSupportTicketParent-BeNzUwuP.js +7 -0
  18. package/dist/{CustomerSupportTicketParent-CldxkQ75.js → CustomerSupportTicketParent-HIxwSVdu.js} +2 -2
  19. package/dist/{CustomerSupportTicketParent-CldxkQ75.js.map → CustomerSupportTicketParent-HIxwSVdu.js.map} +1 -1
  20. package/dist/CustomerSupportTicketSuccess-CC967u3y.js +35 -0
  21. package/dist/EditTeamForm-B5Tee5wL.js +35 -0
  22. package/dist/{EditTeamMemberForm-CiNb4nNG.js → EditTeamMemberForm-CaS2GLjV.js} +2 -2
  23. package/dist/{EditTeamMemberForm-CiNb4nNG.js.map → EditTeamMemberForm-CaS2GLjV.js.map} +1 -1
  24. package/dist/EditTeamMemberForm-OtcS8QWt.js +6 -0
  25. package/dist/{EditUserPage-DpV3dm-c.js → EditUserPage-DURc5rmi.js} +3 -3
  26. package/dist/{EditUserPage-DpV3dm-c.js.map → EditUserPage-DURc5rmi.js.map} +1 -1
  27. package/dist/EditUserPage-T4DQlKhf.js +7 -0
  28. package/dist/ForgotPassword-CUifhmqP.js +7 -0
  29. package/dist/{ForgotPassword-roKwDfce.js → ForgotPassword-OjIPi9s9.js} +2 -2
  30. package/dist/{ForgotPassword-roKwDfce.js.map → ForgotPassword-OjIPi9s9.js.map} +1 -1
  31. package/dist/{LoginForm-BGDymDnO.js → LoginForm-9UFnA-fO.js} +49 -47
  32. package/dist/LoginForm-9UFnA-fO.js.map +1 -0
  33. package/dist/LoginForm-Bg7GoZEA.js +7 -0
  34. package/dist/Logout-Bs92csWH.js +7 -0
  35. package/dist/{Logout-Cbw1SacV.js → Logout-YgTgOFUH.js} +3 -3
  36. package/dist/{Logout-Cbw1SacV.js.map → Logout-YgTgOFUH.js.map} +1 -1
  37. package/dist/MfaSetup-BACX5XP-.js +8 -0
  38. package/dist/{MfaSetup-CwYXnvgW.js → MfaSetup-RtFMY_dj.js} +3 -3
  39. package/dist/{MfaSetup-CwYXnvgW.js.map → MfaSetup-RtFMY_dj.js.map} +1 -1
  40. package/dist/{MfaVerify-CIlen2i5.js → MfaVerify-Cvhe8bEM.js} +4 -4
  41. package/dist/{MfaVerify-CIlen2i5.js.map → MfaVerify-Cvhe8bEM.js.map} +1 -1
  42. package/dist/MfaVerify-ak4iSdQ2.js +8 -0
  43. package/dist/{ResetPassword-BgKyXQ4q.js → ResetPassword-BE4mXK9q.js} +2 -2
  44. package/dist/{ResetPassword-BgKyXQ4q.js.map → ResetPassword-BE4mXK9q.js.map} +1 -1
  45. package/dist/ResetPassword-pY1uhTdl.js +7 -0
  46. package/dist/{SavedFiltersPage-BlzfWkaj.js → SavedFiltersPage-DQt6uc8m.js} +27 -26
  47. package/dist/{SavedFiltersPage-BlzfWkaj.js.map → SavedFiltersPage-DQt6uc8m.js.map} +1 -1
  48. package/dist/{Signup-qBqsSYVz.js → Signup-9TjMMnU4.js} +23 -32
  49. package/dist/Signup-9TjMMnU4.js.map +1 -0
  50. package/dist/Signup-Bq-G3D-s.js +9 -0
  51. package/dist/{SignupConsentFlow-DG2IGikE.js → SignupConsentFlow-QUZGKjdB.js} +59 -33
  52. package/dist/SignupConsentFlow-QUZGKjdB.js.map +1 -0
  53. package/dist/{SignupRequirementsPage-DnLpQfB8.js → SignupRequirementsPage-DfbYmpQD.js} +5 -5
  54. package/dist/{SignupRequirementsPage-DnLpQfB8.js.map → SignupRequirementsPage-DfbYmpQD.js.map} +1 -1
  55. package/dist/StaffCreateSupportTicketForm-D0ZuisDk.js +35 -0
  56. package/dist/{StaffSupportTicketDetailPage-D0SjH36N.js → StaffSupportTicketDetailPage-DQdfh6H1.js} +7 -7
  57. package/dist/{StaffSupportTicketDetailPage-D0SjH36N.js.map → StaffSupportTicketDetailPage-DQdfh6H1.js.map} +1 -1
  58. package/dist/StaffSupportTicketList-CiqC05XB.js +35 -0
  59. package/dist/{StaffSupportTicketParent-Dk6RFRMt.js → StaffSupportTicketParent-CilR4RGM.js} +2 -2
  60. package/dist/{StaffSupportTicketParent-Dk6RFRMt.js.map → StaffSupportTicketParent-CilR4RGM.js.map} +1 -1
  61. package/dist/StaffSupportTicketParent-DkV329NI.js +7 -0
  62. package/dist/StaffSupportTicketSuccess-CUYnimaI.js +35 -0
  63. package/dist/{SupportStaffPage-DFcgP8iE.js → SupportStaffPage-KKugAnFm.js} +5 -5
  64. package/dist/{SupportStaffPage-DFcgP8iE.js.map → SupportStaffPage-KKugAnFm.js.map} +1 -1
  65. package/dist/{SupportTicketMaintenancePage-BCW0eZxV.js → SupportTicketMaintenancePage-smItdkrD.js} +4 -4
  66. package/dist/{SupportTicketMaintenancePage-BCW0eZxV.js.map → SupportTicketMaintenancePage-smItdkrD.js.map} +1 -1
  67. package/dist/TeamAttachmentsTab-DUtCD1Yi.js +35 -0
  68. package/dist/TeamHistoryTab-BsUoH4VK.js +4 -0
  69. package/dist/{TeamHistoryTab-PVS8A-6K.js → TeamHistoryTab-D5biUPmq.js} +2 -2
  70. package/dist/{TeamHistoryTab-PVS8A-6K.js.map → TeamHistoryTab-D5biUPmq.js.map} +1 -1
  71. package/dist/TeamList-BkPIqZ8V.js +35 -0
  72. package/dist/TeamMemberList-1mxUGCNa.js +35 -0
  73. package/dist/TeamMemberParent-DzeBIElY.js +35 -0
  74. package/dist/{TeamNotesTab-D7ELC1EW.js → TeamNotesTab-BzGZZ1h8.js} +4 -4
  75. package/dist/{TeamNotesTab-D7ELC1EW.js.map → TeamNotesTab-BzGZZ1h8.js.map} +1 -1
  76. package/dist/TeamNotesTab-ClHl2nXd.js +7 -0
  77. package/dist/TeamParent-DJa9UZTP.js +35 -0
  78. package/dist/{TimelineNoteInput-D-NjzUiF.js → TimelineNoteInput-0p-M4Qie.js} +2 -2
  79. package/dist/{TimelineNoteInput-D-NjzUiF.js.map → TimelineNoteInput-0p-M4Qie.js.map} +1 -1
  80. package/dist/{TimelineSystemEvent-Cc6HMeO3.js → TimelineSystemEvent-BHzFr46C.js} +4 -4
  81. package/dist/{TimelineSystemEvent-Cc6HMeO3.js.map → TimelineSystemEvent-BHzFr46C.js.map} +1 -1
  82. package/dist/UserListPage-BTLE4J0s.js +4 -0
  83. package/dist/{UserListPage-DdJFeLP1.js → UserListPage-DUE5gJTo.js} +2 -2
  84. package/dist/{UserListPage-DdJFeLP1.js.map → UserListPage-DUE5gJTo.js.map} +1 -1
  85. package/dist/{UserProfilePage-BhCxv0N9.js → UserProfilePage-C3b93Keh.js} +4 -4
  86. package/dist/{UserProfilePage-BhCxv0N9.js.map → UserProfilePage-C3b93Keh.js.map} +1 -1
  87. package/dist/UserProfilePage-CVTORtSx.js +7 -0
  88. package/dist/VerifyEmail-DCP4DWIw.js +9 -0
  89. package/dist/VerifyEmail-DlOmWGG-.js +257 -0
  90. package/dist/VerifyEmail-DlOmWGG-.js.map +1 -0
  91. package/dist/ViewTeam-DVfnLMhV.js +35 -0
  92. package/dist/ViewTeamMember-L4v3gCIn.js +35 -0
  93. package/dist/index.d.ts +703 -705
  94. package/dist/index.js +26 -25
  95. package/dist/{mfaSchema-s-T8m-7-.js → mfaSchema-BnRWf0ma.js} +1 -1
  96. package/dist/{mfaSchema-s-T8m-7-.js.map → mfaSchema-BnRWf0ma.js.map} +1 -1
  97. package/dist/{src--FuqlDhU.js → src-QZJyMfGX.js} +82 -67
  98. package/dist/src-QZJyMfGX.js.map +1 -0
  99. package/dist/useEmailVerificationChannel-BNi926Ho.js +37 -0
  100. package/dist/useEmailVerificationChannel-BNi926Ho.js.map +1 -0
  101. package/dist/{useMutation-Dhx2gMgS.js → useMutation-BTsyHKyn.js} +3 -3
  102. package/dist/{useMutation-Dhx2gMgS.js.map → useMutation-BTsyHKyn.js.map} +1 -1
  103. package/dist/{useQuery-DxmMxM8z.js → useQuery-BggIE52P.js} +3 -3
  104. package/dist/{useQuery-DxmMxM8z.js.map → useQuery-BggIE52P.js.map} +1 -1
  105. package/dist/{useQueryCache-CJKZquh6.js → useQueryCache-Bjm-S8v5.js} +2 -2
  106. package/dist/{useQueryCache-CJKZquh6.js.map → useQueryCache-Bjm-S8v5.js.map} +1 -1
  107. package/dist/{useRpcAuth-Bse-lggK.js → useRpcAuth-rmHf7bYx.js} +40 -1
  108. package/dist/useRpcAuth-rmHf7bYx.js.map +1 -0
  109. package/package.json +2 -2
  110. package/dist/ChangePasswordPage-Re323roR.js +0 -6
  111. package/dist/ConsentRequired-qMNT-U2T.js.map +0 -1
  112. package/dist/CreateTeamForm-DXN1hoJh.js +0 -34
  113. package/dist/CreateTeamMemberForm-CLHT1HN_.js +0 -34
  114. package/dist/CreateUserPage-C8107z_O.js +0 -6
  115. package/dist/CreditBalanceDashboard-D7MFKfh6.js +0 -34
  116. package/dist/CreditManagement-A8hVPoSp.js +0 -34
  117. package/dist/CustomerCreateSupportTicketForm-B8JQNC1I.js +0 -34
  118. package/dist/CustomerSupportTicketList-DR-UfcGr.js +0 -34
  119. package/dist/CustomerSupportTicketParent-C-KzT4qQ.js +0 -7
  120. package/dist/CustomerSupportTicketSuccess-SBdIcS-_.js +0 -34
  121. package/dist/EditTeamForm-BDQkhBbx.js +0 -34
  122. package/dist/EditTeamMemberForm-CBxFLoIy.js +0 -6
  123. package/dist/EditUserPage-BWKrAKZZ.js +0 -7
  124. package/dist/ForgotPassword-D3OQqbrD.js +0 -7
  125. package/dist/LoginForm-BGDymDnO.js.map +0 -1
  126. package/dist/LoginForm-C97dUsU3.js +0 -7
  127. package/dist/Logout-DY3iorah.js +0 -7
  128. package/dist/MfaSetup-DAQV8MhP.js +0 -8
  129. package/dist/MfaVerify-D-_oX6gL.js +0 -8
  130. package/dist/ResetPassword-CkPqUFbq.js +0 -7
  131. package/dist/Signup-C2FshPnc.js +0 -8
  132. package/dist/Signup-qBqsSYVz.js.map +0 -1
  133. package/dist/SignupConsentFlow-DG2IGikE.js.map +0 -1
  134. package/dist/StaffCreateSupportTicketForm-BrGB7tqD.js +0 -34
  135. package/dist/StaffSupportTicketList-HA4NlkKE.js +0 -34
  136. package/dist/StaffSupportTicketParent-BTbpNdfc.js +0 -7
  137. package/dist/StaffSupportTicketSuccess-CTeMG_iK.js +0 -34
  138. package/dist/TeamAttachmentsTab-IaRtuF55.js +0 -34
  139. package/dist/TeamHistoryTab-DWcVhkwC.js +0 -4
  140. package/dist/TeamList-BNo_ime8.js +0 -34
  141. package/dist/TeamMemberList-DJKYxfsx.js +0 -34
  142. package/dist/TeamMemberParent-Bk6dqXsh.js +0 -34
  143. package/dist/TeamNotesTab-JRWYpqRJ.js +0 -7
  144. package/dist/TeamParent-TSWT_0bK.js +0 -34
  145. package/dist/UserListPage-BjHbDpvC.js +0 -4
  146. package/dist/UserProfilePage-BxIMig4s.js +0 -7
  147. package/dist/VerifyEmail-BYSYk5ef.js +0 -7
  148. package/dist/VerifyEmail-DXYcjCX4.js +0 -176
  149. package/dist/VerifyEmail-DXYcjCX4.js.map +0 -1
  150. package/dist/VerifyEmailRequired-DeMYFS0I.js +0 -89
  151. package/dist/VerifyEmailRequired-DeMYFS0I.js.map +0 -1
  152. package/dist/ViewTeam-DIxy437n.js +0 -34
  153. package/dist/ViewTeamMember-DIaIqfbX.js +0 -34
  154. package/dist/src--FuqlDhU.js.map +0 -1
  155. package/dist/useRpcAuth-Bse-lggK.js.map +0 -1
@@ -1,15 +1,29 @@
1
- import { l as useUserSessionStore, m as useEnv } from "./useRpcAuth-Bse-lggK.js";
2
- import { t as useMutation } from "./useMutation-Dhx2gMgS.js";
1
+ import { l as useUserSessionStore, m as useEnv } from "./useRpcAuth-rmHf7bYx.js";
2
+ import { t as useMutation } from "./useMutation-BTsyHKyn.js";
3
3
  import { t as AppLink_default } from "./AppLink-CHMMrSFI.js";
4
- import { i as setEmailVerificationReturnUrl, o as withReturnUrl, r as getValidReturnUrl, t as getAndClearEmailVerificationReturnUrl } from "./useReturnUrl-qFeazn-G.js";
4
+ import { i as setEmailVerificationReturnUrl, o as withReturnUrl, r as getValidReturnUrl } from "./useReturnUrl-qFeazn-G.js";
5
5
  import { n as SIGNUP_REQUIREMENTS_KEY, t as useSignupPendingData } from "./useSignupPendingData-BWHwUHhL.js";
6
- import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, inject, onUnmounted, openBlock, ref, renderList, toDisplayString, unref, watch, withCtx } from "vue";
6
+ import { t as useEmailVerificationChannel } from "./useEmailVerificationChannel-BNi926Ho.js";
7
+ import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, inject, openBlock, ref, renderList, toDisplayString, unref, withCtx } from "vue";
7
8
  import { jwtDecode } from "jwt-decode";
8
9
  import { useRoute, useRouter } from "vue-router";
9
10
  import { toast } from "vue3-toastify";
10
11
  import { signupSchema } from "@dragonmastery/dragoncore-shared";
11
12
  import { useForm, withMetadata } from "@dragonmastery/zinia-forms-core";
12
13
 
14
+ //#region src/slices/auth/utils/isEmailVerificationRequiredError.ts
15
+ /**
16
+ * Detects if an error indicates that email verification is required before login.
17
+ * Used in signup flow when auto-login after signup fails due to unverified email.
18
+ */
19
+ function isEmailVerificationRequiredError(error) {
20
+ if (!error || typeof error !== "object") return false;
21
+ const e = error;
22
+ if (e.error_type === "EmailVerificationRequiredError" || e.error_name === "EmailVerificationRequiredError" || e.name === "EmailVerificationRequiredError") return true;
23
+ return (typeof e.message === "string" ? e.message : "").includes("Please verify your email before logging in");
24
+ }
25
+
26
+ //#endregion
13
27
  //#region src/slices/auth/features/signup/signupSchema.ts
14
28
  const signupSchemaWithMetadata = withMetadata(signupSchema, "signupSchema", {
15
29
  email: {
@@ -38,7 +52,7 @@ const signupSchemaWithMetadata = withMetadata(signupSchema, "signupSchema", {
38
52
 
39
53
  //#endregion
40
54
  //#region src/slices/auth/features/signup/Signup.vue
41
- const _hoisted_1 = { class: "max-w-2xl mx-auto bg-base-200 p-6 rounded-xl shadow-md container" };
55
+ const _hoisted_1 = { class: "max-w-md mx-auto bg-base-200 p-6 rounded-xl shadow-md container" };
42
56
  const _hoisted_2 = {
43
57
  key: 0,
44
58
  class: "space-y-4 text-center"
@@ -56,17 +70,10 @@ const _hoisted_6 = { class: "list-disc list-inside space-y-1 text-sm text-base-c
56
70
  const _hoisted_7 = ["href"];
57
71
  const _hoisted_8 = { key: 1 };
58
72
  const _hoisted_9 = { class: "text-center mt-2" };
59
- const AUTH_CHANNEL = "auth";
60
73
  const _sfc_main = /* @__PURE__ */ defineComponent({
61
74
  __name: "Signup",
62
75
  setup(__props) {
63
76
  const REDIRECTED_TO_CONSENTS = Symbol("redirected-to-consents");
64
- function isEmailVerificationRequiredError(error) {
65
- if (!error || typeof error !== "object") return false;
66
- const e = error;
67
- if (e.error_type === "EmailVerificationRequiredError" || e.error_name === "EmailVerificationRequiredError" || e.name === "EmailVerificationRequiredError") return true;
68
- return (typeof e.message === "string" ? e.message : "").includes("Please verify your email before logging in");
69
- }
70
77
  const { form, zinia, ZiniaForm, ZiniaSubmitButton } = useForm(signupSchemaWithMetadata, {
71
78
  storeName: "signup-form",
72
79
  persistToLocalStorage: false,
@@ -114,7 +121,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
114
121
  setEmailVerificationReturnUrl(getValidReturnUrl(route, "/"));
115
122
  throw loginError;
116
123
  }
117
- const verifyPath = withReturnUrl("/auth/verify-email-required", returnUrl.value);
124
+ const verifyPath = withReturnUrl("/auth/verify-email", returnUrl.value);
118
125
  await router.push(verifyPath);
119
126
  throw loginError;
120
127
  }
@@ -130,7 +137,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
130
137
  const defaultRedirect = getValidReturnUrl(route, "/");
131
138
  const redirectTo = emailVerificationMode !== "disabled" ? (() => {
132
139
  try {
133
- return jwtDecode(payload.user_details_token).details?.user?.email_verified ?? true ? defaultRedirect : withReturnUrl("/auth/verify-email-required", returnUrl.value);
140
+ return jwtDecode(payload.user_details_token).details?.user?.email_verified ?? true ? defaultRedirect : withReturnUrl("/auth/verify-email", returnUrl.value);
134
141
  } catch {
135
142
  return defaultRedirect;
136
143
  }
@@ -144,23 +151,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
144
151
  const message = error instanceof Error ? error.message : "Registration failed";
145
152
  toast.error(message);
146
153
  };
147
- let authChannel = null;
148
- watch(awaitingVerification, (isAwaiting) => {
149
- authChannel?.close();
150
- authChannel = null;
151
- if (!isAwaiting) return;
152
- authChannel = new BroadcastChannel(AUTH_CHANNEL);
153
- authChannel.onmessage = (event) => {
154
- if (event.data?.type === "email_verified") {
155
- const targetUrl = getAndClearEmailVerificationReturnUrl() ?? getValidReturnUrl(route, "/");
156
- router.push(targetUrl);
157
- }
158
- };
159
- }, { immediate: true });
160
- onUnmounted(() => {
161
- authChannel?.close();
162
- authChannel = null;
163
- });
154
+ useEmailVerificationChannel(awaitingVerification, (targetUrl) => router.push(targetUrl), () => getValidReturnUrl(route, "/"));
164
155
  return (_ctx, _cache) => {
165
156
  return openBlock(), createElementBlock("div", _hoisted_1, [
166
157
  _cache[5] || (_cache[5] = createElementVNode("h1", { class: "text-2xl font-bold mb-6 text-center" }, "Sign Up", -1)),
@@ -210,4 +201,4 @@ var Signup_default = _sfc_main;
210
201
 
211
202
  //#endregion
212
203
  export { signupSchemaWithMetadata as n, Signup_default as t };
213
- //# sourceMappingURL=Signup-qBqsSYVz.js.map
204
+ //# sourceMappingURL=Signup-9TjMMnU4.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Signup-9TjMMnU4.js","names":[],"sources":["../src/slices/auth/utils/isEmailVerificationRequiredError.ts","../src/slices/auth/features/signup/signupSchema.ts","../src/slices/auth/features/signup/Signup.vue"],"sourcesContent":["/**\n * Detects if an error indicates that email verification is required before login.\n * Used in signup flow when auto-login after signup fails due to unverified email.\n */\nexport function isEmailVerificationRequiredError(error: unknown): boolean {\n if (!error || typeof error !== 'object') return false;\n const e = error as {\n error_type?: string;\n error_name?: string;\n name?: string;\n message?: string;\n };\n if (\n e.error_type === 'EmailVerificationRequiredError' ||\n e.error_name === 'EmailVerificationRequiredError' ||\n e.name === 'EmailVerificationRequiredError'\n ) {\n return true;\n }\n const msg = typeof e.message === 'string' ? e.message : '';\n return msg.includes('Please verify your email before logging in');\n}\n","import { withMetadata } from '@dragonmastery/zinia-forms-core';\nimport { signupSchema } from '@dragonmastery/dragoncore-shared';\nimport { z } from 'zod';\n\n// Define the signup form type\nexport type SignupForm = z.infer<typeof signupSchema>;\n\n// Enhance the schema with metadata (acceptances are rendered from consumer-provided signup requirements)\nexport const signupSchemaWithMetadata = withMetadata(signupSchema, 'signupSchema', {\n email: {\n inputType: 'email',\n placeholder: 'you@example.com',\n helpText: 'Enter the email address you used to register',\n autocomplete: 'email',\n className: 'login-field',\n autofocus: true,\n },\n 'passwords.password': {\n inputType: 'password',\n placeholder: '••••••••',\n helpText: 'Must be at least 8 characters',\n autocomplete: 'current-password',\n className: 'login-field',\n },\n 'passwords.password_confirm': {\n inputType: 'password',\n placeholder: '••••••••',\n helpText: 'Must be at least 8 characters',\n autocomplete: 'current-password',\n className: 'login-field',\n },\n});\n","<template>\n <div class=\"max-w-md mx-auto bg-base-200 p-6 rounded-xl shadow-md container\">\n <h1 class=\"text-2xl font-bold mb-6 text-center\">Sign Up</h1>\n\n <div\n v-if=\"awaitingVerification\"\n class=\"space-y-4 text-center\"\n >\n <p class=\"text-base-content/80\">\n We sent a verification link to your email address. Click the link to verify your account,\n then you can continue.\n </p>\n <p class=\"text-sm text-base-content/60\">\n If you opened the link in another tab, we'll redirect you automatically when verification\n completes.\n </p>\n </div>\n\n <div v-else-if=\"declinedMessage\" class=\"mb-4\">\n <div class=\"alert alert-warning\">\n <span>{{ declinedMessage }}</span>\n </div>\n </div>\n\n <ZiniaForm\n v-if=\"!awaitingVerification\"\n @handle-submit=\"handleSubmit\"\n @success=\"handleSuccess\"\n @error=\"handleError\"\n >\n <zinia.EmailField />\n <zinia.PasswordsPasswordField />\n <zinia.PasswordsPasswordConfirmField />\n\n <div\n v-if=\"(signupRequirements ?? []).length > 0\"\n class=\"mb-6 p-4 rounded-lg bg-base-100 border border-base-300\"\n >\n <p class=\"font-medium mb-2\">Before signing up, you'll need to accept:</p>\n <ul class=\"list-disc list-inside space-y-1 text-sm text-base-content/80\">\n <li\n v-for=\"config in (signupRequirements ?? [])\"\n :key=\"config.type\"\n >\n <a\n v-if=\"config.url\"\n :href=\"config.url\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n class=\"link link-accent\"\n >\n {{ config.label }}\n </a>\n <span v-else>{{ config.label }}</span>\n </li>\n </ul>\n <p class=\"mt-2 text-sm text-base-content/70\">\n After you click Sign Up, we'll show you each document to review and accept.\n </p>\n </div>\n\n <ZiniaSubmitButton submitText=\"Sign Up\" submittingText=\"Signing up...\" />\n\n <div class=\"text-center mt-2\">\n <p>\n Already have an account?\n <AppLink class=\"link-accent link\" :to=\"loginLink\">Login</AppLink>\n </p>\n </div>\n </ZiniaForm>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport type { SignupRequirementsDto } from '@dragonmastery/dragoncore-shared';\nimport type { UserDetailsTokenPayload } from '../../../../lib/models/userSession';\nimport AppLink from '../../../../components/AppLink.vue';\nimport { SIGNUP_REQUIREMENTS_KEY } from '../../signupRequirements';\nimport { useSignupPendingData } from '../../useSignupPendingData';\nimport { useEnv } from '../../../../composables/useEnv';\nimport { useMutation } from '../../../../composables/useMutation';\nimport { useUserSessionStore } from '../../../../composables/useUserSessionStore';\nimport {\n getValidReturnUrl,\n setEmailVerificationReturnUrl,\n withReturnUrl,\n} from '../../../../utils/useReturnUrl';\nimport { useEmailVerificationChannel } from '../../useEmailVerificationChannel';\nimport { isEmailVerificationRequiredError } from '../../utils/isEmailVerificationRequiredError';\nimport { useForm } from '@dragonmastery/zinia-forms-core';\nimport type { SignupInputDto } from '@dragonmastery/dragoncore-shared';\nimport { jwtDecode } from 'jwt-decode';\nimport { computed, inject, ref } from 'vue';\nimport { useRoute, useRouter } from 'vue-router';\nimport { toast } from 'vue3-toastify';\nimport { signupSchemaWithMetadata } from './signupSchema';\n\nconst REDIRECTED_TO_CONSENTS = Symbol('redirected-to-consents');\n\n// Create a type-safe form using our schema with metadata\nconst { form, zinia, ZiniaForm, ZiniaSubmitButton } = useForm(signupSchemaWithMetadata, {\n storeName: 'signup-form',\n persistToLocalStorage: false,\n renderStyle: 'daisy_ui',\n});\n\nconst sessionStore = useUserSessionStore();\nconst route = useRoute();\nconst router = useRouter();\nconst { emailVerificationMode } = useEnv();\n\nconst returnUrl = computed(() => route.query.returnUrl as string | undefined);\nconst loginLink = computed(() => withReturnUrl('/auth/login', returnUrl.value));\nconst awaitingVerification = ref(false);\n\n// Provided by Auth layout when signupRequirements prop is passed, or app.provide\nconst signupRequirements = inject<SignupRequirementsDto>(SIGNUP_REQUIREMENTS_KEY, () => [], true);\n\nconst { set: setSignupPendingData } = useSignupPendingData();\n\n// Show declined message when returning from consent flow\nconst declinedMessage = computed(() => {\n const declined = route.query.declined;\n if (declined === '1' || declined === 'true') {\n return 'You declined the consent. Your account was not created.';\n }\n return null;\n});\nconst { mutate: signupMutate } = useMutation(\n (api, input: SignupInputDto) => api.users.signupUser(input),\n { skipAuthCheck: true }, // Signup is a public endpoint\n);\nconst { mutate: loginMutate } = useMutation(\n (api, input: { email: string; password: string }) => api.userSessions.login(input),\n { credentials: 'include' }, // Include credentials to allow cookies\n);\n\n// Handle form submission\nconst handleSubmit = async (data: SignupInputDto) => {\n const requirements = signupRequirements ?? [];\n\n if (requirements.length > 0) {\n setSignupPendingData(data);\n const consentPath = withReturnUrl('/auth/signup-consents', returnUrl.value);\n await router.push(consentPath);\n return REDIRECTED_TO_CONSENTS;\n }\n\n const result = await signupMutate(data);\n if (!result) throw new Error('Signup failed');\n\n try {\n const loginResult = await loginMutate({\n email: data.email,\n password: data.passwords.password,\n });\n\n if (!loginResult?.access_token || !loginResult?.user_details_token) {\n throw new Error('Failed to login after signup');\n }\n\n return {\n access_token: loginResult.access_token,\n user_details_token: loginResult.user_details_token,\n };\n } catch (loginError) {\n if (isEmailVerificationRequiredError(loginError)) {\n form.reset();\n if (emailVerificationMode === 'strict') {\n awaitingVerification.value = true;\n const targetUrl = getValidReturnUrl(route, '/');\n setEmailVerificationReturnUrl(targetUrl);\n throw loginError;\n }\n const verifyPath = withReturnUrl('/auth/verify-email', returnUrl.value);\n await router.push(verifyPath);\n throw loginError;\n }\n throw loginError;\n }\n};\n\n// Handle success (not called when we redirect to consent flow)\nconst handleSuccess = async (data: { access_token: string; user_details_token: string } | symbol) => {\n if (data === REDIRECTED_TO_CONSENTS) return;\n\n const payload = data as { access_token: string; user_details_token: string };\n sessionStore.setSession(payload.user_details_token);\n sessionStore.setAccessToken(payload.access_token);\n\n form.reset();\n\n const defaultRedirect = getValidReturnUrl(route, '/');\n const redirectTo =\n emailVerificationMode !== 'disabled'\n ? (() => {\n try {\n const tokenPayload = jwtDecode<UserDetailsTokenPayload>(payload.user_details_token);\n const emailVerified = tokenPayload.details?.user?.email_verified ?? true;\n return emailVerified ? defaultRedirect : withReturnUrl('/auth/verify-email', returnUrl.value);\n } catch {\n return defaultRedirect;\n }\n })()\n : defaultRedirect;\n\n await router.push(redirectTo);\n const wentToVerify = typeof redirectTo === 'string' && redirectTo.startsWith('/auth/verify-email');\n toast.success(\n !wentToVerify\n ? 'Registration successful! You are now logged in.'\n : 'Registration successful! Please check your email to verify your account.',\n );\n};\n\n// Handle error\nconst handleError = (error: unknown) => {\n if (isEmailVerificationRequiredError(error)) {\n return;\n }\n const message = error instanceof Error ? error.message : 'Registration failed';\n toast.error(message);\n};\n\nuseEmailVerificationChannel(\n awaitingVerification,\n (targetUrl) => router.push(targetUrl),\n () => getValidReturnUrl(route, '/'),\n);\n</script>\n"],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import "./useRpcAuth-rmHf7bYx.js";
2
+ import "./useQueryCache-Bjm-S8v5.js";
3
+ import "./useMutation-BTsyHKyn.js";
4
+ import "./AppLink-CHMMrSFI.js";
5
+ import "./useSignupPendingData-BWHwUHhL.js";
6
+ import "./useEmailVerificationChannel-BNi926Ho.js";
7
+ import { t as Signup_default } from "./Signup-9TjMMnU4.js";
8
+
9
+ export { Signup_default as default };
@@ -1,6 +1,6 @@
1
- import { l as useUserSessionStore, m as useEnv } from "./useRpcAuth-Bse-lggK.js";
2
- import "./useQueryCache-CJKZquh6.js";
3
- import { t as useMutation } from "./useMutation-Dhx2gMgS.js";
1
+ import { l as useUserSessionStore, m as useEnv } from "./useRpcAuth-rmHf7bYx.js";
2
+ import "./useQueryCache-Bjm-S8v5.js";
3
+ import { t as useMutation } from "./useMutation-BTsyHKyn.js";
4
4
  import { i as setEmailVerificationReturnUrl, o as withReturnUrl, r as getValidReturnUrl } from "./useReturnUrl-qFeazn-G.js";
5
5
  import { n as SIGNUP_REQUIREMENTS_KEY, t as useSignupPendingData } from "./useSignupPendingData-BWHwUHhL.js";
6
6
  import { Fragment, computed, createCommentVNode, createElementBlock, createElementVNode, defineComponent, inject, nextTick, openBlock, ref, toDisplayString, watch } from "vue";
@@ -10,7 +10,7 @@ import DOMPurify from "dompurify";
10
10
  import { marked } from "marked";
11
11
 
12
12
  //#region src/slices/auth/features/signup_consents/SignupConsentFlow.vue
13
- const _hoisted_1 = { class: "max-w-2xl mx-auto bg-base-200 p-6 rounded-xl shadow-md container" };
13
+ const _hoisted_1 = { class: "w-full max-w-md mx-auto mb-8 sm:mb-10 bg-base-200 px-3 py-4 sm:px-6 sm:py-6 rounded-xl shadow-md container min-w-0" };
14
14
  const _hoisted_2 = {
15
15
  key: 0,
16
16
  class: "text-center"
@@ -19,22 +19,29 @@ const _hoisted_3 = {
19
19
  key: 1,
20
20
  class: "space-y-6"
21
21
  };
22
- const _hoisted_4 = {
22
+ const _hoisted_4 = { class: "text-center space-y-1" };
23
+ const _hoisted_5 = { class: "text-2xl font-bold" };
24
+ const _hoisted_6 = { class: "text-base-content/80" };
25
+ const _hoisted_7 = {
23
26
  key: 0,
24
27
  class: "alert alert-error flex flex-col gap-3"
25
28
  };
26
- const _hoisted_5 = { class: "flex flex-wrap gap-2 mt-1" };
27
- const _hoisted_6 = ["disabled"];
28
- const _hoisted_7 = ["disabled"];
29
- const _hoisted_8 = { class: "text-base-content/80" };
30
- const _hoisted_9 = ["data-consent-type", "innerHTML"];
31
- const _hoisted_10 = ["href"];
29
+ const _hoisted_8 = { class: "flex flex-wrap gap-2 mt-1" };
30
+ const _hoisted_9 = ["disabled"];
31
+ const _hoisted_10 = ["disabled"];
32
32
  const _hoisted_11 = {
33
- key: 3,
34
- class: "flex flex-col gap-3"
33
+ key: 1,
34
+ class: "text-sm text-base-content/70 mb-2"
35
+ };
36
+ const _hoisted_12 = ["data-consent-type"];
37
+ const _hoisted_13 = ["innerHTML"];
38
+ const _hoisted_14 = ["href"];
39
+ const _hoisted_15 = {
40
+ key: 4,
41
+ class: "flex flex-col gap-5"
35
42
  };
36
- const _hoisted_12 = ["disabled"];
37
- const _hoisted_13 = ["disabled"];
43
+ const _hoisted_16 = ["disabled"];
44
+ const _hoisted_17 = ["disabled"];
38
45
  const _sfc_main = /* @__PURE__ */ defineComponent({
39
46
  __name: "SignupConsentFlow",
40
47
  setup(__props) {
@@ -142,8 +149,19 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
142
149
  })) throw new Error("Signup failed");
143
150
  clearSignupPendingData();
144
151
  if (emailVerificationMode !== "disabled") {
152
+ try {
153
+ const loginResult$1 = await loginMutate({
154
+ email: data.email,
155
+ password: data.passwords.password
156
+ });
157
+ if (loginResult$1?.access_token && loginResult$1?.user_details_token) {
158
+ sessionStore.setSession(loginResult$1.user_details_token);
159
+ sessionStore.setAccessToken(loginResult$1.access_token);
160
+ }
161
+ } catch {}
145
162
  if (emailVerificationMode === "strict") setEmailVerificationReturnUrl(getValidReturnUrl(route, "/"));
146
- const verifyPath = withReturnUrl("/auth/verify-email-required", returnUrl.value);
163
+ window.scrollTo(0, 0);
164
+ const verifyPath = withReturnUrl("/auth/verify-email", returnUrl.value);
147
165
  await router.push(verifyPath);
148
166
  return;
149
167
  }
@@ -154,6 +172,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
154
172
  if (!loginResult?.access_token || !loginResult?.user_details_token) throw new Error("Failed to login after signup");
155
173
  sessionStore.setSession(loginResult.user_details_token);
156
174
  sessionStore.setAccessToken(loginResult.access_token);
175
+ window.scrollTo(0, 0);
157
176
  const defaultRedirect = getValidReturnUrl(route, "/");
158
177
  await router.push(defaultRedirect);
159
178
  toast.success("Registration successful! You are now logged in.");
@@ -189,49 +208,56 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
189
208
  }
190
209
  }
191
210
  return (_ctx, _cache) => {
192
- return openBlock(), createElementBlock("div", _hoisted_1, [_cache[2] || (_cache[2] = createElementVNode("h1", { class: "text-2xl font-bold mb-6 text-center" }, "Review and accept", -1)), !signupData.value ? (openBlock(), createElementBlock("div", _hoisted_2, [..._cache[0] || (_cache[0] = [createElementVNode("p", { class: "text-base-content/80" }, "Loading...", -1)])])) : currentConfig.value ? (openBlock(), createElementBlock("div", _hoisted_3, [
193
- submitError.value ? (openBlock(), createElementBlock("div", _hoisted_4, [
211
+ return openBlock(), createElementBlock("div", _hoisted_1, [!signupData.value ? (openBlock(), createElementBlock("div", _hoisted_2, [..._cache[0] || (_cache[0] = [createElementVNode("p", { class: "text-base-content/80" }, "Loading...", -1)])])) : currentConfig.value ? (openBlock(), createElementBlock("div", _hoisted_3, [
212
+ createElementVNode("div", _hoisted_4, [
213
+ createElementVNode("h1", _hoisted_5, toDisplayString(currentConfig.value.label), 1),
214
+ createElementVNode("p", _hoisted_6, "Step " + toDisplayString(currentStep.value) + " of " + toDisplayString(totalSteps.value), 1),
215
+ _cache[1] || (_cache[1] = createElementVNode("p", { class: "text-base-content/70 text-sm" }, "Review and accept", -1))
216
+ ]),
217
+ submitError.value ? (openBlock(), createElementBlock("div", _hoisted_7, [
194
218
  createElementVNode("span", null, toDisplayString(submitError.value), 1),
195
- _cache[1] || (_cache[1] = createElementVNode("p", { class: "text-sm opacity-90" }, " You can try again or go back to sign up and try again later. ", -1)),
196
- createElementVNode("div", _hoisted_5, [createElementVNode("button", {
219
+ _cache[2] || (_cache[2] = createElementVNode("p", { class: "text-sm opacity-90" }, " You can try again or go back to sign up and try again later. ", -1)),
220
+ createElementVNode("div", _hoisted_8, [createElementVNode("button", {
197
221
  type: "button",
198
222
  class: "btn btn-primary btn-sm",
199
223
  disabled: goingBack.value || submitting.value,
200
224
  onClick: goBackToSignup
201
- }, toDisplayString(goingBack.value ? "Returning..." : "Back to sign up"), 9, _hoisted_6), createElementVNode("button", {
225
+ }, toDisplayString(goingBack.value ? "Returning..." : "Back to sign up"), 9, _hoisted_9), createElementVNode("button", {
202
226
  type: "button",
203
227
  class: "btn btn-ghost btn-sm",
204
228
  disabled: submitting.value || goingBack.value,
205
229
  onClick: handleAccept
206
- }, toDisplayString(submitting.value ? "Submitting..." : "Try again"), 9, _hoisted_7)])
230
+ }, toDisplayString(submitting.value ? "Submitting..." : "Try again"), 9, _hoisted_10)])
207
231
  ])) : createCommentVNode("v-if", true),
208
- createElementVNode("p", _hoisted_8, " Step " + toDisplayString(currentStep.value) + " of " + toDisplayString(totalSteps.value) + ": " + toDisplayString(currentConfig.value.label), 1),
232
+ currentConfig.value.content ? (openBlock(), createElementBlock("p", _hoisted_11, " Please read the full document before accepting. Scroll to the bottom when you've finished reading. You can decline at any time; if you decline, your account will not be created and you will return to sign up. ")) : createCommentVNode("v-if", true),
209
233
  createCommentVNode(" Scrollable terms box when content is provided "),
210
234
  currentConfig.value.content ? (openBlock(), createElementBlock("div", {
211
- key: 1,
235
+ key: currentConfig.value.type,
212
236
  ref: (el) => setScrollRef(el),
213
- class: "border border-base-300 rounded-lg p-4 bg-base-100 overflow-y-auto text-sm prose prose-sm max-h-64 prose-headings:font-semibold prose-p:my-2",
237
+ class: "border border-base-300 rounded-lg px-3 py-4 sm:p-4 bg-base-100 overflow-y-auto overflow-x-hidden min-h-80 max-h-[min(32rem,70vh)] w-full min-w-0",
214
238
  "data-consent-type": currentConfig.value.type,
215
- onScroll,
239
+ onScroll
240
+ }, [createElementVNode("div", {
241
+ class: "prose prose-sm prose-max-w-none max-w-full min-w-0 text-sm prose-headings:font-semibold prose-p:my-2",
216
242
  innerHTML: renderMarkdown(currentConfig.value.content)
217
- }, null, 40, _hoisted_9)) : (openBlock(), createElementBlock(Fragment, { key: 2 }, [createCommentVNode(" Link-only when no content "), createElementVNode("div", null, [currentConfig.value.url ? (openBlock(), createElementBlock("a", {
243
+ }, null, 8, _hoisted_13)], 40, _hoisted_12)) : (openBlock(), createElementBlock(Fragment, { key: 3 }, [createCommentVNode(" Link-only when no content "), createElementVNode("div", null, [currentConfig.value.url ? (openBlock(), createElementBlock("a", {
218
244
  key: 0,
219
245
  href: currentConfig.value.url,
220
246
  target: "_blank",
221
247
  rel: "noopener noreferrer",
222
248
  class: "link link-accent"
223
- }, " View " + toDisplayString(currentConfig.value.label), 9, _hoisted_10)) : createCommentVNode("v-if", true)])], 2112)),
224
- !submitError.value ? (openBlock(), createElementBlock("div", _hoisted_11, [createElementVNode("button", {
249
+ }, " View " + toDisplayString(currentConfig.value.label), 9, _hoisted_14)) : createCommentVNode("v-if", true)])], 2112)),
250
+ !submitError.value ? (openBlock(), createElementBlock("div", _hoisted_15, [createElementVNode("button", {
225
251
  type: "button",
226
252
  class: "btn btn-primary",
227
253
  disabled: (currentConfig.value.content ? !hasScrolledToBottom.value : false) || submitting.value,
228
254
  onClick: handleAccept
229
- }, toDisplayString(submitting.value ? "Submitting..." : "Accept and continue"), 9, _hoisted_12), createElementVNode("button", {
255
+ }, toDisplayString(submitting.value ? "Submitting..." : "Accept and continue"), 9, _hoisted_16), createElementVNode("button", {
230
256
  type: "button",
231
- class: "btn btn-ghost btn-sm text-error",
257
+ class: "btn btn-outline btn-sm btn-error",
232
258
  disabled: declining.value || submitting.value,
233
259
  onClick: handleDecline
234
- }, toDisplayString(declining.value ? "Returning..." : "Decline"), 9, _hoisted_13)])) : createCommentVNode("v-if", true)
260
+ }, toDisplayString(declining.value ? "Returning..." : "Decline"), 9, _hoisted_17)])) : createCommentVNode("v-if", true)
235
261
  ])) : createCommentVNode("v-if", true)]);
236
262
  };
237
263
  }
@@ -240,4 +266,4 @@ var SignupConsentFlow_default = _sfc_main;
240
266
 
241
267
  //#endregion
242
268
  export { SignupConsentFlow_default as default };
243
- //# sourceMappingURL=SignupConsentFlow-DG2IGikE.js.map
269
+ //# sourceMappingURL=SignupConsentFlow-QUZGKjdB.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SignupConsentFlow-QUZGKjdB.js","names":["acceptancesSoFar: Record<string, boolean>","input: SignupInputDto"],"sources":["../src/slices/auth/features/signup_consents/SignupConsentFlow.vue"],"sourcesContent":["<template>\n <div class=\"w-full max-w-md mx-auto mb-8 sm:mb-10 bg-base-200 px-3 py-4 sm:px-6 sm:py-6 rounded-xl shadow-md container min-w-0\">\n <div v-if=\"!signupData\" class=\"text-center\">\n <p class=\"text-base-content/80\">Loading...</p>\n </div>\n\n <div v-else-if=\"currentConfig\" class=\"space-y-6\">\n <div class=\"text-center space-y-1\">\n <h1 class=\"text-2xl font-bold\">{{ currentConfig.label }}</h1>\n <p class=\"text-base-content/80\">Step {{ currentStep }} of {{ totalSteps }}</p>\n <p class=\"text-base-content/70 text-sm\">Review and accept</p>\n </div>\n\n <div v-if=\"submitError\" class=\"alert alert-error flex flex-col gap-3\">\n <span>{{ submitError }}</span>\n <p class=\"text-sm opacity-90\">\n You can try again or go back to sign up and try again later.\n </p>\n <div class=\"flex flex-wrap gap-2 mt-1\">\n <button\n type=\"button\"\n class=\"btn btn-primary btn-sm\"\n :disabled=\"goingBack || submitting\"\n @click=\"goBackToSignup\"\n >\n {{ goingBack ? 'Returning...' : 'Back to sign up' }}\n </button>\n <button\n type=\"button\"\n class=\"btn btn-ghost btn-sm\"\n :disabled=\"submitting || goingBack\"\n @click=\"handleAccept\"\n >\n {{ submitting ? 'Submitting...' : 'Try again' }}\n </button>\n </div>\n </div>\n\n <p v-if=\"currentConfig.content\" class=\"text-sm text-base-content/70 mb-2\">\n Please read the full document before accepting. Scroll to the bottom when you've finished reading. You can decline at any time; if you decline, your account will not be created and you will return to sign up.\n </p>\n\n <!-- Scrollable terms box when content is provided -->\n <div\n v-if=\"currentConfig.content\"\n :key=\"currentConfig.type\"\n :ref=\"(el) => setScrollRef(el)\"\n class=\"border border-base-300 rounded-lg px-3 py-4 sm:p-4 bg-base-100 overflow-y-auto overflow-x-hidden min-h-80 max-h-[min(32rem,70vh)] w-full min-w-0\"\n :data-consent-type=\"currentConfig.type\"\n @scroll=\"onScroll\"\n >\n <div\n class=\"prose prose-sm prose-max-w-none max-w-full min-w-0 text-sm prose-headings:font-semibold prose-p:my-2\"\n v-html=\"renderMarkdown(currentConfig.content)\"\n />\n </div>\n\n <!-- Link-only when no content -->\n <div v-else>\n <a\n v-if=\"currentConfig.url\"\n :href=\"currentConfig.url\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n class=\"link link-accent\"\n >\n View {{ currentConfig.label }}\n </a>\n </div>\n\n <div v-if=\"!submitError\" class=\"flex flex-col gap-5\">\n <button\n type=\"button\"\n class=\"btn btn-primary\"\n :disabled=\"(currentConfig.content ? !hasScrolledToBottom : false) || submitting\"\n @click=\"handleAccept\"\n >\n {{ submitting ? 'Submitting...' : 'Accept and continue' }}\n </button>\n <button\n type=\"button\"\n class=\"btn btn-outline btn-sm btn-error\"\n :disabled=\"declining || submitting\"\n @click=\"handleDecline\"\n >\n {{ declining ? 'Returning...' : 'Decline' }}\n </button>\n </div>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport type { SignupInputDto, SignupRequirementsDto } from '@dragonmastery/dragoncore-shared';\nimport DOMPurify from 'dompurify';\nimport { marked } from 'marked';\nimport { computed, inject, nextTick, ref, watch } from 'vue';\nimport { useRoute, useRouter } from 'vue-router';\nimport { toast } from 'vue3-toastify';\nimport { useSignupPendingData } from '../../useSignupPendingData';\nimport { SIGNUP_REQUIREMENTS_KEY } from '../../signupRequirements';\nimport { useEnv } from '../../../../composables/useEnv';\nimport { useMutation } from '../../../../composables/useMutation';\nimport { useUserSessionStore } from '../../../../composables/useUserSessionStore';\nimport {\n getValidReturnUrl,\n setEmailVerificationReturnUrl,\n withReturnUrl,\n} from '../../../../utils/useReturnUrl';\nconst signupRequirements = inject<SignupRequirementsDto>(SIGNUP_REQUIREMENTS_KEY, () => [], true);\n\nconst { get: getSignupPendingData, clear: clearSignupPendingData } = useSignupPendingData();\nconst sessionStore = useUserSessionStore();\nconst router = useRouter();\nconst route = useRoute();\nconst { emailVerificationMode } = useEnv();\n\nconst returnUrl = computed(() => route.query.returnUrl as string | undefined);\n\nconst signupData = computed(() => getSignupPendingData());\n\nconst currentStep = ref(1);\nconst totalSteps = computed(() => signupRequirements?.length ?? 0);\nconst currentConfig = computed(\n () => signupRequirements?.[currentStep.value - 1] ?? null,\n);\n\nconst hasScrolledToBottom = ref(false);\nconst scrollEl = ref<HTMLElement | null>(null);\n\nfunction setScrollRef(el: unknown) {\n scrollEl.value = el instanceof HTMLElement ? el : null;\n}\n\nwatch(\n () => currentConfig.value,\n (config) => {\n hasScrolledToBottom.value = !config?.content;\n nextTick(() => {\n scrollEl.value?.scrollTo(0, 0);\n });\n },\n { immediate: true },\n);\n\nfunction renderMarkdown(content: string): string {\n const html = marked.parse(content) as string;\n return DOMPurify.sanitize(html, {\n ALLOWED_TAGS: ['p', 'br', 'strong', 'em', 'u', 'a', 'ul', 'ol', 'li', 'h1', 'h2', 'h3', 'h4', 'blockquote', 'code', 'pre', 'hr'],\n ALLOWED_ATTR: ['href', 'target', 'rel'],\n });\n}\n\nfunction checkScrolledToBottom() {\n const el = scrollEl.value;\n if (!el) return;\n const { scrollTop, scrollHeight, clientHeight } = el;\n const atBottom = scrollHeight - scrollTop - clientHeight < 10;\n if (atBottom) {\n hasScrolledToBottom.value = true;\n }\n}\n\nfunction onScroll() {\n checkScrolledToBottom();\n}\n\nnextTick(checkScrolledToBottom);\n\nconst declining = ref(false);\nconst goingBack = ref(false);\nconst submitting = ref(false);\nconst submitError = ref<string | null>(null);\n\nfunction getErrorMessage(error: unknown): string {\n if (error instanceof Error && error.message) return error.message;\n if (error && typeof error === 'object' && 'message' in error && typeof (error as { message: unknown }).message === 'string') {\n return (error as { message: string }).message;\n }\n return 'Registration failed. Please try again.';\n}\n\nconst { mutate: signupMutate } = useMutation(\n (api, input: SignupInputDto) => api.users.signupUser(input),\n { skipAuthCheck: true },\n);\nconst { mutate: loginMutate } = useMutation(\n (api, input: { email: string; password: string }) => api.userSessions.login(input),\n { credentials: 'include' },\n);\n\nasync function handleAccept() {\n const config = currentConfig.value;\n if (!config || !signupData.value) return;\n\n submitError.value = null;\n\n const acceptancesSoFar: Record<string, boolean> = {};\n for (let i = 0; i < currentStep.value; i++) {\n const c = signupRequirements?.[i];\n if (c) acceptancesSoFar[c.type] = true;\n }\n\n if (currentStep.value >= totalSteps.value) {\n submitting.value = true;\n try {\n await completeSignup(acceptancesSoFar);\n } catch (err) {\n submitError.value = getErrorMessage(err);\n } finally {\n submitting.value = false;\n }\n return;\n }\n\n currentStep.value++;\n hasScrolledToBottom.value = !currentConfig.value?.content;\n nextTick(checkScrolledToBottom);\n}\n\nasync function completeSignup(acceptances: Record<string, boolean>) {\n const data = signupData.value;\n if (!data) return;\n\n const input: SignupInputDto = {\n ...data,\n acceptances,\n };\n\n const result = await signupMutate(input);\n if (!result) throw new Error('Signup failed');\n\n clearSignupPendingData();\n\n if (emailVerificationMode !== 'disabled') {\n // Log user in with unverified session so they can use Resend on verify-email page\n try {\n const loginResult = await loginMutate({\n email: data.email,\n password: data.passwords.password,\n });\n if (loginResult?.access_token && loginResult?.user_details_token) {\n sessionStore.setSession(loginResult.user_details_token);\n sessionStore.setAccessToken(loginResult.access_token);\n }\n } catch {\n // Login may fail; still redirect so user can verify via email link\n }\n if (emailVerificationMode === 'strict') {\n const targetUrl = getValidReturnUrl(route, '/');\n setEmailVerificationReturnUrl(targetUrl);\n }\n window.scrollTo(0, 0);\n const verifyPath = withReturnUrl('/auth/verify-email', returnUrl.value);\n await router.push(verifyPath);\n return;\n }\n\n const loginResult = await loginMutate({\n email: data.email,\n password: data.passwords.password,\n });\n\n if (!loginResult?.access_token || !loginResult?.user_details_token) {\n throw new Error('Failed to login after signup');\n }\n\n sessionStore.setSession(loginResult.user_details_token);\n sessionStore.setAccessToken(loginResult.access_token);\n\n window.scrollTo(0, 0);\n const defaultRedirect = getValidReturnUrl(route, '/');\n await router.push(defaultRedirect);\n toast.success('Registration successful! You are now logged in.');\n}\n\nasync function handleDecline() {\n declining.value = true;\n try {\n clearSignupPendingData();\n const signupPath = withReturnUrl('/auth/signup', returnUrl.value);\n await router.push({ path: signupPath, query: { ...route.query, declined: '1' } });\n } finally {\n declining.value = false;\n }\n}\n\nasync function goBackToSignup() {\n goingBack.value = true;\n try {\n clearSignupPendingData();\n const signupPath = withReturnUrl('/auth/signup', returnUrl.value);\n const { declined: _d, ...rest } = route.query;\n await router.push({ path: signupPath, query: rest });\n } finally {\n goingBack.value = false;\n }\n}\n\n</script>\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
- import "./useRpcAuth-Bse-lggK.js";
2
- import "./useQueryCache-CJKZquh6.js";
3
- import { t as useMutation } from "./useMutation-Dhx2gMgS.js";
4
- import { t as useQuery } from "./useQuery-DxmMxM8z.js";
1
+ import "./useRpcAuth-rmHf7bYx.js";
2
+ import "./useQueryCache-Bjm-S8v5.js";
3
+ import { t as useMutation } from "./useMutation-BTsyHKyn.js";
4
+ import { t as useQuery } from "./useQuery-BggIE52P.js";
5
5
  import { n as RecordVersionList_default, t as RecordVersionViewer_default } from "./RecordVersionViewer-BWZ78vvE.js";
6
6
  import { r as formatToISODatetime } from "./convertToLocalDateTime-CFhtN6PI.js";
7
7
  import { t as extractRpcErrorMessage } from "./extractRpcErrorMessage-Di8E8-Wh.js";
@@ -357,4 +357,4 @@ var SignupRequirementsPage_default = _sfc_main;
357
357
 
358
358
  //#endregion
359
359
  export { SignupRequirementsPage_default as default };
360
- //# sourceMappingURL=SignupRequirementsPage-DnLpQfB8.js.map
360
+ //# sourceMappingURL=SignupRequirementsPage-DfbYmpQD.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"SignupRequirementsPage-DnLpQfB8.js","names":["consentItemFieldMetadata: {\n [K in PathsOf<typeof SignupConsentItemFormSchema>]: SchemaFieldMetadata;\n}","config: SignupRequirementsDto"],"sources":["../src/slices/admin/features/signup_requirements/signupRequirementsFormMetadata.ts","../src/slices/admin/features/signup_requirements/SignupRequirementsPage.vue"],"sourcesContent":["import {\n SignupConsentItemFormSchema,\n type SignupConsentItemFormDto,\n} from '@dragonmastery/dragoncore-shared';\nimport {\n withMetadata,\n type PathsOf,\n type SchemaFieldMetadata,\n} from '@dragonmastery/zinia-forms-core';\nimport { z } from 'zod';\n\n/** Field metadata for consent item form — keys must match schema paths */\nexport const consentItemFieldMetadata: {\n [K in PathsOf<typeof SignupConsentItemFormSchema>]: SchemaFieldMetadata;\n} = {\n type: {\n label: 'Type',\n helpText: 'Type (e.g. terms_of_service, privacy_policy)',\n placeholder: 'terms_of_service',\n },\n version: {\n label: 'Version',\n helpText: 'Version (e.g. 2025.1)',\n placeholder: '2025.1',\n },\n label: {\n label: 'Label',\n placeholder: 'Terms of Service',\n },\n effective_at: {\n label: 'Effective at',\n inputType: 'datetime-local',\n helpText:\n 'When this version becomes enforceable for existing users. Set to now for immediate effect.',\n },\n url: {\n label: 'URL',\n helpText: 'URL (link to document)',\n placeholder: 'https://example.com/terms',\n },\n required: {\n label: 'Required',\n helpText: 'User must accept to sign up',\n inputType: 'checkbox' as const,\n },\n content: {\n label: 'Content',\n helpText: 'Optional, Markdown — when set, shown in scroll box; user must scroll to bottom',\n placeholder: '# Terms of Service\\n\\nYour markdown content here...',\n inputType: 'textarea',\n },\n};\n\n/** Item schema with metadata - used as array element (like followupCreateMetadata in tracker) */\nexport const signupConsentItemFormMetadata = withMetadata(\n SignupConsentItemFormSchema,\n 'signupConsentItemForm',\n consentItemFieldMetadata,\n);\n\n/** Full form schema with items array using metadata-wrapped item schema */\nexport const signupRequirementsFormMetadata = withMetadata(\n z.object({\n items: z.array(signupConsentItemFormMetadata).default([]),\n }),\n 'signupRequirementsForm',\n {},\n);\n\nexport function createEmptyConsentItem(): SignupConsentItemFormDto {\n const now = new Date();\n const pad = (n: number) => String(n).padStart(2, '0');\n const effectiveAt = `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())}T${pad(now.getHours())}:${pad(now.getMinutes())}`;\n return {\n type: '',\n required: true,\n url: '',\n label: '',\n version: '1',\n effective_at: effectiveAt,\n content: '',\n };\n}\n","<template>\n <div class=\"mt-2\">\n <div class=\"flex justify-between items-center mb-4\">\n <h1 class=\"text-2xl font-bold\">Signup Requirements</h1>\n </div>\n\n <p class=\"text-base-content/70 mb-4\">\n Configure consent checkboxes shown on signup and consent-required flows. Each item can be\n required or optional. When <strong>content</strong> is provided, terms are shown in a\n scroll box (Markdown supported) and the user must scroll to bottom before accepting. When\n content is omitted, only a link is shown.\n </p>\n\n <div v-if=\"isLoading\" class=\"flex justify-center py-8\">\n <span class=\"loading loading-spinner loading-lg\"></span>\n </div>\n\n <div v-else class=\"space-y-6\">\n <ZiniaForm\n @handle-submit=\"handleSubmit\"\n @success=\"handleSuccess\"\n @error=\"handleError\"\n title=\"\"\n subtitle=\"\"\n >\n <zinia.ItemsField label=\"Consent Items\" :create-item=\"createEmptyConsentItem\">\n <template #itemPreview=\"{ item }\">\n <div class=\"font-medium text-sm\">\n {{ item.label || item.type || 'Item' }}\n <span v-if=\"item.type\" class=\"text-base-content/60\">({{ item.type }})</span>\n </div>\n </template>\n <template #itemRenderer=\"{ fields }\">\n <div class=\"space-y-3\">\n <div class=\"grid grid-cols-1 md:grid-cols-3 gap-3\">\n <ziniaGeneric.TextField\n :name=\"fields.type\"\n :label=\"consentItemFieldMetadata.type.label\"\n :placeholder=\"consentItemFieldMetadata.type.placeholder\"\n required\n />\n <ziniaGeneric.TextField\n :name=\"fields.version\"\n :label=\"consentItemFieldMetadata.version.label\"\n :placeholder=\"consentItemFieldMetadata.version.placeholder\"\n required\n />\n <ziniaGeneric.TextField\n :name=\"fields.label\"\n :label=\"consentItemFieldMetadata.label.label\"\n :placeholder=\"consentItemFieldMetadata.label.placeholder\"\n required\n />\n </div>\n <ziniaGeneric.DateField\n :name=\"fields.effective_at\"\n :label=\"consentItemFieldMetadata.effective_at.label\"\n :formatter=\"formatToISODatetime\"\n required\n />\n <ziniaGeneric.TextField\n :name=\"fields.url\"\n :label=\"consentItemFieldMetadata.url.label\"\n :placeholder=\"consentItemFieldMetadata.url.placeholder\"\n type=\"url\"\n />\n <ziniaGeneric.CheckboxField\n :name=\"fields.required\"\n :label=\"consentItemFieldMetadata.required.label\"\n />\n <ziniaGeneric.TextareaField\n :name=\"fields.content\"\n :label=\"consentItemFieldMetadata.content.label\"\n :placeholder=\"consentItemFieldMetadata.content.placeholder\"\n :rows=\"5\"\n class=\"font-mono text-sm\"\n />\n </div>\n </template>\n </zinia.ItemsField>\n\n <div v-if=\"form.submitError\" class=\"alert alert-error mt-2\">\n <span>{{ form.submitError }}</span>\n </div>\n\n <div class=\"mt-4 flex justify-end\">\n <ZiniaSubmitButton\n submitText=\"Save\"\n submittingText=\"Saving...\"\n :disabled=\"!hasChanges\"\n />\n </div>\n </ZiniaForm>\n\n <!-- Version History -->\n <div class=\"card bg-base-200\">\n <div class=\"card-body\">\n <h2 class=\"card-title text-lg\">Version History</h2>\n <p class=\"text-sm text-base-content/70\">\n Past changes to signup requirements. Each save creates a new version.\n </p>\n <RecordVersionList\n :versions=\"versionHistoryItems\"\n :loading=\"versionHistoryLoading\"\n :error=\"versionHistoryError\"\n :has-next-page=\"versionHistoryPageInfo?.hasNextPage ?? false\"\n :loading-more=\"versionHistoryLoadingMore\"\n :config=\"versionListConfig\"\n exclude-latest\n @retry=\"refetchVersionHistory\"\n @load-more=\"loadMoreVersions\"\n />\n <dialog ref=\"versionModalRef\" class=\"modal\">\n <div class=\"modal-box max-w-4xl max-h-[90vh] overflow-auto\">\n <RecordVersionViewer\n v-if=\"selectedVersion\"\n :version=\"selectedVersion\"\n :record-data=\"selectedVersionRecordData\"\n :config=\"versionViewerConfig\"\n >\n <template #content=\"{ recordData }\">\n <div v-if=\"recordData?.items?.length\" class=\"space-y-4\">\n <h3 class=\"font-semibold\">Consent items at this version</h3>\n <div\n v-for=\"(item, idx) in recordData.items\"\n :key=\"idx\"\n class=\"border border-base-300 rounded p-3 text-sm space-y-1\"\n >\n <div><strong>Type:</strong> {{ item.type }}</div>\n <div><strong>Version:</strong> {{ item.version }}</div>\n <div><strong>Label:</strong> {{ item.label }}</div>\n <div><strong>Effective at:</strong> {{ item.effective_at }}</div>\n <div><strong>Required:</strong> {{ item.required ? 'Yes' : 'No' }}</div>\n <div v-if=\"item.url\"><strong>URL:</strong> {{ item.url }}</div>\n </div>\n </div>\n <pre v-else class=\"text-xs bg-base-200 p-3 rounded overflow-auto max-h-96\">{{\n JSON.stringify(recordData, null, 2)\n }}</pre>\n </template>\n </RecordVersionViewer>\n </div>\n <form method=\"dialog\" class=\"modal-backdrop\">\n <button type=\"button\" @click=\"closeVersionModal\">close</button>\n </form>\n </dialog>\n </div>\n </div>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport type { SignupRequirementsDto } from '@dragonmastery/dragoncore-shared';\nimport { RecordConst } from '@dragonmastery/dragoncore-shared';\nimport { useForm } from '@dragonmastery/zinia-forms-core';\nimport { computed, ref } from 'vue';\nimport { toast } from 'vue3-toastify';\nimport RecordVersionList from '../../../../components/ui/RecordVersionList.vue';\nimport RecordVersionViewer from '../../../../components/ui/RecordVersionViewer.vue';\nimport { useMutation } from '../../../../composables/useMutation';\nimport { useQuery } from '../../../../composables/useQuery';\nimport { formatToISODatetime } from '../../../../utils/convertToLocalDateTime';\nimport { extractRpcErrorMessage } from '../../../../utils/extractRpcErrorMessage';\nimport {\n consentItemFieldMetadata,\n createEmptyConsentItem,\n signupRequirementsFormMetadata,\n} from './signupRequirementsFormMetadata';\n\nconst {\n data: _signupRequirements,\n loading: isLoading,\n refetch,\n} = useQuery((api) => api.appSettings.getSignupRequirements(), {\n // cacheKey: 'admin-signup-requirements',\n // staleTime: 30 * 1000,\n});\n\nconst { form, zinia, ziniaGeneric, ZiniaForm, ZiniaSubmitButton } = useForm(\n signupRequirementsFormMetadata,\n {\n storeName: 'admin-signup-requirements-form',\n persistToLocalStorage: false,\n renderStyle: 'daisy_ui',\n // wait for signup requirements to load\n fetchData: async () => {\n while (isLoading.value) {\n await new Promise((resolve) => setTimeout(resolve, 100));\n }\n return { items: _signupRequirements.value ?? [] };\n },\n },\n);\n\nconst initialSnapshot = ref<string>('');\n\nconst hasChanges = computed(() => {\n const current = form.values?.items ?? [];\n return JSON.stringify(current) !== initialSnapshot.value;\n});\n\nconst { mutate: updateSignupRequirements } = useMutation(\n (api, config: SignupRequirementsDto) => api.appSettings.updateSignupRequirements(config),\n { invalidate: /admin-signup-requirements/ },\n);\n\nasync function handleSubmit(formData: {\n items: Array<{\n type: string;\n required: boolean;\n url: string;\n label: string;\n version: string;\n effective_at: string;\n content?: string | null;\n }>;\n}) {\n const config: SignupRequirementsDto = formData.items.map((c) => ({\n type: c.type.trim() || 'unknown',\n required: c.required,\n url: c.url.trim(),\n label: c.label.trim() || c.type.trim() || 'Consent',\n version: c.version.trim() || '1',\n effective_at:\n (c.effective_at?.trim()\n ? formatToISODatetime(c.effective_at.trim())\n : formatToISODatetime(new Date().toISOString())) ?? new Date().toISOString(),\n content: c.content?.trim() ? c.content.trim() : undefined,\n }));\n await updateSignupRequirements(config);\n}\n\nasync function handleSuccess() {\n toast.success('Signup requirements saved');\n initialSnapshot.value = JSON.stringify(form.values?.items ?? []);\n await refetch();\n await refetchVersionHistory();\n}\n\nfunction handleError(error: Error | unknown) {\n const message = error instanceof Error ? error.message : 'An unknown error occurred';\n form.setSubmitError(extractRpcErrorMessage(error, message));\n toast.error(form.submitError ?? 'Failed to save signup requirements');\n}\n\n// Version history\nconst VERSION_HISTORY_KEY = 'admin-signup-requirements-history';\n\nconst {\n data: versionHistoryData,\n loading: versionHistoryLoading,\n error: versionHistoryError,\n refetch: refetchVersionHistory,\n} = useQuery(\n async (api) =>\n api.recordVersions.listRecordVersionsPaginated(\n 'signup_requirements',\n RecordConst.APP_SETTING,\n {\n first: 50,\n sortBy: 'recorded_at',\n sortDirection: 'desc',\n },\n ),\n {\n cacheKey: VERSION_HISTORY_KEY,\n staleTime: 60 * 1000,\n },\n);\n\nconst versionHistoryItems = computed(() => versionHistoryData.value?.items ?? []);\nconst versionHistoryPageInfo = computed(() => versionHistoryData.value?.pageInfo);\nconst versionHistoryLoadingMore = ref(false);\n\nfunction loadMoreVersions() {\n // Pagination: could add cursor-based load more if needed\n}\n\nconst versionListConfig = {\n recordDisplayName: 'signup requirements',\n noVersionsText: 'No previous versions. Save changes to create the first version.',\n viewAction: (version: { id: string }) => openVersionModal(version),\n viewActionText: 'View',\n};\n\nconst versionModalRef = ref<HTMLDialogElement | null>(null);\nconst selectedVersion = ref<{\n id: string;\n operation: string;\n recorded_at: string;\n auth_username?: string | null;\n record?: unknown;\n old_record?: unknown;\n} | null>(null);\n\nconst selectedVersionRecordData = computed(() => {\n if (!selectedVersion.value) return null;\n const v = selectedVersion.value;\n const record = v.record;\n if (Array.isArray(record)) return { items: record };\n if (typeof record === 'object' && record !== null) return record;\n if (typeof record === 'string') {\n try {\n const parsed = JSON.parse(record);\n return Array.isArray(parsed) ? { items: parsed } : parsed;\n } catch {\n return { raw: record };\n }\n }\n return null;\n});\n\nconst versionViewerConfig = {\n recordDisplayName: 'signup requirements',\n title: 'Signup Requirements Version',\n onBack: () => closeVersionModal(),\n excludeFields: ['raw'],\n};\n\nfunction openVersionModal(version: { id: string; record?: unknown; old_record?: unknown }) {\n selectedVersion.value = version as typeof selectedVersion.value;\n versionModalRef.value?.showModal();\n}\n\nfunction closeVersionModal() {\n selectedVersion.value = null;\n versionModalRef.value?.close();\n}\n</script>\n"],"mappings":";;;;;;;;;;;;;;;AAYA,MAAaA,2BAET;CACF,MAAM;EACJ,OAAO;EACP,UAAU;EACV,aAAa;EACd;CACD,SAAS;EACP,OAAO;EACP,UAAU;EACV,aAAa;EACd;CACD,OAAO;EACL,OAAO;EACP,aAAa;EACd;CACD,cAAc;EACZ,OAAO;EACP,WAAW;EACX,UACE;EACH;CACD,KAAK;EACH,OAAO;EACP,UAAU;EACV,aAAa;EACd;CACD,UAAU;EACR,OAAO;EACP,UAAU;EACV,WAAW;EACZ;CACD,SAAS;EACP,OAAO;EACP,UAAU;EACV,aAAa;EACb,WAAW;EACZ;CACF;;AAGD,MAAa,gCAAgC,aAC3C,6BACA,yBACA,yBACD;;AAGD,MAAa,iCAAiC,aAC5C,EAAE,OAAO,EACP,OAAO,EAAE,MAAM,8BAA8B,CAAC,QAAQ,EAAE,CAAC,EAC1D,CAAC,EACF,0BACA,EAAE,CACH;AAED,SAAgB,yBAAmD;CACjE,MAAM,sBAAM,IAAI,MAAM;CACtB,MAAM,OAAO,MAAc,OAAO,EAAE,CAAC,SAAS,GAAG,IAAI;AAErD,QAAO;EACL,MAAM;EACN,UAAU;EACV,KAAK;EACL,OAAO;EACP,SAAS;EACT,cAPkB,GAAG,IAAI,aAAa,CAAC,GAAG,IAAI,IAAI,UAAU,GAAG,EAAE,CAAC,GAAG,IAAI,IAAI,SAAS,CAAC,CAAC,GAAG,IAAI,IAAI,UAAU,CAAC,CAAC,GAAG,IAAI,IAAI,YAAY,CAAC;EAQvI,SAAS;EACV;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACsKH,MAAM,sBAAsB;;;;EA7E5B,MAAM,EACJ,MAAM,qBACN,SAAS,WACT,YACE,UAAU,QAAQ,IAAI,YAAY,uBAAuB,EAAE,EAG9D,CAAC;EAEF,MAAM,EAAE,MAAM,OAAO,cAAc,WAAW,sBAAsB,QAClE,gCACA;GACE,WAAW;GACX,uBAAuB;GACvB,aAAa;GAEb,WAAW,YAAY;AACrB,WAAO,UAAU,MACf,OAAM,IAAI,SAAS,YAAY,WAAW,SAAS,IAAI,CAAC;AAE1D,WAAO,EAAE,OAAO,oBAAoB,SAAS,EAAE,EAAE;;GAEpD,CACF;EAED,MAAM,kBAAkB,IAAY,GAAG;EAEvC,MAAM,aAAa,eAAe;GAChC,MAAM,UAAU,KAAK,QAAQ,SAAS,EAAE;AACxC,UAAO,KAAK,UAAU,QAAQ,KAAK,gBAAgB;IACnD;EAEF,MAAM,EAAE,QAAQ,6BAA6B,aAC1C,KAAK,WAAkC,IAAI,YAAY,yBAAyB,OAAO,EACxF,EAAE,YAAY,6BAA6B,CAC5C;EAED,eAAe,aAAa,UAUzB;AAaD,SAAM,yBAZgC,SAAS,MAAM,KAAK,OAAO;IAC/D,MAAM,EAAE,KAAK,MAAM,IAAI;IACvB,UAAU,EAAE;IACZ,KAAK,EAAE,IAAI,MAAM;IACjB,OAAO,EAAE,MAAM,MAAM,IAAI,EAAE,KAAK,MAAM,IAAI;IAC1C,SAAS,EAAE,QAAQ,MAAM,IAAI;IAC7B,eACG,EAAE,cAAc,MAAK,GAClB,oBAAoB,EAAE,aAAa,MAAM,CAAA,GACzC,qCAAoB,IAAI,MAAM,EAAC,aAAa,CAAC,sBAAK,IAAI,MAAM,EAAC,aAAa;IAChF,SAAS,EAAE,SAAS,MAAM,GAAG,EAAE,QAAQ,MAAM,GAAG;IACjD,EAAE,CACmC;;EAGxC,eAAe,gBAAgB;AAC7B,SAAM,QAAQ,4BAA4B;AAC1C,mBAAgB,QAAQ,KAAK,UAAU,KAAK,QAAQ,SAAS,EAAE,CAAC;AAChE,SAAM,SAAS;AACf,SAAM,uBAAuB;;EAG/B,SAAS,YAAY,OAAwB;GAC3C,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;AACzD,QAAK,eAAe,uBAAuB,OAAO,QAAQ,CAAC;AAC3D,SAAM,MAAM,KAAK,eAAe,qCAAqC;;EAMvE,MAAM,EACJ,MAAM,oBACN,SAAS,uBACT,OAAO,qBACP,SAAS,0BACP,SACF,OAAO,QACL,IAAI,eAAe,4BACjB,uBACA,YAAY,aACZ;GACE,OAAO;GACP,QAAQ;GACR,eAAe;GAChB,CACF,EACH;GACE,UAAU;GACV,WAAW,KAAK;GACjB,CACF;EAED,MAAM,sBAAsB,eAAe,mBAAmB,OAAO,SAAS,EAAE,CAAC;EACjF,MAAM,yBAAyB,eAAe,mBAAmB,OAAO,SAAS;EACjF,MAAM,4BAA4B,IAAI,MAAM;EAE5C,SAAS,mBAAmB;EAI5B,MAAM,oBAAoB;GACxB,mBAAmB;GACnB,gBAAgB;GAChB,aAAa,YAA4B,iBAAiB,QAAQ;GAClE,gBAAgB;GACjB;EAED,MAAM,kBAAkB,IAA8B,KAAK;EAC3D,MAAM,kBAAkB,IAOd,KAAK;EAEf,MAAM,4BAA4B,eAAe;AAC/C,OAAI,CAAC,gBAAgB,MAAO,QAAO;GAEnC,MAAM,SADI,gBAAgB,MACT;AACjB,OAAI,MAAM,QAAQ,OAAO,CAAE,QAAO,EAAE,OAAO,QAAQ;AACnD,OAAI,OAAO,WAAW,YAAY,WAAW,KAAM,QAAO;AAC1D,OAAI,OAAO,WAAW,SACpB,KAAI;IACF,MAAM,SAAS,KAAK,MAAM,OAAO;AACjC,WAAO,MAAM,QAAQ,OAAO,GAAG,EAAE,OAAO,QAAQ,GAAG;WAC7C;AACN,WAAO,EAAE,KAAK,QAAQ;;AAG1B,UAAO;IACP;EAEF,MAAM,sBAAsB;GAC1B,mBAAmB;GACnB,OAAO;GACP,cAAc,mBAAmB;GACjC,eAAe,CAAC,MAAM;GACvB;EAED,SAAS,iBAAiB,SAAiE;AACzF,mBAAgB,QAAQ;AACxB,mBAAgB,OAAO,WAAW;;EAGpC,SAAS,oBAAoB;AAC3B,mBAAgB,QAAQ;AACxB,mBAAgB,OAAO,OAAO;;;uBAtU9B,mBAoJM,OApJN,YAoJM;gCAnJJ,mBAEM,OAAA,EAFD,OAAM,0CAAwC,EAAA,CACjD,mBAAuD,MAAA,EAAnD,OAAM,sBAAoB,EAAC,sBAAmB,CAAA;gCAGpD,mBAKI,KAAA,EALD,OAAM,6BAA2B,EAAA;qBAAC,yHAER;KAAA,mBAAwB,UAAA,MAAhB,UAAO;qBAAS,0KAGrD;;IAEW,MAAA,UAAS,IAAA,WAAA,EAApB,mBAEM,OAFN,YAEM,CAAA,GAAA,OAAA,OAAA,OAAA,KAAA,CADJ,mBAAwD,QAAA,EAAlD,OAAM,sCAAoC,EAAA,MAAA,GAAA,CAAA,EAAA,CAAA,KAAA,WAAA,EAGlD,mBAmIM,OAnIN,YAmIM;KAlIJ,YA0EY,MAAA,UAAA,EAAA;MAzET,gBAAe;MACf,WAAS;MACT,SAAO;MACR,OAAM;MACN,UAAS;;6BAwDU;OAtDnB,YAsDmB,MAAA,MAAA,CAAA,YAAA;QAtDD,OAAM;QAAiB,eAAa,MAAA,uBAAsB;;QAC/D,aAAW,SAId,EAJkB,WAAI,CAC5B,mBAGM,OAHN,YAGM,CAAA,gCAFD,KAAK,SAAS,KAAK,QAAI,OAAA,GAAa,KACvC,EAAA,EAAY,KAAK,QAAA,WAAA,EAAjB,mBAA4E,QAA5E,YAAoD,MAAC,gBAAG,KAAK,KAAI,GAAG,KAAC,EAAA,IAAA,mBAAA,QAAA,KAAA,CAAA,CAAA,CAAA,CAAA;QAG9D,cAAY,SA6Cf,EA7CmB,aAAM,CAC/B,mBA4CM,OA5CN,YA4CM;SA3CJ,mBAmBM,OAnBN,YAmBM;UAlBJ,YAKE,MAAA,aAAA,CAAA,WAAA;WAJC,MAAM,OAAO;WACb,OAAO,MAAA,yBAAwB,CAAC,KAAK;WACrC,aAAa,MAAA,yBAAwB,CAAC,KAAK;WAC5C,UAAA;;;;;;UAEF,YAKE,MAAA,aAAA,CAAA,WAAA;WAJC,MAAM,OAAO;WACb,OAAO,MAAA,yBAAwB,CAAC,QAAQ;WACxC,aAAa,MAAA,yBAAwB,CAAC,QAAQ;WAC/C,UAAA;;;;;;UAEF,YAKE,MAAA,aAAA,CAAA,WAAA;WAJC,MAAM,OAAO;WACb,OAAO,MAAA,yBAAwB,CAAC,MAAM;WACtC,aAAa,MAAA,yBAAwB,CAAC,MAAM;WAC7C,UAAA;;;;;;;SAGJ,YAKE,MAAA,aAAA,CAAA,WAAA;UAJC,MAAM,OAAO;UACb,OAAO,MAAA,yBAAwB,CAAC,aAAa;UAC7C,WAAW,MAAA,oBAAmB;UAC/B,UAAA;;;;;;SAEF,YAKE,MAAA,aAAA,CAAA,WAAA;UAJC,MAAM,OAAO;UACb,OAAO,MAAA,yBAAwB,CAAC,IAAI;UACpC,aAAa,MAAA,yBAAwB,CAAC,IAAI;UAC3C,MAAK;;;;;;SAEP,YAGE,MAAA,aAAA,CAAA,eAAA;UAFC,MAAM,OAAO;UACb,OAAO,MAAA,yBAAwB,CAAC,SAAS;;SAE5C,YAME,MAAA,aAAA,CAAA,eAAA;UALC,MAAM,OAAO;UACb,OAAO,MAAA,yBAAwB,CAAC,QAAQ;UACxC,aAAa,MAAA,yBAAwB,CAAC,QAAQ;UAC9C,MAAM;UACP,OAAM;;;;;;;;;OAMH,MAAA,KAAI,CAAC,eAAA,WAAA,EAAhB,mBAEM,OAFN,YAEM,CADJ,mBAAmC,QAAA,MAAA,gBAA1B,MAAA,KAAI,CAAC,YAAW,EAAA,EAAA,CAAA,CAAA,IAAA,mBAAA,QAAA,KAAA;OAG3B,mBAMM,OANN,YAMM,CALJ,YAIE,MAAA,kBAAA,EAAA;QAHA,YAAW;QACX,gBAAe;QACd,UAAQ,CAAG,WAAA;;;;;KAKlB,mBAAA,oBAAwB;KACxB,mBAoDM,OApDN,aAoDM,CAnDJ,mBAkDM,OAlDN,aAkDM;gCAjDJ,mBAAmD,MAAA,EAA/C,OAAM,sBAAoB,EAAC,mBAAe,GAAA;gCAC9C,mBAEI,KAAA,EAFD,OAAM,gCAA8B,EAAC,2EAExC,GAAA;MACA,YAUE,2BAAA;OATC,UAAU,oBAAA;OACV,SAAS,MAAA,sBAAqB;OAC9B,OAAO,MAAA,oBAAmB;OAC1B,iBAAe,uBAAA,OAAwB,eAAW;OAClD,gBAAc,0BAAA;OACd,QAAQ;OACT,kBAAA;OACC,SAAO,MAAA,sBAAqB;OAC5B,YAAW;;;;;;;;;MAEd,mBAiCS,UAAA;gBAjCG;OAAJ,KAAI;OAAkB,OAAM;UAClC,mBA4BM,OA5BN,aA4BM,CA1BI,gBAAA,SAAA,WAAA,EADR,YA0BsB,6BAAA;;OAxBnB,SAAS,gBAAA;OACT,eAAa,0BAAA;OACb,QAAQ;;OAEE,SAAO,SAeV,EAfc,iBAAU,CACnB,YAAY,OAAO,UAAA,WAAA,EAA9B,mBAcM,OAdN,aAcM,CAAA,OAAA,OAAA,OAAA,KAbJ,mBAA4D,MAAA,EAAxD,OAAM,iBAAe,EAAC,iCAA6B,GAAA,IAAA,UAAA,KAAA,EACvD,mBAWM,UAAA,MAAA,WAVkB,WAAW,QAAzB,MAAM,QAAG;4BADnB,mBAWM,OAAA;SATH,KAAK;SACN,OAAM;;SAEN,mBAAiD,OAAA,MAAA,CAAA,OAAA,OAAA,OAAA,KAA5C,mBAAsB,UAAA,MAAd,SAAK,GAAA,GAAA,gBAAS,MAAC,gBAAG,KAAK,KAAI,EAAA,EAAA,CAAA,CAAA;SACxC,mBAAuD,OAAA,MAAA,CAAA,OAAA,OAAA,OAAA,KAAlD,mBAAyB,UAAA,MAAjB,YAAQ,GAAA,GAAA,gBAAS,MAAC,gBAAG,KAAK,QAAO,EAAA,EAAA,CAAA,CAAA;SAC9C,mBAAmD,OAAA,MAAA,CAAA,OAAA,OAAA,OAAA,KAA9C,mBAAuB,UAAA,MAAf,UAAM,GAAA,GAAA,gBAAS,MAAC,gBAAG,KAAK,MAAK,EAAA,EAAA,CAAA,CAAA;SAC1C,mBAAiE,OAAA,MAAA,CAAA,OAAA,OAAA,OAAA,KAA5D,mBAA8B,UAAA,MAAtB,iBAAa,GAAA,GAAA,gBAAS,MAAC,gBAAG,KAAK,aAAY,EAAA,EAAA,CAAA,CAAA;SACxD,mBAAwE,OAAA,MAAA,CAAA,OAAA,OAAA,OAAA,KAAnE,mBAA0B,UAAA,MAAlB,aAAS,GAAA,GAAA,gBAAS,MAAC,gBAAG,KAAK,WAAQ,QAAA,KAAA,EAAA,EAAA,CAAA,CAAA;SACrC,KAAK,OAAA,WAAA,EAAhB,mBAA+D,OAAA,aAAA,CAAA,OAAA,OAAA,OAAA,KAA1C,mBAAqB,UAAA,MAAb,QAAI,GAAA,GAAA,gBAAS,MAAC,gBAAG,KAAK,IAAG,EAAA,EAAA,CAAA,CAAA,IAAA,mBAAA,QAAA,KAAA;;oCAG1D,mBAEQ,OAFR,aAEQ,gBADN,KAAK,UAAU,YAAU,MAAA,EAAA,CAAA,EAAA,EAAA,EAAA,CAAA;;+EAKjC,mBAEO,QAAA;OAFD,QAAO;OAAS,OAAM;UAC1B,mBAA+D,UAAA;OAAvD,MAAK;OAAU,SAAO;SAAmB,QAAK,CAAA,CAAA,CAAA"}
1
+ {"version":3,"file":"SignupRequirementsPage-DfbYmpQD.js","names":["consentItemFieldMetadata: {\n [K in PathsOf<typeof SignupConsentItemFormSchema>]: SchemaFieldMetadata;\n}","config: SignupRequirementsDto"],"sources":["../src/slices/admin/features/signup_requirements/signupRequirementsFormMetadata.ts","../src/slices/admin/features/signup_requirements/SignupRequirementsPage.vue"],"sourcesContent":["import {\n SignupConsentItemFormSchema,\n type SignupConsentItemFormDto,\n} from '@dragonmastery/dragoncore-shared';\nimport {\n withMetadata,\n type PathsOf,\n type SchemaFieldMetadata,\n} from '@dragonmastery/zinia-forms-core';\nimport { z } from 'zod';\n\n/** Field metadata for consent item form — keys must match schema paths */\nexport const consentItemFieldMetadata: {\n [K in PathsOf<typeof SignupConsentItemFormSchema>]: SchemaFieldMetadata;\n} = {\n type: {\n label: 'Type',\n helpText: 'Type (e.g. terms_of_service, privacy_policy)',\n placeholder: 'terms_of_service',\n },\n version: {\n label: 'Version',\n helpText: 'Version (e.g. 2025.1)',\n placeholder: '2025.1',\n },\n label: {\n label: 'Label',\n placeholder: 'Terms of Service',\n },\n effective_at: {\n label: 'Effective at',\n inputType: 'datetime-local',\n helpText:\n 'When this version becomes enforceable for existing users. Set to now for immediate effect.',\n },\n url: {\n label: 'URL',\n helpText: 'URL (link to document)',\n placeholder: 'https://example.com/terms',\n },\n required: {\n label: 'Required',\n helpText: 'User must accept to sign up',\n inputType: 'checkbox' as const,\n },\n content: {\n label: 'Content',\n helpText: 'Optional, Markdown — when set, shown in scroll box; user must scroll to bottom',\n placeholder: '# Terms of Service\\n\\nYour markdown content here...',\n inputType: 'textarea',\n },\n};\n\n/** Item schema with metadata - used as array element (like followupCreateMetadata in tracker) */\nexport const signupConsentItemFormMetadata = withMetadata(\n SignupConsentItemFormSchema,\n 'signupConsentItemForm',\n consentItemFieldMetadata,\n);\n\n/** Full form schema with items array using metadata-wrapped item schema */\nexport const signupRequirementsFormMetadata = withMetadata(\n z.object({\n items: z.array(signupConsentItemFormMetadata).default([]),\n }),\n 'signupRequirementsForm',\n {},\n);\n\nexport function createEmptyConsentItem(): SignupConsentItemFormDto {\n const now = new Date();\n const pad = (n: number) => String(n).padStart(2, '0');\n const effectiveAt = `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())}T${pad(now.getHours())}:${pad(now.getMinutes())}`;\n return {\n type: '',\n required: true,\n url: '',\n label: '',\n version: '1',\n effective_at: effectiveAt,\n content: '',\n };\n}\n","<template>\n <div class=\"mt-2\">\n <div class=\"flex justify-between items-center mb-4\">\n <h1 class=\"text-2xl font-bold\">Signup Requirements</h1>\n </div>\n\n <p class=\"text-base-content/70 mb-4\">\n Configure consent checkboxes shown on signup and consent-required flows. Each item can be\n required or optional. When <strong>content</strong> is provided, terms are shown in a\n scroll box (Markdown supported) and the user must scroll to bottom before accepting. When\n content is omitted, only a link is shown.\n </p>\n\n <div v-if=\"isLoading\" class=\"flex justify-center py-8\">\n <span class=\"loading loading-spinner loading-lg\"></span>\n </div>\n\n <div v-else class=\"space-y-6\">\n <ZiniaForm\n @handle-submit=\"handleSubmit\"\n @success=\"handleSuccess\"\n @error=\"handleError\"\n title=\"\"\n subtitle=\"\"\n >\n <zinia.ItemsField label=\"Consent Items\" :create-item=\"createEmptyConsentItem\">\n <template #itemPreview=\"{ item }\">\n <div class=\"font-medium text-sm\">\n {{ item.label || item.type || 'Item' }}\n <span v-if=\"item.type\" class=\"text-base-content/60\">({{ item.type }})</span>\n </div>\n </template>\n <template #itemRenderer=\"{ fields }\">\n <div class=\"space-y-3\">\n <div class=\"grid grid-cols-1 md:grid-cols-3 gap-3\">\n <ziniaGeneric.TextField\n :name=\"fields.type\"\n :label=\"consentItemFieldMetadata.type.label\"\n :placeholder=\"consentItemFieldMetadata.type.placeholder\"\n required\n />\n <ziniaGeneric.TextField\n :name=\"fields.version\"\n :label=\"consentItemFieldMetadata.version.label\"\n :placeholder=\"consentItemFieldMetadata.version.placeholder\"\n required\n />\n <ziniaGeneric.TextField\n :name=\"fields.label\"\n :label=\"consentItemFieldMetadata.label.label\"\n :placeholder=\"consentItemFieldMetadata.label.placeholder\"\n required\n />\n </div>\n <ziniaGeneric.DateField\n :name=\"fields.effective_at\"\n :label=\"consentItemFieldMetadata.effective_at.label\"\n :formatter=\"formatToISODatetime\"\n required\n />\n <ziniaGeneric.TextField\n :name=\"fields.url\"\n :label=\"consentItemFieldMetadata.url.label\"\n :placeholder=\"consentItemFieldMetadata.url.placeholder\"\n type=\"url\"\n />\n <ziniaGeneric.CheckboxField\n :name=\"fields.required\"\n :label=\"consentItemFieldMetadata.required.label\"\n />\n <ziniaGeneric.TextareaField\n :name=\"fields.content\"\n :label=\"consentItemFieldMetadata.content.label\"\n :placeholder=\"consentItemFieldMetadata.content.placeholder\"\n :rows=\"5\"\n class=\"font-mono text-sm\"\n />\n </div>\n </template>\n </zinia.ItemsField>\n\n <div v-if=\"form.submitError\" class=\"alert alert-error mt-2\">\n <span>{{ form.submitError }}</span>\n </div>\n\n <div class=\"mt-4 flex justify-end\">\n <ZiniaSubmitButton\n submitText=\"Save\"\n submittingText=\"Saving...\"\n :disabled=\"!hasChanges\"\n />\n </div>\n </ZiniaForm>\n\n <!-- Version History -->\n <div class=\"card bg-base-200\">\n <div class=\"card-body\">\n <h2 class=\"card-title text-lg\">Version History</h2>\n <p class=\"text-sm text-base-content/70\">\n Past changes to signup requirements. Each save creates a new version.\n </p>\n <RecordVersionList\n :versions=\"versionHistoryItems\"\n :loading=\"versionHistoryLoading\"\n :error=\"versionHistoryError\"\n :has-next-page=\"versionHistoryPageInfo?.hasNextPage ?? false\"\n :loading-more=\"versionHistoryLoadingMore\"\n :config=\"versionListConfig\"\n exclude-latest\n @retry=\"refetchVersionHistory\"\n @load-more=\"loadMoreVersions\"\n />\n <dialog ref=\"versionModalRef\" class=\"modal\">\n <div class=\"modal-box max-w-4xl max-h-[90vh] overflow-auto\">\n <RecordVersionViewer\n v-if=\"selectedVersion\"\n :version=\"selectedVersion\"\n :record-data=\"selectedVersionRecordData\"\n :config=\"versionViewerConfig\"\n >\n <template #content=\"{ recordData }\">\n <div v-if=\"recordData?.items?.length\" class=\"space-y-4\">\n <h3 class=\"font-semibold\">Consent items at this version</h3>\n <div\n v-for=\"(item, idx) in recordData.items\"\n :key=\"idx\"\n class=\"border border-base-300 rounded p-3 text-sm space-y-1\"\n >\n <div><strong>Type:</strong> {{ item.type }}</div>\n <div><strong>Version:</strong> {{ item.version }}</div>\n <div><strong>Label:</strong> {{ item.label }}</div>\n <div><strong>Effective at:</strong> {{ item.effective_at }}</div>\n <div><strong>Required:</strong> {{ item.required ? 'Yes' : 'No' }}</div>\n <div v-if=\"item.url\"><strong>URL:</strong> {{ item.url }}</div>\n </div>\n </div>\n <pre v-else class=\"text-xs bg-base-200 p-3 rounded overflow-auto max-h-96\">{{\n JSON.stringify(recordData, null, 2)\n }}</pre>\n </template>\n </RecordVersionViewer>\n </div>\n <form method=\"dialog\" class=\"modal-backdrop\">\n <button type=\"button\" @click=\"closeVersionModal\">close</button>\n </form>\n </dialog>\n </div>\n </div>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport type { SignupRequirementsDto } from '@dragonmastery/dragoncore-shared';\nimport { RecordConst } from '@dragonmastery/dragoncore-shared';\nimport { useForm } from '@dragonmastery/zinia-forms-core';\nimport { computed, ref } from 'vue';\nimport { toast } from 'vue3-toastify';\nimport RecordVersionList from '../../../../components/ui/RecordVersionList.vue';\nimport RecordVersionViewer from '../../../../components/ui/RecordVersionViewer.vue';\nimport { useMutation } from '../../../../composables/useMutation';\nimport { useQuery } from '../../../../composables/useQuery';\nimport { formatToISODatetime } from '../../../../utils/convertToLocalDateTime';\nimport { extractRpcErrorMessage } from '../../../../utils/extractRpcErrorMessage';\nimport {\n consentItemFieldMetadata,\n createEmptyConsentItem,\n signupRequirementsFormMetadata,\n} from './signupRequirementsFormMetadata';\n\nconst {\n data: _signupRequirements,\n loading: isLoading,\n refetch,\n} = useQuery((api) => api.appSettings.getSignupRequirements(), {\n // cacheKey: 'admin-signup-requirements',\n // staleTime: 30 * 1000,\n});\n\nconst { form, zinia, ziniaGeneric, ZiniaForm, ZiniaSubmitButton } = useForm(\n signupRequirementsFormMetadata,\n {\n storeName: 'admin-signup-requirements-form',\n persistToLocalStorage: false,\n renderStyle: 'daisy_ui',\n // wait for signup requirements to load\n fetchData: async () => {\n while (isLoading.value) {\n await new Promise((resolve) => setTimeout(resolve, 100));\n }\n return { items: _signupRequirements.value ?? [] };\n },\n },\n);\n\nconst initialSnapshot = ref<string>('');\n\nconst hasChanges = computed(() => {\n const current = form.values?.items ?? [];\n return JSON.stringify(current) !== initialSnapshot.value;\n});\n\nconst { mutate: updateSignupRequirements } = useMutation(\n (api, config: SignupRequirementsDto) => api.appSettings.updateSignupRequirements(config),\n { invalidate: /admin-signup-requirements/ },\n);\n\nasync function handleSubmit(formData: {\n items: Array<{\n type: string;\n required: boolean;\n url: string;\n label: string;\n version: string;\n effective_at: string;\n content?: string | null;\n }>;\n}) {\n const config: SignupRequirementsDto = formData.items.map((c) => ({\n type: c.type.trim() || 'unknown',\n required: c.required,\n url: c.url.trim(),\n label: c.label.trim() || c.type.trim() || 'Consent',\n version: c.version.trim() || '1',\n effective_at:\n (c.effective_at?.trim()\n ? formatToISODatetime(c.effective_at.trim())\n : formatToISODatetime(new Date().toISOString())) ?? new Date().toISOString(),\n content: c.content?.trim() ? c.content.trim() : undefined,\n }));\n await updateSignupRequirements(config);\n}\n\nasync function handleSuccess() {\n toast.success('Signup requirements saved');\n initialSnapshot.value = JSON.stringify(form.values?.items ?? []);\n await refetch();\n await refetchVersionHistory();\n}\n\nfunction handleError(error: Error | unknown) {\n const message = error instanceof Error ? error.message : 'An unknown error occurred';\n form.setSubmitError(extractRpcErrorMessage(error, message));\n toast.error(form.submitError ?? 'Failed to save signup requirements');\n}\n\n// Version history\nconst VERSION_HISTORY_KEY = 'admin-signup-requirements-history';\n\nconst {\n data: versionHistoryData,\n loading: versionHistoryLoading,\n error: versionHistoryError,\n refetch: refetchVersionHistory,\n} = useQuery(\n async (api) =>\n api.recordVersions.listRecordVersionsPaginated(\n 'signup_requirements',\n RecordConst.APP_SETTING,\n {\n first: 50,\n sortBy: 'recorded_at',\n sortDirection: 'desc',\n },\n ),\n {\n cacheKey: VERSION_HISTORY_KEY,\n staleTime: 60 * 1000,\n },\n);\n\nconst versionHistoryItems = computed(() => versionHistoryData.value?.items ?? []);\nconst versionHistoryPageInfo = computed(() => versionHistoryData.value?.pageInfo);\nconst versionHistoryLoadingMore = ref(false);\n\nfunction loadMoreVersions() {\n // Pagination: could add cursor-based load more if needed\n}\n\nconst versionListConfig = {\n recordDisplayName: 'signup requirements',\n noVersionsText: 'No previous versions. Save changes to create the first version.',\n viewAction: (version: { id: string }) => openVersionModal(version),\n viewActionText: 'View',\n};\n\nconst versionModalRef = ref<HTMLDialogElement | null>(null);\nconst selectedVersion = ref<{\n id: string;\n operation: string;\n recorded_at: string;\n auth_username?: string | null;\n record?: unknown;\n old_record?: unknown;\n} | null>(null);\n\nconst selectedVersionRecordData = computed(() => {\n if (!selectedVersion.value) return null;\n const v = selectedVersion.value;\n const record = v.record;\n if (Array.isArray(record)) return { items: record };\n if (typeof record === 'object' && record !== null) return record;\n if (typeof record === 'string') {\n try {\n const parsed = JSON.parse(record);\n return Array.isArray(parsed) ? { items: parsed } : parsed;\n } catch {\n return { raw: record };\n }\n }\n return null;\n});\n\nconst versionViewerConfig = {\n recordDisplayName: 'signup requirements',\n title: 'Signup Requirements Version',\n onBack: () => closeVersionModal(),\n excludeFields: ['raw'],\n};\n\nfunction openVersionModal(version: { id: string; record?: unknown; old_record?: unknown }) {\n selectedVersion.value = version as typeof selectedVersion.value;\n versionModalRef.value?.showModal();\n}\n\nfunction closeVersionModal() {\n selectedVersion.value = null;\n versionModalRef.value?.close();\n}\n</script>\n"],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ import "./useRpcAuth-rmHf7bYx.js";
2
+ import "./useQueryCache-Bjm-S8v5.js";
3
+ import "./useMutation-BTsyHKyn.js";
4
+ import "./useQuery-BggIE52P.js";
5
+ import { E as StaffCreateSupportTicketForm_default } from "./src-QZJyMfGX.js";
6
+ import "./AppLink-CHMMrSFI.js";
7
+ import "./TimelineSystemEvent-BHzFr46C.js";
8
+ import "./TeamMembersTab-4gmnP9sD.js";
9
+ import "./Appearance-DxWTyx1M.js";
10
+ import "./useSignupPendingData-BWHwUHhL.js";
11
+ import "./useBreadcrumbs-qB6ghsAf.js";
12
+ import "./EditTeamMemberForm-CaS2GLjV.js";
13
+ import "./RecordVersionViewer-BWZ78vvE.js";
14
+ import "./TeamHistoryTab-D5biUPmq.js";
15
+ import "./UserProfilePage-C3b93Keh.js";
16
+ import "./ChangePasswordPage--3XwluwE.js";
17
+ import "./TeamNotesTab-BzGZZ1h8.js";
18
+ import "./CustomerSupportTicketParent-HIxwSVdu.js";
19
+ import "./SupportTicketDevLifecycleBadge-EMrQHfyG.js";
20
+ import "./StaffSupportTicketParent-CilR4RGM.js";
21
+ import "./LoginForm-9UFnA-fO.js";
22
+ import "./useEmailVerificationChannel-BNi926Ho.js";
23
+ import "./Signup-9TjMMnU4.js";
24
+ import "./ForgotPassword-OjIPi9s9.js";
25
+ import "./ResetPassword-BE4mXK9q.js";
26
+ import "./Logout-YgTgOFUH.js";
27
+ import "./mfaSchema-BnRWf0ma.js";
28
+ import "./MfaSetup-RtFMY_dj.js";
29
+ import "./MfaVerify-Cvhe8bEM.js";
30
+ import "./VerifyEmail-DlOmWGG-.js";
31
+ import "./UserListPage-DUE5gJTo.js";
32
+ import "./CreateUserPage-DLwXeLAq.js";
33
+ import "./EditUserPage-DURc5rmi.js";
34
+
35
+ export { StaffCreateSupportTicketForm_default as default };
@@ -1,13 +1,13 @@
1
- import { t as BATCH_MODE } from "./useRpcAuth-Bse-lggK.js";
2
- import "./useQueryCache-CJKZquh6.js";
3
- import { t as useMutation } from "./useMutation-Dhx2gMgS.js";
4
- import { t as useQuery } from "./useQuery-DxmMxM8z.js";
5
- import { a as SupportTicketTypeBadge_default, i as SupportTicketApprovalBadge_default, l as formatStaffCreditValue, n as TimelineItem_default, o as SupportTicketPriorityBadge_default, r as formatTicketDate, t as TimelineSystemEvent_default } from "./TimelineSystemEvent-Cc6HMeO3.js";
1
+ import { t as BATCH_MODE } from "./useRpcAuth-rmHf7bYx.js";
2
+ import "./useQueryCache-Bjm-S8v5.js";
3
+ import { t as useMutation } from "./useMutation-BTsyHKyn.js";
4
+ import { t as useQuery } from "./useQuery-BggIE52P.js";
5
+ import { a as SupportTicketTypeBadge_default, i as SupportTicketApprovalBadge_default, l as formatStaffCreditValue, n as TimelineItem_default, o as SupportTicketPriorityBadge_default, r as formatTicketDate, t as TimelineSystemEvent_default } from "./TimelineSystemEvent-BHzFr46C.js";
6
6
  import { n as formatToISODate } from "./convertToLocalDateTime-CFhtN6PI.js";
7
7
  import { t as extractRpcErrorMessage } from "./extractRpcErrorMessage-Di8E8-Wh.js";
8
8
  import { t as formatTicketDisplayId } from "./displayIdFormatter-Dz900Awr.js";
9
9
  import { t as SupportTicketDevLifecycleBadge_default } from "./SupportTicketDevLifecycleBadge-EMrQHfyG.js";
10
- import { a as SupportTicketAttachmentsCollapsible_default, i as parseRecordVersions, n as MetadataField_default, r as ActionBannerAlert_default, t as TimelineNoteInput_default } from "./TimelineNoteInput-D-NjzUiF.js";
10
+ import { a as SupportTicketAttachmentsCollapsible_default, i as parseRecordVersions, n as MetadataField_default, r as ActionBannerAlert_default, t as TimelineNoteInput_default } from "./TimelineNoteInput-0p-M4Qie.js";
11
11
  import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, inject, nextTick, normalizeClass, openBlock, ref, renderList, resolveComponent, toDisplayString, unref, vModelCheckbox, vModelSelect, vModelText, watch, withCtx, withDirectives } from "vue";
12
12
  import { useRoute, useRouter } from "vue-router";
13
13
  import { toast } from "vue3-toastify";
@@ -1925,4 +1925,4 @@ var StaffSupportTicketDetailPage_default = _sfc_main;
1925
1925
 
1926
1926
  //#endregion
1927
1927
  export { StaffSupportTicketDetailPage_default as default };
1928
- //# sourceMappingURL=StaffSupportTicketDetailPage-D0SjH36N.js.map
1928
+ //# sourceMappingURL=StaffSupportTicketDetailPage-DQdfh6H1.js.map