@dragonmastery/dragoncore-vue 0.0.19 → 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 (182) hide show
  1. package/dist/AppLink-CHMMrSFI.js +54 -0
  2. package/dist/AppLink-CHMMrSFI.js.map +1 -0
  3. package/dist/Appearance-D5pwxuf4.js +3 -0
  4. package/dist/{Appearance-BfPdKMXw.js → Appearance-DxWTyx1M.js} +1 -1
  5. package/dist/{Appearance-BfPdKMXw.js.map → Appearance-DxWTyx1M.js.map} +1 -1
  6. package/dist/{ChangePasswordPage-DXzU3NI9.js → ChangePasswordPage--3XwluwE.js} +2 -2
  7. package/dist/{ChangePasswordPage-DXzU3NI9.js.map → ChangePasswordPage--3XwluwE.js.map} +1 -1
  8. package/dist/ChangePasswordPage-CpDPmEml.js +6 -0
  9. package/dist/ConsentRequired-C4IRMA0c.js +213 -0
  10. package/dist/ConsentRequired-C4IRMA0c.js.map +1 -0
  11. package/dist/CreateTeamForm-B4cIuYAf.js +35 -0
  12. package/dist/CreateTeamMemberForm-Chrw1y00.js +35 -0
  13. package/dist/{CreateUserPage-bwR6fq5C.js → CreateUserPage-DLwXeLAq.js} +2 -2
  14. package/dist/{CreateUserPage-bwR6fq5C.js.map → CreateUserPage-DLwXeLAq.js.map} +1 -1
  15. package/dist/CreateUserPage-WruMs7WP.js +6 -0
  16. package/dist/CreditBalanceDashboard-CkcsrZ_e.js +35 -0
  17. package/dist/CreditManagement-Ddvu9dMw.js +35 -0
  18. package/dist/CustomerCreateSupportTicketForm-BKperKGS.js +35 -0
  19. package/dist/{CustomerSupportTicketDetailPage-D_1t2EpN.js → CustomerSupportTicketDetailPage-BdyaKG1v.js} +9 -9
  20. package/dist/{CustomerSupportTicketDetailPage-D_1t2EpN.js.map → CustomerSupportTicketDetailPage-BdyaKG1v.js.map} +1 -1
  21. package/dist/CustomerSupportTicketList-DcbrjDa9.js +35 -0
  22. package/dist/CustomerSupportTicketParent-BeNzUwuP.js +7 -0
  23. package/dist/{CustomerSupportTicketParent-B09_iFpJ.js → CustomerSupportTicketParent-HIxwSVdu.js} +4 -4
  24. package/dist/{CustomerSupportTicketParent-B09_iFpJ.js.map → CustomerSupportTicketParent-HIxwSVdu.js.map} +1 -1
  25. package/dist/CustomerSupportTicketSuccess-CC967u3y.js +35 -0
  26. package/dist/EditTeamForm-B5Tee5wL.js +35 -0
  27. package/dist/{EditTeamMemberForm-DJW7yRQW.js → EditTeamMemberForm-CaS2GLjV.js} +2 -2
  28. package/dist/{EditTeamMemberForm-DJW7yRQW.js.map → EditTeamMemberForm-CaS2GLjV.js.map} +1 -1
  29. package/dist/EditTeamMemberForm-OtcS8QWt.js +6 -0
  30. package/dist/{EditUserPage-aDygGmfD.js → EditUserPage-DURc5rmi.js} +4 -4
  31. package/dist/{EditUserPage-aDygGmfD.js.map → EditUserPage-DURc5rmi.js.map} +1 -1
  32. package/dist/EditUserPage-T4DQlKhf.js +7 -0
  33. package/dist/ForgotPassword-CUifhmqP.js +7 -0
  34. package/dist/{ForgotPassword-CJjzm9GK.js → ForgotPassword-OjIPi9s9.js} +4 -3
  35. package/dist/{ForgotPassword-CJjzm9GK.js.map → ForgotPassword-OjIPi9s9.js.map} +1 -1
  36. package/dist/LoginForm-9UFnA-fO.js +118 -0
  37. package/dist/LoginForm-9UFnA-fO.js.map +1 -0
  38. package/dist/LoginForm-Bg7GoZEA.js +7 -0
  39. package/dist/Logout-Bs92csWH.js +7 -0
  40. package/dist/{Logout-Cm9kEzgH.js → Logout-YgTgOFUH.js} +5 -4
  41. package/dist/{Logout-Cm9kEzgH.js.map → Logout-YgTgOFUH.js.map} +1 -1
  42. package/dist/MfaSetup-BACX5XP-.js +8 -0
  43. package/dist/{MfaSetup-Ch0w-gTN.js → MfaSetup-RtFMY_dj.js} +5 -4
  44. package/dist/{MfaSetup-Ch0w-gTN.js.map → MfaSetup-RtFMY_dj.js.map} +1 -1
  45. package/dist/{MfaVerify-BwzjVrTj.js → MfaVerify-Cvhe8bEM.js} +6 -5
  46. package/dist/{MfaVerify-BwzjVrTj.js.map → MfaVerify-Cvhe8bEM.js.map} +1 -1
  47. package/dist/MfaVerify-ak4iSdQ2.js +8 -0
  48. package/dist/RecordVersionViewer-BWZ78vvE.js +490 -0
  49. package/dist/RecordVersionViewer-BWZ78vvE.js.map +1 -0
  50. package/dist/{ResetPassword-DuLuXaNp.js → ResetPassword-BE4mXK9q.js} +4 -3
  51. package/dist/{ResetPassword-DuLuXaNp.js.map → ResetPassword-BE4mXK9q.js.map} +1 -1
  52. package/dist/ResetPassword-pY1uhTdl.js +7 -0
  53. package/dist/{SavedFiltersPage-CawED9Oz.js → SavedFiltersPage-DQt6uc8m.js} +33 -30
  54. package/dist/{SavedFiltersPage-CawED9Oz.js.map → SavedFiltersPage-DQt6uc8m.js.map} +1 -1
  55. package/dist/Signup-9TjMMnU4.js +204 -0
  56. package/dist/Signup-9TjMMnU4.js.map +1 -0
  57. package/dist/Signup-Bq-G3D-s.js +9 -0
  58. package/dist/SignupConsentFlow-QUZGKjdB.js +269 -0
  59. package/dist/SignupConsentFlow-QUZGKjdB.js.map +1 -0
  60. package/dist/SignupRequirementsPage-DfbYmpQD.js +360 -0
  61. package/dist/SignupRequirementsPage-DfbYmpQD.js.map +1 -0
  62. package/dist/StaffCreateSupportTicketForm-D0ZuisDk.js +35 -0
  63. package/dist/{StaffSupportTicketDetailPage-DZZN3jmt.js → StaffSupportTicketDetailPage-DQdfh6H1.js} +11 -11
  64. package/dist/{StaffSupportTicketDetailPage-DZZN3jmt.js.map → StaffSupportTicketDetailPage-DQdfh6H1.js.map} +1 -1
  65. package/dist/StaffSupportTicketList-CiqC05XB.js +35 -0
  66. package/dist/{StaffSupportTicketParent-BYxQPuhI.js → StaffSupportTicketParent-CilR4RGM.js} +4 -4
  67. package/dist/{StaffSupportTicketParent-BYxQPuhI.js.map → StaffSupportTicketParent-CilR4RGM.js.map} +1 -1
  68. package/dist/StaffSupportTicketParent-DkV329NI.js +7 -0
  69. package/dist/StaffSupportTicketSuccess-CUYnimaI.js +35 -0
  70. package/dist/{SupportStaffPage-B05UR5LK.js → SupportStaffPage-KKugAnFm.js} +7 -7
  71. package/dist/{SupportStaffPage-B05UR5LK.js.map → SupportStaffPage-KKugAnFm.js.map} +1 -1
  72. package/dist/{SupportTicketDevLifecycleBadge-Ba-Rm6QW.js → SupportTicketDevLifecycleBadge-EMrQHfyG.js} +1 -1
  73. package/dist/{SupportTicketDevLifecycleBadge-Ba-Rm6QW.js.map → SupportTicketDevLifecycleBadge-EMrQHfyG.js.map} +1 -1
  74. package/dist/{SupportTicketMaintenancePage-BoZpjcAF.js → SupportTicketMaintenancePage-smItdkrD.js} +4 -4
  75. package/dist/{SupportTicketMaintenancePage-BoZpjcAF.js.map → SupportTicketMaintenancePage-smItdkrD.js.map} +1 -1
  76. package/dist/TeamAttachmentsTab-DUtCD1Yi.js +35 -0
  77. package/dist/TeamHistoryTab-BsUoH4VK.js +4 -0
  78. package/dist/{TeamHistoryTab-BrC6FFIw.js → TeamHistoryTab-D5biUPmq.js} +3 -3
  79. package/dist/{TeamHistoryTab-BrC6FFIw.js.map → TeamHistoryTab-D5biUPmq.js.map} +1 -1
  80. package/dist/TeamList-BkPIqZ8V.js +35 -0
  81. package/dist/TeamMemberList-1mxUGCNa.js +35 -0
  82. package/dist/TeamMemberParent-DzeBIElY.js +35 -0
  83. package/dist/{TeamNotesTab-B2eETkAz.js → TeamNotesTab-BzGZZ1h8.js} +5 -5
  84. package/dist/{TeamNotesTab-B2eETkAz.js.map → TeamNotesTab-BzGZZ1h8.js.map} +1 -1
  85. package/dist/TeamNotesTab-ClHl2nXd.js +7 -0
  86. package/dist/TeamParent-DJa9UZTP.js +35 -0
  87. package/dist/{TimelineNoteInput-C0a0WRQC.js → TimelineNoteInput-0p-M4Qie.js} +2 -2
  88. package/dist/{TimelineNoteInput-C0a0WRQC.js.map → TimelineNoteInput-0p-M4Qie.js.map} +1 -1
  89. package/dist/{TimelineSystemEvent-Dj2TMOF6.js → TimelineSystemEvent-BHzFr46C.js} +4 -4
  90. package/dist/{TimelineSystemEvent-Dj2TMOF6.js.map → TimelineSystemEvent-BHzFr46C.js.map} +1 -1
  91. package/dist/UserListPage-BTLE4J0s.js +4 -0
  92. package/dist/{UserListPage-QSdxrJT6.js → UserListPage-DUE5gJTo.js} +3 -3
  93. package/dist/{UserListPage-QSdxrJT6.js.map → UserListPage-DUE5gJTo.js.map} +1 -1
  94. package/dist/{UserProfilePage-X4z2lG-J.js → UserProfilePage-C3b93Keh.js} +4 -4
  95. package/dist/{UserProfilePage-X4z2lG-J.js.map → UserProfilePage-C3b93Keh.js.map} +1 -1
  96. package/dist/UserProfilePage-CVTORtSx.js +7 -0
  97. package/dist/VerifyEmail-DCP4DWIw.js +9 -0
  98. package/dist/VerifyEmail-DlOmWGG-.js +257 -0
  99. package/dist/VerifyEmail-DlOmWGG-.js.map +1 -0
  100. package/dist/ViewTeam-DVfnLMhV.js +35 -0
  101. package/dist/ViewTeamMember-L4v3gCIn.js +35 -0
  102. package/dist/{convertToLocalDateTime-DOSGtMn8.js → convertToLocalDateTime-CFhtN6PI.js} +12 -2
  103. package/dist/convertToLocalDateTime-CFhtN6PI.js.map +1 -0
  104. package/dist/{displayIdFormatter-B1ZKgofu.js → displayIdFormatter-Dz900Awr.js} +1 -1
  105. package/dist/{displayIdFormatter-B1ZKgofu.js.map → displayIdFormatter-Dz900Awr.js.map} +1 -1
  106. package/dist/{extractRpcErrorMessage-C_UbKgHL.js → extractRpcErrorMessage-Di8E8-Wh.js} +1 -1
  107. package/dist/{extractRpcErrorMessage-C_UbKgHL.js.map → extractRpcErrorMessage-Di8E8-Wh.js.map} +1 -1
  108. package/dist/index.d.ts +62 -17
  109. package/dist/index.js +37 -33
  110. package/dist/{mfaSchema-nfNCcEhM.js → mfaSchema-BnRWf0ma.js} +1 -1
  111. package/dist/{mfaSchema-nfNCcEhM.js.map → mfaSchema-BnRWf0ma.js.map} +1 -1
  112. package/dist/{src-CkgUIye9.js → src-QZJyMfGX.js} +422 -812
  113. package/dist/src-QZJyMfGX.js.map +1 -0
  114. package/dist/{useBreadcrumbs-DmgSucoe.js → useBreadcrumbs-qB6ghsAf.js} +1 -1
  115. package/dist/{useBreadcrumbs-DmgSucoe.js.map → useBreadcrumbs-qB6ghsAf.js.map} +1 -1
  116. package/dist/useEmailVerificationChannel-BNi926Ho.js +37 -0
  117. package/dist/useEmailVerificationChannel-BNi926Ho.js.map +1 -0
  118. package/dist/{useMutation-DbzXtqf1.js → useMutation-BTsyHKyn.js} +3 -3
  119. package/dist/{useMutation-DbzXtqf1.js.map → useMutation-BTsyHKyn.js.map} +1 -1
  120. package/dist/{useQuery-BKb5JXVS.js → useQuery-BggIE52P.js} +5 -5
  121. package/dist/useQuery-BggIE52P.js.map +1 -0
  122. package/dist/{useQueryCache-CHG4-HGF.js → useQueryCache-Bjm-S8v5.js} +2 -2
  123. package/dist/{useQueryCache-CHG4-HGF.js.map → useQueryCache-Bjm-S8v5.js.map} +1 -1
  124. package/dist/{useReturnUrl-Da8PpLb9.js → useReturnUrl-qFeazn-G.js} +2 -54
  125. package/dist/useReturnUrl-qFeazn-G.js.map +1 -0
  126. package/dist/{useRpcAuth-8Byr6SSI.js → useRpcAuth-rmHf7bYx.js} +42 -2
  127. package/dist/useRpcAuth-rmHf7bYx.js.map +1 -0
  128. package/dist/useSignupPendingData-BWHwUHhL.js +47 -0
  129. package/dist/useSignupPendingData-BWHwUHhL.js.map +1 -0
  130. package/package.json +5 -2
  131. package/src/daisyui.css +1 -0
  132. package/dist/Appearance-C3WguxT-.js +0 -3
  133. package/dist/ChangePasswordPage-BuVNYC_G.js +0 -6
  134. package/dist/CreateTeamForm-BuMrZ169.js +0 -32
  135. package/dist/CreateTeamMemberForm-D0xqR9me.js +0 -32
  136. package/dist/CreateUserPage-BWIvFF-4.js +0 -6
  137. package/dist/CreditBalanceDashboard-BR-er7gs.js +0 -32
  138. package/dist/CreditManagement-CyjrE1ep.js +0 -32
  139. package/dist/CustomerCreateSupportTicketForm-C9-CLRRQ.js +0 -32
  140. package/dist/CustomerSupportTicketList-B0dC7lgD.js +0 -32
  141. package/dist/CustomerSupportTicketParent-D0wLnKXf.js +0 -7
  142. package/dist/CustomerSupportTicketSuccess-BvuBglg8.js +0 -32
  143. package/dist/EditTeamForm-BJlOKEkI.js +0 -32
  144. package/dist/EditTeamMemberForm-CbDvTLXI.js +0 -6
  145. package/dist/EditUserPage-CsHl1h_g.js +0 -7
  146. package/dist/ForgotPassword-DJjmzU_m.js +0 -7
  147. package/dist/LoginForm-BeiI_y3E.js +0 -7
  148. package/dist/LoginForm-IEP-hEh0.js +0 -115
  149. package/dist/LoginForm-IEP-hEh0.js.map +0 -1
  150. package/dist/Logout-DmZTNQDP.js +0 -7
  151. package/dist/MfaSetup-BwkenBRD.js +0 -8
  152. package/dist/MfaVerify-BaUROEol.js +0 -8
  153. package/dist/ResetPassword-DEFj1pgV.js +0 -7
  154. package/dist/Signup-C94alv87.js +0 -166
  155. package/dist/Signup-C94alv87.js.map +0 -1
  156. package/dist/Signup-CFUbdrYs.js +0 -7
  157. package/dist/StaffCreateSupportTicketForm-AxprwWRv.js +0 -32
  158. package/dist/StaffSupportTicketList-DYKysNs3.js +0 -32
  159. package/dist/StaffSupportTicketParent-CT8oYFd6.js +0 -7
  160. package/dist/StaffSupportTicketSuccess-zWEagE4E.js +0 -32
  161. package/dist/TeamAttachmentsTab-BFRMbPlZ.js +0 -32
  162. package/dist/TeamHistoryTab-CYrt5KnE.js +0 -4
  163. package/dist/TeamList-CF5BQhfx.js +0 -32
  164. package/dist/TeamMemberList-Dfi2iKOH.js +0 -32
  165. package/dist/TeamMemberParent-DXcumR-Q.js +0 -32
  166. package/dist/TeamNotesTab-Bv_HPC6f.js +0 -7
  167. package/dist/TeamParent-DLoNn-mW.js +0 -32
  168. package/dist/UserListPage-CBwfXo15.js +0 -4
  169. package/dist/UserProfilePage-cTrZuwOT.js +0 -7
  170. package/dist/VerifyEmail-8bsvoDdM.js +0 -175
  171. package/dist/VerifyEmail-8bsvoDdM.js.map +0 -1
  172. package/dist/VerifyEmail-Cpc0umIu.js +0 -7
  173. package/dist/VerifyEmailRequired-CN1FU1AE.js +0 -74
  174. package/dist/VerifyEmailRequired-CN1FU1AE.js.map +0 -1
  175. package/dist/ViewTeam-DpjnoTwo.js +0 -32
  176. package/dist/ViewTeamMember-CRb2oBHG.js +0 -32
  177. package/dist/convertToLocalDateTime-DOSGtMn8.js.map +0 -1
  178. package/dist/src-CkgUIye9.js.map +0 -1
  179. package/dist/useQuery-BKb5JXVS.js.map +0 -1
  180. package/dist/useReturnUrl-Da8PpLb9.js.map +0 -1
  181. package/dist/useRpcAuth-8Byr6SSI.js.map +0 -1
  182. /package/dist/{TeamMembersTab-DTJxmb-M.js → TeamMembersTab-CBB2Yl_I.js} +0 -0
@@ -0,0 +1,269 @@
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
+ import { i as setEmailVerificationReturnUrl, o as withReturnUrl, r as getValidReturnUrl } from "./useReturnUrl-qFeazn-G.js";
5
+ import { n as SIGNUP_REQUIREMENTS_KEY, t as useSignupPendingData } from "./useSignupPendingData-BWHwUHhL.js";
6
+ import { Fragment, computed, createCommentVNode, createElementBlock, createElementVNode, defineComponent, inject, nextTick, openBlock, ref, toDisplayString, watch } from "vue";
7
+ import { useRoute, useRouter } from "vue-router";
8
+ import { toast } from "vue3-toastify";
9
+ import DOMPurify from "dompurify";
10
+ import { marked } from "marked";
11
+
12
+ //#region src/slices/auth/features/signup_consents/SignupConsentFlow.vue
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
+ const _hoisted_2 = {
15
+ key: 0,
16
+ class: "text-center"
17
+ };
18
+ const _hoisted_3 = {
19
+ key: 1,
20
+ class: "space-y-6"
21
+ };
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 = {
26
+ key: 0,
27
+ class: "alert alert-error flex flex-col gap-3"
28
+ };
29
+ const _hoisted_8 = { class: "flex flex-wrap gap-2 mt-1" };
30
+ const _hoisted_9 = ["disabled"];
31
+ const _hoisted_10 = ["disabled"];
32
+ const _hoisted_11 = {
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"
42
+ };
43
+ const _hoisted_16 = ["disabled"];
44
+ const _hoisted_17 = ["disabled"];
45
+ const _sfc_main = /* @__PURE__ */ defineComponent({
46
+ __name: "SignupConsentFlow",
47
+ setup(__props) {
48
+ const signupRequirements = inject(SIGNUP_REQUIREMENTS_KEY, () => [], true);
49
+ const { get: getSignupPendingData, clear: clearSignupPendingData } = useSignupPendingData();
50
+ const sessionStore = useUserSessionStore();
51
+ const router = useRouter();
52
+ const route = useRoute();
53
+ const { emailVerificationMode } = useEnv();
54
+ const returnUrl = computed(() => route.query.returnUrl);
55
+ const signupData = computed(() => getSignupPendingData());
56
+ const currentStep = ref(1);
57
+ const totalSteps = computed(() => signupRequirements?.length ?? 0);
58
+ const currentConfig = computed(() => signupRequirements?.[currentStep.value - 1] ?? null);
59
+ const hasScrolledToBottom = ref(false);
60
+ const scrollEl = ref(null);
61
+ function setScrollRef(el) {
62
+ scrollEl.value = el instanceof HTMLElement ? el : null;
63
+ }
64
+ watch(() => currentConfig.value, (config) => {
65
+ hasScrolledToBottom.value = !config?.content;
66
+ nextTick(() => {
67
+ scrollEl.value?.scrollTo(0, 0);
68
+ });
69
+ }, { immediate: true });
70
+ function renderMarkdown(content) {
71
+ const html = marked.parse(content);
72
+ return DOMPurify.sanitize(html, {
73
+ ALLOWED_TAGS: [
74
+ "p",
75
+ "br",
76
+ "strong",
77
+ "em",
78
+ "u",
79
+ "a",
80
+ "ul",
81
+ "ol",
82
+ "li",
83
+ "h1",
84
+ "h2",
85
+ "h3",
86
+ "h4",
87
+ "blockquote",
88
+ "code",
89
+ "pre",
90
+ "hr"
91
+ ],
92
+ ALLOWED_ATTR: [
93
+ "href",
94
+ "target",
95
+ "rel"
96
+ ]
97
+ });
98
+ }
99
+ function checkScrolledToBottom() {
100
+ const el = scrollEl.value;
101
+ if (!el) return;
102
+ const { scrollTop, scrollHeight, clientHeight } = el;
103
+ if (scrollHeight - scrollTop - clientHeight < 10) hasScrolledToBottom.value = true;
104
+ }
105
+ function onScroll() {
106
+ checkScrolledToBottom();
107
+ }
108
+ nextTick(checkScrolledToBottom);
109
+ const declining = ref(false);
110
+ const goingBack = ref(false);
111
+ const submitting = ref(false);
112
+ const submitError = ref(null);
113
+ function getErrorMessage(error) {
114
+ if (error instanceof Error && error.message) return error.message;
115
+ if (error && typeof error === "object" && "message" in error && typeof error.message === "string") return error.message;
116
+ return "Registration failed. Please try again.";
117
+ }
118
+ const { mutate: signupMutate } = useMutation((api, input) => api.users.signupUser(input), { skipAuthCheck: true });
119
+ const { mutate: loginMutate } = useMutation((api, input) => api.userSessions.login(input), { credentials: "include" });
120
+ async function handleAccept() {
121
+ if (!currentConfig.value || !signupData.value) return;
122
+ submitError.value = null;
123
+ const acceptancesSoFar = {};
124
+ for (let i = 0; i < currentStep.value; i++) {
125
+ const c = signupRequirements?.[i];
126
+ if (c) acceptancesSoFar[c.type] = true;
127
+ }
128
+ if (currentStep.value >= totalSteps.value) {
129
+ submitting.value = true;
130
+ try {
131
+ await completeSignup(acceptancesSoFar);
132
+ } catch (err) {
133
+ submitError.value = getErrorMessage(err);
134
+ } finally {
135
+ submitting.value = false;
136
+ }
137
+ return;
138
+ }
139
+ currentStep.value++;
140
+ hasScrolledToBottom.value = !currentConfig.value?.content;
141
+ nextTick(checkScrolledToBottom);
142
+ }
143
+ async function completeSignup(acceptances) {
144
+ const data = signupData.value;
145
+ if (!data) return;
146
+ if (!await signupMutate({
147
+ ...data,
148
+ acceptances
149
+ })) throw new Error("Signup failed");
150
+ clearSignupPendingData();
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 {}
162
+ if (emailVerificationMode === "strict") setEmailVerificationReturnUrl(getValidReturnUrl(route, "/"));
163
+ window.scrollTo(0, 0);
164
+ const verifyPath = withReturnUrl("/auth/verify-email", returnUrl.value);
165
+ await router.push(verifyPath);
166
+ return;
167
+ }
168
+ const loginResult = await loginMutate({
169
+ email: data.email,
170
+ password: data.passwords.password
171
+ });
172
+ if (!loginResult?.access_token || !loginResult?.user_details_token) throw new Error("Failed to login after signup");
173
+ sessionStore.setSession(loginResult.user_details_token);
174
+ sessionStore.setAccessToken(loginResult.access_token);
175
+ window.scrollTo(0, 0);
176
+ const defaultRedirect = getValidReturnUrl(route, "/");
177
+ await router.push(defaultRedirect);
178
+ toast.success("Registration successful! You are now logged in.");
179
+ }
180
+ async function handleDecline() {
181
+ declining.value = true;
182
+ try {
183
+ clearSignupPendingData();
184
+ const signupPath = withReturnUrl("/auth/signup", returnUrl.value);
185
+ await router.push({
186
+ path: signupPath,
187
+ query: {
188
+ ...route.query,
189
+ declined: "1"
190
+ }
191
+ });
192
+ } finally {
193
+ declining.value = false;
194
+ }
195
+ }
196
+ async function goBackToSignup() {
197
+ goingBack.value = true;
198
+ try {
199
+ clearSignupPendingData();
200
+ const signupPath = withReturnUrl("/auth/signup", returnUrl.value);
201
+ const { declined: _d, ...rest } = route.query;
202
+ await router.push({
203
+ path: signupPath,
204
+ query: rest
205
+ });
206
+ } finally {
207
+ goingBack.value = false;
208
+ }
209
+ }
210
+ return (_ctx, _cache) => {
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, [
218
+ createElementVNode("span", null, toDisplayString(submitError.value), 1),
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", {
221
+ type: "button",
222
+ class: "btn btn-primary btn-sm",
223
+ disabled: goingBack.value || submitting.value,
224
+ onClick: goBackToSignup
225
+ }, toDisplayString(goingBack.value ? "Returning..." : "Back to sign up"), 9, _hoisted_9), createElementVNode("button", {
226
+ type: "button",
227
+ class: "btn btn-ghost btn-sm",
228
+ disabled: submitting.value || goingBack.value,
229
+ onClick: handleAccept
230
+ }, toDisplayString(submitting.value ? "Submitting..." : "Try again"), 9, _hoisted_10)])
231
+ ])) : createCommentVNode("v-if", true),
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),
233
+ createCommentVNode(" Scrollable terms box when content is provided "),
234
+ currentConfig.value.content ? (openBlock(), createElementBlock("div", {
235
+ key: currentConfig.value.type,
236
+ ref: (el) => setScrollRef(el),
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",
238
+ "data-consent-type": currentConfig.value.type,
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",
242
+ innerHTML: renderMarkdown(currentConfig.value.content)
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", {
244
+ key: 0,
245
+ href: currentConfig.value.url,
246
+ target: "_blank",
247
+ rel: "noopener noreferrer",
248
+ class: "link link-accent"
249
+ }, " View " + toDisplayString(currentConfig.value.label), 9, _hoisted_14)) : createCommentVNode("v-if", true)])], 2112)),
250
+ !submitError.value ? (openBlock(), createElementBlock("div", _hoisted_15, [createElementVNode("button", {
251
+ type: "button",
252
+ class: "btn btn-primary",
253
+ disabled: (currentConfig.value.content ? !hasScrolledToBottom.value : false) || submitting.value,
254
+ onClick: handleAccept
255
+ }, toDisplayString(submitting.value ? "Submitting..." : "Accept and continue"), 9, _hoisted_16), createElementVNode("button", {
256
+ type: "button",
257
+ class: "btn btn-outline btn-sm btn-error",
258
+ disabled: declining.value || submitting.value,
259
+ onClick: handleDecline
260
+ }, toDisplayString(declining.value ? "Returning..." : "Decline"), 9, _hoisted_17)])) : createCommentVNode("v-if", true)
261
+ ])) : createCommentVNode("v-if", true)]);
262
+ };
263
+ }
264
+ });
265
+ var SignupConsentFlow_default = _sfc_main;
266
+
267
+ //#endregion
268
+ export { SignupConsentFlow_default as default };
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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6GA,MAAM,qBAAqB,OAA8B,+BAA+B,EAAE,EAAE,KAAK;EAEjG,MAAM,EAAE,KAAK,sBAAsB,OAAO,2BAA2B,sBAAsB;EAC3F,MAAM,eAAe,qBAAqB;EAC1C,MAAM,SAAS,WAAW;EAC1B,MAAM,QAAQ,UAAU;EACxB,MAAM,EAAE,0BAA0B,QAAQ;EAE1C,MAAM,YAAY,eAAe,MAAM,MAAM,UAAgC;EAE7E,MAAM,aAAa,eAAe,sBAAsB,CAAC;EAEzD,MAAM,cAAc,IAAI,EAAE;EAC1B,MAAM,aAAa,eAAe,oBAAoB,UAAU,EAAE;EAClE,MAAM,gBAAgB,eACd,qBAAqB,YAAY,QAAQ,MAAM,KACtD;EAED,MAAM,sBAAsB,IAAI,MAAM;EACtC,MAAM,WAAW,IAAwB,KAAK;EAE9C,SAAS,aAAa,IAAa;AACjC,YAAS,QAAQ,cAAc,cAAc,KAAK;;AAGpD,cACQ,cAAc,QACnB,WAAW;AACV,uBAAoB,QAAQ,CAAC,QAAQ;AACrC,kBAAe;AACb,aAAS,OAAO,SAAS,GAAG,EAAE;KAC9B;KAEJ,EAAE,WAAW,MAAM,CACpB;EAED,SAAS,eAAe,SAAyB;GAC/C,MAAM,OAAO,OAAO,MAAM,QAAQ;AAClC,UAAO,UAAU,SAAS,MAAM;IAC9B,cAAc;KAAC;KAAK;KAAM;KAAU;KAAM;KAAK;KAAK;KAAM;KAAM;KAAM;KAAM;KAAM;KAAM;KAAM;KAAc;KAAQ;KAAO;KAAK;IAChI,cAAc;KAAC;KAAQ;KAAU;KAAM;IACxC,CAAC;;EAGJ,SAAS,wBAAwB;GAC/B,MAAM,KAAK,SAAS;AACpB,OAAI,CAAC,GAAI;GACT,MAAM,EAAE,WAAW,cAAc,iBAAiB;AAElD,OADiB,eAAe,YAAY,eAAe,GAEzD,qBAAoB,QAAQ;;EAIhC,SAAS,WAAW;AAClB,0BAAuB;;AAGzB,WAAS,sBAAsB;EAE/B,MAAM,YAAY,IAAI,MAAM;EAC5B,MAAM,YAAY,IAAI,MAAM;EAC5B,MAAM,aAAa,IAAI,MAAM;EAC7B,MAAM,cAAc,IAAmB,KAAK;EAE5C,SAAS,gBAAgB,OAAwB;AAC/C,OAAI,iBAAiB,SAAS,MAAM,QAAS,QAAO,MAAM;AAC1D,OAAI,SAAS,OAAO,UAAU,YAAY,aAAa,SAAS,OAAQ,MAA+B,YAAY,SACjH,QAAQ,MAA8B;AAExC,UAAO;;EAGT,MAAM,EAAE,QAAQ,iBAAiB,aAC9B,KAAK,UAA0B,IAAI,MAAM,WAAW,MAAM,EAC3D,EAAE,eAAe,MAAM,CACxB;EACD,MAAM,EAAE,QAAQ,gBAAgB,aAC7B,KAAK,UAA+C,IAAI,aAAa,MAAM,MAAM,EAClF,EAAE,aAAa,WAAW,CAC3B;EAED,eAAe,eAAe;AAE5B,OAAI,CADW,cAAc,SACd,CAAC,WAAW,MAAO;AAElC,eAAY,QAAQ;GAEpB,MAAMA,mBAA4C,EAAE;AACpD,QAAK,IAAI,IAAI,GAAG,IAAI,YAAY,OAAO,KAAK;IAC1C,MAAM,IAAI,qBAAqB;AAC/B,QAAI,EAAG,kBAAiB,EAAE,QAAQ;;AAGpC,OAAI,YAAY,SAAS,WAAW,OAAO;AACzC,eAAW,QAAQ;AACnB,QAAI;AACF,WAAM,eAAe,iBAAiB;aAC/B,KAAK;AACZ,iBAAY,QAAQ,gBAAgB,IAAI;cAChC;AACR,gBAAW,QAAQ;;AAErB;;AAGF,eAAY;AACZ,uBAAoB,QAAQ,CAAC,cAAc,OAAO;AAClD,YAAS,sBAAsB;;EAGjC,eAAe,eAAe,aAAsC;GAClE,MAAM,OAAO,WAAW;AACxB,OAAI,CAAC,KAAM;AAQX,OAAI,CADW,MAAM,aALS;IAC5B,GAAG;IACH;IACD,CAEuC,CAC3B,OAAM,IAAI,MAAM,gBAAgB;AAE7C,2BAAwB;AAExB,OAAI,0BAA0B,YAAY;AAExC,QAAI;KACF,MAAM,gBAAc,MAAM,YAAY;MACpC,OAAO,KAAK;MACZ,UAAU,KAAK,UAAU;MAC1B,CAAC;AACF,SAAI,eAAa,gBAAgB,eAAa,oBAAoB;AAChE,mBAAa,WAAW,cAAY,mBAAmB;AACvD,mBAAa,eAAe,cAAY,aAAa;;YAEjD;AAGR,QAAI,0BAA0B,SAE5B,+BADkB,kBAAkB,OAAO,IAAI,CACP;AAE1C,WAAO,SAAS,GAAG,EAAE;IACrB,MAAM,aAAa,cAAc,sBAAsB,UAAU,MAAM;AACvE,UAAM,OAAO,KAAK,WAAW;AAC7B;;GAGF,MAAM,cAAc,MAAM,YAAY;IACpC,OAAO,KAAK;IACZ,UAAU,KAAK,UAAU;IAC1B,CAAC;AAEF,OAAI,CAAC,aAAa,gBAAgB,CAAC,aAAa,mBAC9C,OAAM,IAAI,MAAM,+BAA+B;AAGjD,gBAAa,WAAW,YAAY,mBAAmB;AACvD,gBAAa,eAAe,YAAY,aAAa;AAErD,UAAO,SAAS,GAAG,EAAE;GACrB,MAAM,kBAAkB,kBAAkB,OAAO,IAAI;AACrD,SAAM,OAAO,KAAK,gBAAgB;AAClC,SAAM,QAAQ,kDAAkD;;EAGlE,eAAe,gBAAgB;AAC7B,aAAU,QAAQ;AAClB,OAAI;AACF,4BAAwB;IACxB,MAAM,aAAa,cAAc,gBAAgB,UAAU,MAAM;AACjE,UAAM,OAAO,KAAK;KAAE,MAAM;KAAY,OAAO;MAAE,GAAG,MAAM;MAAO,UAAU;MAAK;KAAE,CAAC;aACzE;AACR,cAAU,QAAQ;;;EAItB,eAAe,iBAAiB;AAC9B,aAAU,QAAQ;AAClB,OAAI;AACF,4BAAwB;IACxB,MAAM,aAAa,cAAc,gBAAgB,UAAU,MAAM;IACjE,MAAM,EAAE,UAAU,IAAI,GAAG,SAAS,MAAM;AACxC,UAAM,OAAO,KAAK;KAAE,MAAM;KAAY,OAAO;KAAM,CAAC;aAC5C;AACR,cAAU,QAAQ;;;;uBAtSpB,mBAwFM,OAxFN,YAwFM,CAAA,CAvFQ,WAAA,SAAA,WAAA,EAAZ,mBAEM,OAFN,YAEM,CAAA,GAAA,OAAA,OAAA,OAAA,KAAA,CADJ,mBAA8C,KAAA,EAA3C,OAAM,wBAAsB,EAAC,cAAU,GAAA,CAAA,EAAA,CAAA,IAG5B,cAAA,SAAA,WAAA,EAAhB,mBAkFM,OAlFN,YAkFM;IAjFJ,mBAIM,OAJN,YAIM;KAHJ,mBAA6D,MAA7D,YAA6D,gBAA3B,cAAA,MAAc,MAAK,EAAA,EAAA;KACrD,mBAA8E,KAA9E,YAAgC,UAAK,gBAAG,YAAA,MAAW,GAAG,SAAI,gBAAG,WAAA,MAAU,EAAA,EAAA;+BACvE,mBAA6D,KAAA,EAA1D,OAAM,gCAA8B,EAAC,qBAAiB,GAAA;;IAGhD,YAAA,SAAA,WAAA,EAAX,mBAuBM,OAvBN,YAuBM;KAtBJ,mBAA8B,QAAA,MAAA,gBAArB,YAAA,MAAW,EAAA,EAAA;+BACpB,mBAEI,KAAA,EAFD,OAAM,sBAAoB,EAAC,kEAE9B,GAAA;KACA,mBAiBM,OAjBN,YAiBM,CAhBJ,mBAOS,UAAA;MANP,MAAK;MACL,OAAM;MACL,UAAU,UAAA,SAAa,WAAA;MACvB,SAAO;wBAEL,UAAA,QAAS,iBAAA,kBAAA,EAAA,GAAA,WAAA,EAEd,mBAOS,UAAA;MANP,MAAK;MACL,OAAM;MACL,UAAU,WAAA,SAAc,UAAA;MACxB,SAAO;wBAEL,WAAA,QAAU,kBAAA,YAAA,EAAA,GAAA,YAAA,CAAA,CAAA;;IAKV,cAAA,MAAc,WAAA,WAAA,EAAvB,mBAEI,KAFJ,aAA0E,qNAE1E,IAAA,mBAAA,QAAA,KAAA;IAEA,mBAAA,kDAAsD;IAE9C,cAAA,MAAc,WAAA,WAAA,EADtB,mBAYM,OAAA;KAVH,KAAK,cAAA,MAAc;KACnB,MAAM,OAAO,aAAa,GAAE;KAC7B,OAAM;KACL,qBAAmB,cAAA,MAAc;KACzB;QAET,mBAGE,OAAA;KAFA,OAAM;KACN,WAAQ,eAAe,cAAA,MAAc,QAAO;iEAKhD,mBAUM,UAAA,EAAA,KAAA,GAAA,EAAA,CAXN,mBAAA,8BAAkC,EAClC,mBAUM,OAAA,MAAA,CARI,cAAA,MAAc,OAAA,WAAA,EADtB,mBAQI,KAAA;;KAND,MAAM,cAAA,MAAc;KACrB,QAAO;KACP,KAAI;KACJ,OAAM;OACP,WACM,gBAAG,cAAA,MAAc,MAAK,EAAA,GAAA,YAAA,IAAA,mBAAA,QAAA,KAAA,CAAA,CAAA,CAAA;KAInB,YAAA,SAAA,WAAA,EAAZ,mBAiBM,OAjBN,aAiBM,CAhBJ,mBAOS,UAAA;KANP,MAAK;KACL,OAAM;KACL,WAAW,cAAA,MAAc,UAAO,CAAI,oBAAA,QAAmB,UAAa,WAAA;KACpE,SAAO;uBAEL,WAAA,QAAU,kBAAA,sBAAA,EAAA,GAAA,YAAA,EAEf,mBAOS,UAAA;KANP,MAAK;KACL,OAAM;KACL,UAAU,UAAA,SAAa,WAAA;KACvB,SAAO;uBAEL,UAAA,QAAS,iBAAA,UAAA,EAAA,GAAA,YAAA,CAAA,CAAA,IAAA,mBAAA,QAAA,KAAA"}
@@ -0,0 +1,360 @@
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
+ import { n as RecordVersionList_default, t as RecordVersionViewer_default } from "./RecordVersionViewer-BWZ78vvE.js";
6
+ import { r as formatToISODatetime } from "./convertToLocalDateTime-CFhtN6PI.js";
7
+ import { t as extractRpcErrorMessage } from "./extractRpcErrorMessage-Di8E8-Wh.js";
8
+ import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, openBlock, ref, renderList, toDisplayString, unref, withCtx } from "vue";
9
+ import { toast } from "vue3-toastify";
10
+ import { RecordConst, SignupConsentItemFormSchema } from "@dragonmastery/dragoncore-shared";
11
+ import { useForm, withMetadata } from "@dragonmastery/zinia-forms-core";
12
+ import { z } from "zod";
13
+
14
+ //#region src/slices/admin/features/signup_requirements/signupRequirementsFormMetadata.ts
15
+ /** Field metadata for consent item form — keys must match schema paths */
16
+ const consentItemFieldMetadata = {
17
+ type: {
18
+ label: "Type",
19
+ helpText: "Type (e.g. terms_of_service, privacy_policy)",
20
+ placeholder: "terms_of_service"
21
+ },
22
+ version: {
23
+ label: "Version",
24
+ helpText: "Version (e.g. 2025.1)",
25
+ placeholder: "2025.1"
26
+ },
27
+ label: {
28
+ label: "Label",
29
+ placeholder: "Terms of Service"
30
+ },
31
+ effective_at: {
32
+ label: "Effective at",
33
+ inputType: "datetime-local",
34
+ helpText: "When this version becomes enforceable for existing users. Set to now for immediate effect."
35
+ },
36
+ url: {
37
+ label: "URL",
38
+ helpText: "URL (link to document)",
39
+ placeholder: "https://example.com/terms"
40
+ },
41
+ required: {
42
+ label: "Required",
43
+ helpText: "User must accept to sign up",
44
+ inputType: "checkbox"
45
+ },
46
+ content: {
47
+ label: "Content",
48
+ helpText: "Optional, Markdown — when set, shown in scroll box; user must scroll to bottom",
49
+ placeholder: "# Terms of Service\n\nYour markdown content here...",
50
+ inputType: "textarea"
51
+ }
52
+ };
53
+ /** Item schema with metadata - used as array element (like followupCreateMetadata in tracker) */
54
+ const signupConsentItemFormMetadata = withMetadata(SignupConsentItemFormSchema, "signupConsentItemForm", consentItemFieldMetadata);
55
+ /** Full form schema with items array using metadata-wrapped item schema */
56
+ const signupRequirementsFormMetadata = withMetadata(z.object({ items: z.array(signupConsentItemFormMetadata).default([]) }), "signupRequirementsForm", {});
57
+ function createEmptyConsentItem() {
58
+ const now = /* @__PURE__ */ new Date();
59
+ const pad = (n) => String(n).padStart(2, "0");
60
+ return {
61
+ type: "",
62
+ required: true,
63
+ url: "",
64
+ label: "",
65
+ version: "1",
66
+ effective_at: `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())}T${pad(now.getHours())}:${pad(now.getMinutes())}`,
67
+ content: ""
68
+ };
69
+ }
70
+
71
+ //#endregion
72
+ //#region src/slices/admin/features/signup_requirements/SignupRequirementsPage.vue
73
+ const _hoisted_1 = { class: "mt-2" };
74
+ const _hoisted_2 = {
75
+ key: 0,
76
+ class: "flex justify-center py-8"
77
+ };
78
+ const _hoisted_3 = {
79
+ key: 1,
80
+ class: "space-y-6"
81
+ };
82
+ const _hoisted_4 = { class: "font-medium text-sm" };
83
+ const _hoisted_5 = {
84
+ key: 0,
85
+ class: "text-base-content/60"
86
+ };
87
+ const _hoisted_6 = { class: "space-y-3" };
88
+ const _hoisted_7 = { class: "grid grid-cols-1 md:grid-cols-3 gap-3" };
89
+ const _hoisted_8 = {
90
+ key: 0,
91
+ class: "alert alert-error mt-2"
92
+ };
93
+ const _hoisted_9 = { class: "mt-4 flex justify-end" };
94
+ const _hoisted_10 = { class: "card bg-base-200" };
95
+ const _hoisted_11 = { class: "card-body" };
96
+ const _hoisted_12 = { class: "modal-box max-w-4xl max-h-[90vh] overflow-auto" };
97
+ const _hoisted_13 = {
98
+ key: 0,
99
+ class: "space-y-4"
100
+ };
101
+ const _hoisted_14 = { key: 0 };
102
+ const _hoisted_15 = {
103
+ key: 1,
104
+ class: "text-xs bg-base-200 p-3 rounded overflow-auto max-h-96"
105
+ };
106
+ const VERSION_HISTORY_KEY = "admin-signup-requirements-history";
107
+ const _sfc_main = /* @__PURE__ */ defineComponent({
108
+ __name: "SignupRequirementsPage",
109
+ setup(__props) {
110
+ const { data: _signupRequirements, loading: isLoading, refetch } = useQuery((api) => api.appSettings.getSignupRequirements(), {});
111
+ const { form, zinia, ziniaGeneric, ZiniaForm, ZiniaSubmitButton } = useForm(signupRequirementsFormMetadata, {
112
+ storeName: "admin-signup-requirements-form",
113
+ persistToLocalStorage: false,
114
+ renderStyle: "daisy_ui",
115
+ fetchData: async () => {
116
+ while (isLoading.value) await new Promise((resolve) => setTimeout(resolve, 100));
117
+ return { items: _signupRequirements.value ?? [] };
118
+ }
119
+ });
120
+ const initialSnapshot = ref("");
121
+ const hasChanges = computed(() => {
122
+ const current = form.values?.items ?? [];
123
+ return JSON.stringify(current) !== initialSnapshot.value;
124
+ });
125
+ const { mutate: updateSignupRequirements } = useMutation((api, config) => api.appSettings.updateSignupRequirements(config), { invalidate: /admin-signup-requirements/ });
126
+ async function handleSubmit(formData) {
127
+ await updateSignupRequirements(formData.items.map((c) => ({
128
+ type: c.type.trim() || "unknown",
129
+ required: c.required,
130
+ url: c.url.trim(),
131
+ label: c.label.trim() || c.type.trim() || "Consent",
132
+ version: c.version.trim() || "1",
133
+ effective_at: (c.effective_at?.trim() ? formatToISODatetime(c.effective_at.trim()) : formatToISODatetime((/* @__PURE__ */ new Date()).toISOString())) ?? (/* @__PURE__ */ new Date()).toISOString(),
134
+ content: c.content?.trim() ? c.content.trim() : void 0
135
+ })));
136
+ }
137
+ async function handleSuccess() {
138
+ toast.success("Signup requirements saved");
139
+ initialSnapshot.value = JSON.stringify(form.values?.items ?? []);
140
+ await refetch();
141
+ await refetchVersionHistory();
142
+ }
143
+ function handleError(error) {
144
+ const message = error instanceof Error ? error.message : "An unknown error occurred";
145
+ form.setSubmitError(extractRpcErrorMessage(error, message));
146
+ toast.error(form.submitError ?? "Failed to save signup requirements");
147
+ }
148
+ const { data: versionHistoryData, loading: versionHistoryLoading, error: versionHistoryError, refetch: refetchVersionHistory } = useQuery(async (api) => api.recordVersions.listRecordVersionsPaginated("signup_requirements", RecordConst.APP_SETTING, {
149
+ first: 50,
150
+ sortBy: "recorded_at",
151
+ sortDirection: "desc"
152
+ }), {
153
+ cacheKey: VERSION_HISTORY_KEY,
154
+ staleTime: 60 * 1e3
155
+ });
156
+ const versionHistoryItems = computed(() => versionHistoryData.value?.items ?? []);
157
+ const versionHistoryPageInfo = computed(() => versionHistoryData.value?.pageInfo);
158
+ const versionHistoryLoadingMore = ref(false);
159
+ function loadMoreVersions() {}
160
+ const versionListConfig = {
161
+ recordDisplayName: "signup requirements",
162
+ noVersionsText: "No previous versions. Save changes to create the first version.",
163
+ viewAction: (version) => openVersionModal(version),
164
+ viewActionText: "View"
165
+ };
166
+ const versionModalRef = ref(null);
167
+ const selectedVersion = ref(null);
168
+ const selectedVersionRecordData = computed(() => {
169
+ if (!selectedVersion.value) return null;
170
+ const record = selectedVersion.value.record;
171
+ if (Array.isArray(record)) return { items: record };
172
+ if (typeof record === "object" && record !== null) return record;
173
+ if (typeof record === "string") try {
174
+ const parsed = JSON.parse(record);
175
+ return Array.isArray(parsed) ? { items: parsed } : parsed;
176
+ } catch {
177
+ return { raw: record };
178
+ }
179
+ return null;
180
+ });
181
+ const versionViewerConfig = {
182
+ recordDisplayName: "signup requirements",
183
+ title: "Signup Requirements Version",
184
+ onBack: () => closeVersionModal(),
185
+ excludeFields: ["raw"]
186
+ };
187
+ function openVersionModal(version) {
188
+ selectedVersion.value = version;
189
+ versionModalRef.value?.showModal();
190
+ }
191
+ function closeVersionModal() {
192
+ selectedVersion.value = null;
193
+ versionModalRef.value?.close();
194
+ }
195
+ return (_ctx, _cache) => {
196
+ return openBlock(), createElementBlock("div", _hoisted_1, [
197
+ _cache[10] || (_cache[10] = createElementVNode("div", { class: "flex justify-between items-center mb-4" }, [createElementVNode("h1", { class: "text-2xl font-bold" }, "Signup Requirements")], -1)),
198
+ _cache[11] || (_cache[11] = createElementVNode("p", { class: "text-base-content/70 mb-4" }, [
199
+ createTextVNode(" Configure consent checkboxes shown on signup and consent-required flows. Each item can be required or optional. When "),
200
+ createElementVNode("strong", null, "content"),
201
+ createTextVNode(" is provided, terms are shown in a scroll box (Markdown supported) and the user must scroll to bottom before accepting. When content is omitted, only a link is shown. ")
202
+ ], -1)),
203
+ unref(isLoading) ? (openBlock(), createElementBlock("div", _hoisted_2, [..._cache[0] || (_cache[0] = [createElementVNode("span", { class: "loading loading-spinner loading-lg" }, null, -1)])])) : (openBlock(), createElementBlock("div", _hoisted_3, [
204
+ createVNode(unref(ZiniaForm), {
205
+ onHandleSubmit: handleSubmit,
206
+ onSuccess: handleSuccess,
207
+ onError: handleError,
208
+ title: "",
209
+ subtitle: ""
210
+ }, {
211
+ default: withCtx(() => [
212
+ createVNode(unref(zinia).ItemsField, {
213
+ label: "Consent Items",
214
+ "create-item": unref(createEmptyConsentItem)
215
+ }, {
216
+ itemPreview: withCtx(({ item }) => [createElementVNode("div", _hoisted_4, [createTextVNode(toDisplayString(item.label || item.type || "Item") + " ", 1), item.type ? (openBlock(), createElementBlock("span", _hoisted_5, "(" + toDisplayString(item.type) + ")", 1)) : createCommentVNode("v-if", true)])]),
217
+ itemRenderer: withCtx(({ fields }) => [createElementVNode("div", _hoisted_6, [
218
+ createElementVNode("div", _hoisted_7, [
219
+ createVNode(unref(ziniaGeneric).TextField, {
220
+ name: fields.type,
221
+ label: unref(consentItemFieldMetadata).type.label,
222
+ placeholder: unref(consentItemFieldMetadata).type.placeholder,
223
+ required: ""
224
+ }, null, 8, [
225
+ "name",
226
+ "label",
227
+ "placeholder"
228
+ ]),
229
+ createVNode(unref(ziniaGeneric).TextField, {
230
+ name: fields.version,
231
+ label: unref(consentItemFieldMetadata).version.label,
232
+ placeholder: unref(consentItemFieldMetadata).version.placeholder,
233
+ required: ""
234
+ }, null, 8, [
235
+ "name",
236
+ "label",
237
+ "placeholder"
238
+ ]),
239
+ createVNode(unref(ziniaGeneric).TextField, {
240
+ name: fields.label,
241
+ label: unref(consentItemFieldMetadata).label.label,
242
+ placeholder: unref(consentItemFieldMetadata).label.placeholder,
243
+ required: ""
244
+ }, null, 8, [
245
+ "name",
246
+ "label",
247
+ "placeholder"
248
+ ])
249
+ ]),
250
+ createVNode(unref(ziniaGeneric).DateField, {
251
+ name: fields.effective_at,
252
+ label: unref(consentItemFieldMetadata).effective_at.label,
253
+ formatter: unref(formatToISODatetime),
254
+ required: ""
255
+ }, null, 8, [
256
+ "name",
257
+ "label",
258
+ "formatter"
259
+ ]),
260
+ createVNode(unref(ziniaGeneric).TextField, {
261
+ name: fields.url,
262
+ label: unref(consentItemFieldMetadata).url.label,
263
+ placeholder: unref(consentItemFieldMetadata).url.placeholder,
264
+ type: "url"
265
+ }, null, 8, [
266
+ "name",
267
+ "label",
268
+ "placeholder"
269
+ ]),
270
+ createVNode(unref(ziniaGeneric).CheckboxField, {
271
+ name: fields.required,
272
+ label: unref(consentItemFieldMetadata).required.label
273
+ }, null, 8, ["name", "label"]),
274
+ createVNode(unref(ziniaGeneric).TextareaField, {
275
+ name: fields.content,
276
+ label: unref(consentItemFieldMetadata).content.label,
277
+ placeholder: unref(consentItemFieldMetadata).content.placeholder,
278
+ rows: 5,
279
+ class: "font-mono text-sm"
280
+ }, null, 8, [
281
+ "name",
282
+ "label",
283
+ "placeholder"
284
+ ])
285
+ ])]),
286
+ _: 1
287
+ }, 8, ["create-item"]),
288
+ unref(form).submitError ? (openBlock(), createElementBlock("div", _hoisted_8, [createElementVNode("span", null, toDisplayString(unref(form).submitError), 1)])) : createCommentVNode("v-if", true),
289
+ createElementVNode("div", _hoisted_9, [createVNode(unref(ZiniaSubmitButton), {
290
+ submitText: "Save",
291
+ submittingText: "Saving...",
292
+ disabled: !hasChanges.value
293
+ }, null, 8, ["disabled"])])
294
+ ]),
295
+ _: 1
296
+ }),
297
+ createCommentVNode(" Version History "),
298
+ createElementVNode("div", _hoisted_10, [createElementVNode("div", _hoisted_11, [
299
+ _cache[8] || (_cache[8] = createElementVNode("h2", { class: "card-title text-lg" }, "Version History", -1)),
300
+ _cache[9] || (_cache[9] = createElementVNode("p", { class: "text-sm text-base-content/70" }, " Past changes to signup requirements. Each save creates a new version. ", -1)),
301
+ createVNode(RecordVersionList_default, {
302
+ versions: versionHistoryItems.value,
303
+ loading: unref(versionHistoryLoading),
304
+ error: unref(versionHistoryError),
305
+ "has-next-page": versionHistoryPageInfo.value?.hasNextPage ?? false,
306
+ "loading-more": versionHistoryLoadingMore.value,
307
+ config: versionListConfig,
308
+ "exclude-latest": "",
309
+ onRetry: unref(refetchVersionHistory),
310
+ onLoadMore: loadMoreVersions
311
+ }, null, 8, [
312
+ "versions",
313
+ "loading",
314
+ "error",
315
+ "has-next-page",
316
+ "loading-more",
317
+ "onRetry"
318
+ ]),
319
+ createElementVNode("dialog", {
320
+ ref_key: "versionModalRef",
321
+ ref: versionModalRef,
322
+ class: "modal"
323
+ }, [createElementVNode("div", _hoisted_12, [selectedVersion.value ? (openBlock(), createBlock(RecordVersionViewer_default, {
324
+ key: 0,
325
+ version: selectedVersion.value,
326
+ "record-data": selectedVersionRecordData.value,
327
+ config: versionViewerConfig
328
+ }, {
329
+ content: withCtx(({ recordData }) => [recordData?.items?.length ? (openBlock(), createElementBlock("div", _hoisted_13, [_cache[7] || (_cache[7] = createElementVNode("h3", { class: "font-semibold" }, "Consent items at this version", -1)), (openBlock(true), createElementBlock(Fragment, null, renderList(recordData.items, (item, idx) => {
330
+ return openBlock(), createElementBlock("div", {
331
+ key: idx,
332
+ class: "border border-base-300 rounded p-3 text-sm space-y-1"
333
+ }, [
334
+ createElementVNode("div", null, [_cache[1] || (_cache[1] = createElementVNode("strong", null, "Type:", -1)), createTextVNode(" " + toDisplayString(item.type), 1)]),
335
+ createElementVNode("div", null, [_cache[2] || (_cache[2] = createElementVNode("strong", null, "Version:", -1)), createTextVNode(" " + toDisplayString(item.version), 1)]),
336
+ createElementVNode("div", null, [_cache[3] || (_cache[3] = createElementVNode("strong", null, "Label:", -1)), createTextVNode(" " + toDisplayString(item.label), 1)]),
337
+ createElementVNode("div", null, [_cache[4] || (_cache[4] = createElementVNode("strong", null, "Effective at:", -1)), createTextVNode(" " + toDisplayString(item.effective_at), 1)]),
338
+ createElementVNode("div", null, [_cache[5] || (_cache[5] = createElementVNode("strong", null, "Required:", -1)), createTextVNode(" " + toDisplayString(item.required ? "Yes" : "No"), 1)]),
339
+ item.url ? (openBlock(), createElementBlock("div", _hoisted_14, [_cache[6] || (_cache[6] = createElementVNode("strong", null, "URL:", -1)), createTextVNode(" " + toDisplayString(item.url), 1)])) : createCommentVNode("v-if", true)
340
+ ]);
341
+ }), 128))])) : (openBlock(), createElementBlock("pre", _hoisted_15, toDisplayString(JSON.stringify(recordData, null, 2)), 1))]),
342
+ _: 1
343
+ }, 8, ["version", "record-data"])) : createCommentVNode("v-if", true)]), createElementVNode("form", {
344
+ method: "dialog",
345
+ class: "modal-backdrop"
346
+ }, [createElementVNode("button", {
347
+ type: "button",
348
+ onClick: closeVersionModal
349
+ }, "close")])], 512)
350
+ ])])
351
+ ]))
352
+ ]);
353
+ };
354
+ }
355
+ });
356
+ var SignupRequirementsPage_default = _sfc_main;
357
+
358
+ //#endregion
359
+ export { SignupRequirementsPage_default as default };
360
+ //# sourceMappingURL=SignupRequirementsPage-DfbYmpQD.js.map