@dragonmastery/dragoncore-vue 0.0.18 → 0.0.19

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 (162) hide show
  1. package/dist/ChangePasswordPage-BuVNYC_G.js +6 -0
  2. package/dist/{ChangePasswordPage-D2Ci00Sh.js → ChangePasswordPage-DXzU3NI9.js} +2 -2
  3. package/dist/{ChangePasswordPage-D2Ci00Sh.js.map → ChangePasswordPage-DXzU3NI9.js.map} +1 -1
  4. package/dist/CreateTeamForm-BuMrZ169.js +32 -0
  5. package/dist/CreateTeamMemberForm-D0xqR9me.js +32 -0
  6. package/dist/CreateUserPage-BWIvFF-4.js +6 -0
  7. package/dist/{CreateUserPage-DbT_l32W.js → CreateUserPage-bwR6fq5C.js} +2 -2
  8. package/dist/{CreateUserPage-DbT_l32W.js.map → CreateUserPage-bwR6fq5C.js.map} +1 -1
  9. package/dist/CreditBalanceDashboard-BR-er7gs.js +32 -0
  10. package/dist/CreditManagement-CyjrE1ep.js +32 -0
  11. package/dist/CustomerCreateSupportTicketForm-C9-CLRRQ.js +32 -0
  12. package/dist/{CustomerSupportTicketDetailPage-CthS9akm.js → CustomerSupportTicketDetailPage-D_1t2EpN.js} +9 -9
  13. package/dist/{CustomerSupportTicketDetailPage-CthS9akm.js.map → CustomerSupportTicketDetailPage-D_1t2EpN.js.map} +1 -1
  14. package/dist/CustomerSupportTicketList-B0dC7lgD.js +32 -0
  15. package/dist/{CustomerSupportTicketParent-iBV1KRKL.js → CustomerSupportTicketParent-B09_iFpJ.js} +4 -4
  16. package/dist/{CustomerSupportTicketParent-iBV1KRKL.js.map → CustomerSupportTicketParent-B09_iFpJ.js.map} +1 -1
  17. package/dist/CustomerSupportTicketParent-D0wLnKXf.js +7 -0
  18. package/dist/CustomerSupportTicketSuccess-BvuBglg8.js +32 -0
  19. package/dist/EditTeamForm-BJlOKEkI.js +32 -0
  20. package/dist/EditTeamMemberForm-CbDvTLXI.js +6 -0
  21. package/dist/{EditTeamMemberForm-Cy8nzoUb.js → EditTeamMemberForm-DJW7yRQW.js} +2 -2
  22. package/dist/{EditTeamMemberForm-Cy8nzoUb.js.map → EditTeamMemberForm-DJW7yRQW.js.map} +1 -1
  23. package/dist/EditUserPage-CsHl1h_g.js +7 -0
  24. package/dist/{EditUserPage-CIRqNko-.js → EditUserPage-aDygGmfD.js} +4 -4
  25. package/dist/{EditUserPage-CIRqNko-.js.map → EditUserPage-aDygGmfD.js.map} +1 -1
  26. package/dist/{ForgotPassword-CJg_buPl.js → ForgotPassword-CJjzm9GK.js} +3 -4
  27. package/dist/{ForgotPassword-CJg_buPl.js.map → ForgotPassword-CJjzm9GK.js.map} +1 -1
  28. package/dist/ForgotPassword-DJjmzU_m.js +7 -0
  29. package/dist/LoginForm-BeiI_y3E.js +7 -0
  30. package/dist/{LoginForm-DyHmiC1I.js → LoginForm-IEP-hEh0.js} +4 -5
  31. package/dist/{LoginForm-DyHmiC1I.js.map → LoginForm-IEP-hEh0.js.map} +1 -1
  32. package/dist/Logout-Cm9kEzgH.js +70 -0
  33. package/dist/Logout-Cm9kEzgH.js.map +1 -0
  34. package/dist/Logout-DmZTNQDP.js +7 -0
  35. package/dist/MfaSetup-BwkenBRD.js +8 -0
  36. package/dist/{MfaSetup-D80HhwEz.js → MfaSetup-Ch0w-gTN.js} +4 -5
  37. package/dist/{MfaSetup-D80HhwEz.js.map → MfaSetup-Ch0w-gTN.js.map} +1 -1
  38. package/dist/MfaVerify-BaUROEol.js +8 -0
  39. package/dist/{MfaVerify-BEd-f6oV.js → MfaVerify-BwzjVrTj.js} +5 -6
  40. package/dist/{MfaVerify-BEd-f6oV.js.map → MfaVerify-BwzjVrTj.js.map} +1 -1
  41. package/dist/ResetPassword-DEFj1pgV.js +7 -0
  42. package/dist/{ResetPassword-4HLdgM7s.js → ResetPassword-DuLuXaNp.js} +3 -4
  43. package/dist/{ResetPassword-4HLdgM7s.js.map → ResetPassword-DuLuXaNp.js.map} +1 -1
  44. package/dist/{SavedFiltersPage-p0qGRIuN.js → SavedFiltersPage-CawED9Oz.js} +29 -29
  45. package/dist/{SavedFiltersPage-p0qGRIuN.js.map → SavedFiltersPage-CawED9Oz.js.map} +1 -1
  46. package/dist/{Signup-Ct0m0x78.js → Signup-C94alv87.js} +41 -12
  47. package/dist/Signup-C94alv87.js.map +1 -0
  48. package/dist/Signup-CFUbdrYs.js +7 -0
  49. package/dist/StaffCreateSupportTicketForm-AxprwWRv.js +32 -0
  50. package/dist/{StaffSupportTicketDetailPage-TaAPQARa.js → StaffSupportTicketDetailPage-DZZN3jmt.js} +11 -11
  51. package/dist/{StaffSupportTicketDetailPage-TaAPQARa.js.map → StaffSupportTicketDetailPage-DZZN3jmt.js.map} +1 -1
  52. package/dist/StaffSupportTicketList-DYKysNs3.js +32 -0
  53. package/dist/{StaffSupportTicketParent-KYzy4eb4.js → StaffSupportTicketParent-BYxQPuhI.js} +4 -4
  54. package/dist/{StaffSupportTicketParent-KYzy4eb4.js.map → StaffSupportTicketParent-BYxQPuhI.js.map} +1 -1
  55. package/dist/StaffSupportTicketParent-CT8oYFd6.js +7 -0
  56. package/dist/StaffSupportTicketSuccess-zWEagE4E.js +32 -0
  57. package/dist/{SupportStaffPage-D_YsHZZa.js → SupportStaffPage-B05UR5LK.js} +7 -7
  58. package/dist/{SupportStaffPage-D_YsHZZa.js.map → SupportStaffPage-B05UR5LK.js.map} +1 -1
  59. package/dist/{SupportTicketDevLifecycleBadge-B2NysMAj.js → SupportTicketDevLifecycleBadge-Ba-Rm6QW.js} +1 -1
  60. package/dist/{SupportTicketDevLifecycleBadge-B2NysMAj.js.map → SupportTicketDevLifecycleBadge-Ba-Rm6QW.js.map} +1 -1
  61. package/dist/{SupportTicketMaintenancePage-CpK1esq2.js → SupportTicketMaintenancePage-BoZpjcAF.js} +4 -4
  62. package/dist/{SupportTicketMaintenancePage-CpK1esq2.js.map → SupportTicketMaintenancePage-BoZpjcAF.js.map} +1 -1
  63. package/dist/TeamAttachmentsTab-BFRMbPlZ.js +32 -0
  64. package/dist/{TeamHistoryTab-BQ-eXtiw.js → TeamHistoryTab-BrC6FFIw.js} +3 -3
  65. package/dist/{TeamHistoryTab-BQ-eXtiw.js.map → TeamHistoryTab-BrC6FFIw.js.map} +1 -1
  66. package/dist/TeamHistoryTab-CYrt5KnE.js +4 -0
  67. package/dist/TeamList-CF5BQhfx.js +32 -0
  68. package/dist/TeamMemberList-Dfi2iKOH.js +32 -0
  69. package/dist/TeamMemberParent-DXcumR-Q.js +32 -0
  70. package/dist/{TeamNotesTab-Dj12Q2gD.js → TeamNotesTab-B2eETkAz.js} +5 -5
  71. package/dist/{TeamNotesTab-Dj12Q2gD.js.map → TeamNotesTab-B2eETkAz.js.map} +1 -1
  72. package/dist/TeamNotesTab-Bv_HPC6f.js +7 -0
  73. package/dist/TeamParent-DLoNn-mW.js +32 -0
  74. package/dist/{TimelineNoteInput-DGDgyGe-.js → TimelineNoteInput-C0a0WRQC.js} +2 -2
  75. package/dist/{TimelineNoteInput-DGDgyGe-.js.map → TimelineNoteInput-C0a0WRQC.js.map} +1 -1
  76. package/dist/{TimelineSystemEvent-CBwUl5G8.js → TimelineSystemEvent-Dj2TMOF6.js} +4 -4
  77. package/dist/{TimelineSystemEvent-CBwUl5G8.js.map → TimelineSystemEvent-Dj2TMOF6.js.map} +1 -1
  78. package/dist/UserListPage-CBwfXo15.js +4 -0
  79. package/dist/{UserListPage-D-IdlsHK.js → UserListPage-QSdxrJT6.js} +3 -3
  80. package/dist/{UserListPage-D-IdlsHK.js.map → UserListPage-QSdxrJT6.js.map} +1 -1
  81. package/dist/{UserProfilePage-DMwDVgXa.js → UserProfilePage-X4z2lG-J.js} +4 -4
  82. package/dist/{UserProfilePage-DMwDVgXa.js.map → UserProfilePage-X4z2lG-J.js.map} +1 -1
  83. package/dist/UserProfilePage-cTrZuwOT.js +7 -0
  84. package/dist/{VerifyEmail-CHfTzrHg.js → VerifyEmail-8bsvoDdM.js} +57 -22
  85. package/dist/VerifyEmail-8bsvoDdM.js.map +1 -0
  86. package/dist/VerifyEmail-Cpc0umIu.js +7 -0
  87. package/dist/{VerifyEmailRequired-BCKREd_C.js → VerifyEmailRequired-CN1FU1AE.js} +6 -7
  88. package/dist/{VerifyEmailRequired-BCKREd_C.js.map → VerifyEmailRequired-CN1FU1AE.js.map} +1 -1
  89. package/dist/ViewTeam-DpjnoTwo.js +32 -0
  90. package/dist/ViewTeamMember-CRb2oBHG.js +32 -0
  91. package/dist/{convertToLocalDateTime-mKs5eC9T.js → convertToLocalDateTime-DOSGtMn8.js} +1 -1
  92. package/dist/{convertToLocalDateTime-mKs5eC9T.js.map → convertToLocalDateTime-DOSGtMn8.js.map} +1 -1
  93. package/dist/{displayIdFormatter-rSbbsHIX.js → displayIdFormatter-B1ZKgofu.js} +1 -1
  94. package/dist/{displayIdFormatter-rSbbsHIX.js.map → displayIdFormatter-B1ZKgofu.js.map} +1 -1
  95. package/dist/{extractRpcErrorMessage-pP3v8kKE.js → extractRpcErrorMessage-C_UbKgHL.js} +1 -1
  96. package/dist/{extractRpcErrorMessage-pP3v8kKE.js.map → extractRpcErrorMessage-C_UbKgHL.js.map} +1 -1
  97. package/dist/index.d.ts +785 -776
  98. package/dist/index.js +31 -32
  99. package/dist/{mfaSchema-_vbG9jiT.js → mfaSchema-nfNCcEhM.js} +1 -1
  100. package/dist/{mfaSchema-_vbG9jiT.js.map → mfaSchema-nfNCcEhM.js.map} +1 -1
  101. package/dist/{src-B5eswi_J.js → src-CkgUIye9.js} +66 -60
  102. package/dist/src-CkgUIye9.js.map +1 -0
  103. package/dist/{useBreadcrumbs-B-W-miq6.js → useBreadcrumbs-DmgSucoe.js} +1 -1
  104. package/dist/{useBreadcrumbs-B-W-miq6.js.map → useBreadcrumbs-DmgSucoe.js.map} +1 -1
  105. package/dist/{useMutation-DzRSXPB1.js → useMutation-DbzXtqf1.js} +3 -3
  106. package/dist/{useMutation-DzRSXPB1.js.map → useMutation-DbzXtqf1.js.map} +1 -1
  107. package/dist/{useQuery-bvJabe9Q.js → useQuery-BKb5JXVS.js} +3 -3
  108. package/dist/{useQuery-bvJabe9Q.js.map → useQuery-BKb5JXVS.js.map} +1 -1
  109. package/dist/{useQueryCache-DIGf3fCM.js → useQueryCache-CHG4-HGF.js} +2 -2
  110. package/dist/{useQueryCache-DIGf3fCM.js.map → useQueryCache-CHG4-HGF.js.map} +1 -1
  111. package/dist/useReturnUrl-Da8PpLb9.js +118 -0
  112. package/dist/useReturnUrl-Da8PpLb9.js.map +1 -0
  113. package/dist/{useRpcAuth-SgNzCAPa.js → useRpcAuth-8Byr6SSI.js} +21 -9
  114. package/dist/{useRpcAuth-SgNzCAPa.js.map → useRpcAuth-8Byr6SSI.js.map} +1 -1
  115. package/package.json +2 -2
  116. package/dist/AppLink-CHMMrSFI.js +0 -54
  117. package/dist/AppLink-CHMMrSFI.js.map +0 -1
  118. package/dist/ChangePasswordPage-DqnWhaUa.js +0 -6
  119. package/dist/CreateTeamForm-LadKAxsM.js +0 -32
  120. package/dist/CreateTeamMemberForm-eWL__TEt.js +0 -32
  121. package/dist/CreateUserPage-cduuWl9g.js +0 -6
  122. package/dist/CreditBalanceDashboard-CgRRO6MD.js +0 -32
  123. package/dist/CreditManagement-BBb_Xumq.js +0 -32
  124. package/dist/CustomerCreateSupportTicketForm-yfyeXr0V.js +0 -32
  125. package/dist/CustomerSupportTicketList-Zzsg1FtO.js +0 -32
  126. package/dist/CustomerSupportTicketParent-CqR8lF7r.js +0 -7
  127. package/dist/CustomerSupportTicketSuccess-BPyydSLQ.js +0 -32
  128. package/dist/EditTeamForm-D0wZKYm2.js +0 -32
  129. package/dist/EditTeamMemberForm-JuRGiWOn.js +0 -6
  130. package/dist/EditUserPage-Dl6d3Cuh.js +0 -7
  131. package/dist/ForgotPassword-rSN-8EC4.js +0 -7
  132. package/dist/LoginForm-YCzdrekw.js +0 -7
  133. package/dist/Logout-C6pWyTIm.js +0 -41
  134. package/dist/Logout-C6pWyTIm.js.map +0 -1
  135. package/dist/Logout-Ctc8b-B0.js +0 -6
  136. package/dist/MfaSetup-xNmNjSh1.js +0 -8
  137. package/dist/MfaVerify-C0COXH_W.js +0 -8
  138. package/dist/ResetPassword-BCzMTXpT.js +0 -7
  139. package/dist/Signup-Ct0m0x78.js.map +0 -1
  140. package/dist/Signup-DNEklGpK.js +0 -7
  141. package/dist/StaffCreateSupportTicketForm-CxpKnqCq.js +0 -32
  142. package/dist/StaffSupportTicketList-BuKBTk2v.js +0 -32
  143. package/dist/StaffSupportTicketParent-Lkn-5u7C.js +0 -7
  144. package/dist/StaffSupportTicketSuccess-BD1Xsnx1.js +0 -32
  145. package/dist/TeamAttachmentsTab-DA_MBYj8.js +0 -32
  146. package/dist/TeamHistoryTab-lz2ouNyP.js +0 -4
  147. package/dist/TeamList-T3mZJTzq.js +0 -32
  148. package/dist/TeamMemberList-BW4qqzC1.js +0 -32
  149. package/dist/TeamMemberParent-Wcht0pIz.js +0 -32
  150. package/dist/TeamNotesTab-aGD8O49y.js +0 -7
  151. package/dist/TeamParent-BkhaJwud.js +0 -32
  152. package/dist/UserListPage-C9zUjaOK.js +0 -4
  153. package/dist/UserProfilePage-D52_Q5yf.js +0 -7
  154. package/dist/VerifyEmail-5thal4d_.js +0 -7
  155. package/dist/VerifyEmail-CHfTzrHg.js.map +0 -1
  156. package/dist/ViewTeam-g7WhYvsR.js +0 -32
  157. package/dist/ViewTeamMember-ByCSsl5k.js +0 -32
  158. package/dist/src-B5eswi_J.js.map +0 -1
  159. package/dist/useReturnUrl-BBoPnDR3.js +0 -51
  160. package/dist/useReturnUrl-BBoPnDR3.js.map +0 -1
  161. /package/dist/{Appearance-CohgRf-_.js → Appearance-C3WguxT-.js} +0 -0
  162. /package/dist/{TeamMembersTab-CpE9BaCi.js → TeamMembersTab-DTJxmb-M.js} +0 -0
@@ -0,0 +1,4 @@
1
+ import "./useRpcAuth-8Byr6SSI.js";
2
+ import { t as UserListPage_default } from "./UserListPage-QSdxrJT6.js";
3
+
4
+ export { UserListPage_default as default };
@@ -1,5 +1,5 @@
1
- import { r as executeWithAuth, s as getRefreshTokenHandler } from "./useRpcAuth-SgNzCAPa.js";
2
- import { t as formatSystemTimestamp } from "./convertToLocalDateTime-mKs5eC9T.js";
1
+ import { r as executeWithAuth, s as getRefreshTokenHandler } from "./useRpcAuth-8Byr6SSI.js";
2
+ import { t as formatSystemTimestamp } from "./convertToLocalDateTime-DOSGtMn8.js";
3
3
  import { computed, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, normalizeClass, openBlock, resolveComponent, toDisplayString, unref, withCtx } from "vue";
4
4
  import { UserReadSchema } from "@dragonmastery/dragoncore-shared";
5
5
  import { useCursorDataTable, withMetadata } from "@dragonmastery/zinia-forms-core";
@@ -150,4 +150,4 @@ var UserListPage_default = _sfc_main;
150
150
 
151
151
  //#endregion
152
152
  export { userRowSchemaWithMetadata as n, UserTypeBadge_default as r, UserListPage_default as t };
153
- //# sourceMappingURL=UserListPage-D-IdlsHK.js.map
153
+ //# sourceMappingURL=UserListPage-QSdxrJT6.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"UserListPage-D-IdlsHK.js","names":["mappedUsers: UserRow[]"],"sources":["../src/slices/admin/components/UserTypeBadge.vue","../src/slices/admin/features/user_management/userRowSchema.ts","../src/slices/admin/features/user_management/UserListPage.vue"],"sourcesContent":["<template>\n <span class=\"badge badge-sm\" :class=\"badgeClasses\">\n {{ typeLabel }}\n </span>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue';\n\ninterface Props {\n userType: 'consumer' | 'lead' | 'staff' | 'super_admin';\n size?: 'xs' | 'sm' | 'md' | 'lg';\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n size: 'sm',\n});\n\nconst typeConfig = {\n consumer: {\n label: 'Consumer',\n variant: 'neutral',\n },\n lead: {\n label: 'Lead',\n variant: 'info',\n },\n staff: {\n label: 'Staff',\n variant: 'warning',\n },\n super_admin: {\n label: 'Admin',\n variant: 'error',\n },\n};\n\nconst typeLabel = computed(() => {\n return typeConfig[props.userType]?.label || props.userType;\n});\n\nconst badgeClasses = computed(() => {\n const config = typeConfig[props.userType];\n const baseClasses = `badge-${props.size}`;\n\n if (!config) {\n return `${baseClasses} badge-neutral`;\n }\n\n return `${baseClasses} badge-${config.variant}`;\n});\n</script>\n","import { withMetadata } from '@dragonmastery/zinia-forms-core';\nimport { UserReadSchema } from '@dragonmastery/dragoncore-shared';\nimport type { z } from 'zod';\n\nexport const userRowSchemaWithMetadata = withMetadata(UserReadSchema, 'userRowSchema', {\n username: { label: 'Username' },\n email: { label: 'Email' },\n user_type: { label: 'Role' },\n email_verified: { label: 'Verified' },\n created_at: { label: 'Created' },\n});\n\nexport type UserRow = z.infer<typeof UserReadSchema>;\n","<template>\n <div class=\"mt-2\">\n <!-- Header with title and actions -->\n <div class=\"flex justify-between items-center mb-4\">\n <h1 class=\"text-2xl font-bold\">User Management</h1>\n </div>\n\n <!-- Zinia Data Table -->\n <ZiniaDataTable>\n <!-- Custom cell templates -->\n <template #cell-user_type=\"{ row }\">\n <UserTypeBadge :user-type=\"row.user_type\" />\n </template>\n\n <template #cell-email_verified=\"{ row }\">\n <span\n class=\"badge badge-sm\"\n :class=\"row.email_verified ? 'badge-success' : 'badge-error'\"\n >\n {{ row.email_verified ? 'Verified' : 'Not Verified' }}\n </span>\n </template>\n\n <template #cell-created_at=\"{ row }\">\n {{ formatSystemTimestamp(row.created_at) }}\n </template>\n\n <template #cell-actions=\"{ row }\">\n <router-link\n :to=\"{ name: 'EditUser', params: { id: row.id } }\"\n class=\"btn btn-sm btn-primary\"\n >\n Edit\n </router-link>\n </template>\n </ZiniaDataTable>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { executeWithAuth } from '../../../../composables/useRpcAuth';\nimport { getRefreshTokenHandler } from '../../../../utils/EnhancedRefreshTokenHandler';\nimport { formatSystemTimestamp } from '../../../../utils/convertToLocalDateTime';\nimport { useCursorDataTable } from '@dragonmastery/zinia-forms-core';\nimport UserTypeBadge from '../../components/UserTypeBadge.vue';\nimport { userRowSchemaWithMetadata, type UserRow } from './userRowSchema';\n\n// Set up data table\nconst { ZiniaDataTable } = useCursorDataTable(userRowSchemaWithMetadata, {\n fetchData: async () => {\n const users = await executeWithAuth(\n async (api) => {\n return await api.users.listUsers();\n },\n { refreshTokenHandler: getRefreshTokenHandler() },\n );\n\n // Map response to UserRow format\n const mappedUsers: UserRow[] = users.map((user) => ({\n id: user.id,\n username: user.username,\n email: user.email,\n email_verified: user.email_verified,\n user_type: user.user_type,\n created_at: user.created_at,\n updated_at: user.updated_at ?? null,\n }));\n\n return {\n data: mappedUsers,\n hasNextPage: false,\n hasPreviousPage: false,\n prevPageCursor: undefined,\n nextPageCursor: undefined,\n };\n },\n\n // Column configuration\n columns: {\n username: { label: 'Username', field: 'username', sortable: true },\n email: { label: 'Email', field: 'email', sortable: true },\n user_type: { label: 'Role', field: 'user_type', sortable: true },\n email_verified: {\n label: 'Verified',\n field: 'email_verified',\n sortable: true,\n },\n created_at: { label: 'Created', field: 'created_at', sortable: true },\n },\n\n // Action buttons\n actions: {\n items: [\n {\n key: 'edit',\n icon: 'edit',\n size: 'xs',\n variant: 'primary',\n type: 'link',\n href: (row: UserRow) => `/admin/users/${row.id}/edit`,\n },\n ],\n },\n\n pagination: {\n pageSize: 100,\n },\n});\n</script>\n"],"mappings":"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"}
1
+ {"version":3,"file":"UserListPage-QSdxrJT6.js","names":["mappedUsers: UserRow[]"],"sources":["../src/slices/admin/components/UserTypeBadge.vue","../src/slices/admin/features/user_management/userRowSchema.ts","../src/slices/admin/features/user_management/UserListPage.vue"],"sourcesContent":["<template>\n <span class=\"badge badge-sm\" :class=\"badgeClasses\">\n {{ typeLabel }}\n </span>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue';\n\ninterface Props {\n userType: 'consumer' | 'lead' | 'staff' | 'super_admin';\n size?: 'xs' | 'sm' | 'md' | 'lg';\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n size: 'sm',\n});\n\nconst typeConfig = {\n consumer: {\n label: 'Consumer',\n variant: 'neutral',\n },\n lead: {\n label: 'Lead',\n variant: 'info',\n },\n staff: {\n label: 'Staff',\n variant: 'warning',\n },\n super_admin: {\n label: 'Admin',\n variant: 'error',\n },\n};\n\nconst typeLabel = computed(() => {\n return typeConfig[props.userType]?.label || props.userType;\n});\n\nconst badgeClasses = computed(() => {\n const config = typeConfig[props.userType];\n const baseClasses = `badge-${props.size}`;\n\n if (!config) {\n return `${baseClasses} badge-neutral`;\n }\n\n return `${baseClasses} badge-${config.variant}`;\n});\n</script>\n","import { withMetadata } from '@dragonmastery/zinia-forms-core';\nimport { UserReadSchema } from '@dragonmastery/dragoncore-shared';\nimport type { z } from 'zod';\n\nexport const userRowSchemaWithMetadata = withMetadata(UserReadSchema, 'userRowSchema', {\n username: { label: 'Username' },\n email: { label: 'Email' },\n user_type: { label: 'Role' },\n email_verified: { label: 'Verified' },\n created_at: { label: 'Created' },\n});\n\nexport type UserRow = z.infer<typeof UserReadSchema>;\n","<template>\n <div class=\"mt-2\">\n <!-- Header with title and actions -->\n <div class=\"flex justify-between items-center mb-4\">\n <h1 class=\"text-2xl font-bold\">User Management</h1>\n </div>\n\n <!-- Zinia Data Table -->\n <ZiniaDataTable>\n <!-- Custom cell templates -->\n <template #cell-user_type=\"{ row }\">\n <UserTypeBadge :user-type=\"row.user_type\" />\n </template>\n\n <template #cell-email_verified=\"{ row }\">\n <span\n class=\"badge badge-sm\"\n :class=\"row.email_verified ? 'badge-success' : 'badge-error'\"\n >\n {{ row.email_verified ? 'Verified' : 'Not Verified' }}\n </span>\n </template>\n\n <template #cell-created_at=\"{ row }\">\n {{ formatSystemTimestamp(row.created_at) }}\n </template>\n\n <template #cell-actions=\"{ row }\">\n <router-link\n :to=\"{ name: 'EditUser', params: { id: row.id } }\"\n class=\"btn btn-sm btn-primary\"\n >\n Edit\n </router-link>\n </template>\n </ZiniaDataTable>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { executeWithAuth } from '../../../../composables/useRpcAuth';\nimport { getRefreshTokenHandler } from '../../../../utils/EnhancedRefreshTokenHandler';\nimport { formatSystemTimestamp } from '../../../../utils/convertToLocalDateTime';\nimport { useCursorDataTable } from '@dragonmastery/zinia-forms-core';\nimport UserTypeBadge from '../../components/UserTypeBadge.vue';\nimport { userRowSchemaWithMetadata, type UserRow } from './userRowSchema';\n\n// Set up data table\nconst { ZiniaDataTable } = useCursorDataTable(userRowSchemaWithMetadata, {\n fetchData: async () => {\n const users = await executeWithAuth(\n async (api) => {\n return await api.users.listUsers();\n },\n { refreshTokenHandler: getRefreshTokenHandler() },\n );\n\n // Map response to UserRow format\n const mappedUsers: UserRow[] = users.map((user) => ({\n id: user.id,\n username: user.username,\n email: user.email,\n email_verified: user.email_verified,\n user_type: user.user_type,\n created_at: user.created_at,\n updated_at: user.updated_at ?? null,\n }));\n\n return {\n data: mappedUsers,\n hasNextPage: false,\n hasPreviousPage: false,\n prevPageCursor: undefined,\n nextPageCursor: undefined,\n };\n },\n\n // Column configuration\n columns: {\n username: { label: 'Username', field: 'username', sortable: true },\n email: { label: 'Email', field: 'email', sortable: true },\n user_type: { label: 'Role', field: 'user_type', sortable: true },\n email_verified: {\n label: 'Verified',\n field: 'email_verified',\n sortable: true,\n },\n created_at: { label: 'Created', field: 'created_at', sortable: true },\n },\n\n // Action buttons\n actions: {\n items: [\n {\n key: 'edit',\n icon: 'edit',\n size: 'xs',\n variant: 'primary',\n type: 'link',\n href: (row: UserRow) => `/admin/users/${row.id}/edit`,\n },\n ],\n },\n\n pagination: {\n pageSize: 100,\n },\n});\n</script>\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
- import { l as useUserSessionStore, m as useEnv } from "./useRpcAuth-SgNzCAPa.js";
2
- import { t as useMutation } from "./useMutation-DzRSXPB1.js";
3
- import { t as useQuery } from "./useQuery-bvJabe9Q.js";
1
+ import { l as useUserSessionStore, m as useEnv } from "./useRpcAuth-8Byr6SSI.js";
2
+ import { t as useMutation } from "./useMutation-DbzXtqf1.js";
3
+ import { t as useQuery } from "./useQuery-BKb5JXVS.js";
4
4
  import { createCommentVNode, createElementBlock, createElementVNode, createVNode, defineComponent, normalizeClass, openBlock, ref, toDisplayString, unref, withCtx } from "vue";
5
5
  import { toast } from "vue3-toastify";
6
6
  import { UserProfileUpdateSchema } from "@dragonmastery/dragoncore-shared";
@@ -167,4 +167,4 @@ var UserProfilePage_default = _sfc_main;
167
167
 
168
168
  //#endregion
169
169
  export { userProfileSchemaWithMetadata as n, UserProfilePage_default as t };
170
- //# sourceMappingURL=UserProfilePage-DMwDVgXa.js.map
170
+ //# sourceMappingURL=UserProfilePage-X4z2lG-J.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"UserProfilePage-DMwDVgXa.js","names":[],"sources":["../src/slices/user/features/user_profile/userProfileSchema.ts","../src/slices/user/features/user_profile/UserProfilePage.vue"],"sourcesContent":["import { withMetadata } from '@dragonmastery/zinia-forms-core';\nimport { UserProfileBaseSchema, UserProfileUpdateSchema } from '@dragonmastery/dragoncore-shared';\nimport { z } from 'zod';\n\n// Define the login form type\nexport type UserProfileForm = z.infer<typeof UserProfileBaseSchema>;\n\n// Enhance the schema with metadata\nexport const userProfileSchemaWithMetadata = withMetadata(\n UserProfileUpdateSchema,\n 'userProfileSchema',\n {\n first_name: {\n inputType: 'text',\n placeholder: 'Enter first name',\n helpText: 'Enter the first name',\n autocomplete: 'first-name',\n autofocus: true,\n },\n\n last_name: {\n inputType: 'text',\n placeholder: 'Enter last name',\n helpText: 'Enter the last name',\n autocomplete: 'last-name',\n },\n\n bio: {\n inputType: 'textarea',\n placeholder: 'Enter bio',\n helpText: 'Enter a short bio',\n },\n },\n);\n","<template>\n <div v-if=\"form.isLoading\" class=\"flex justify-center items-center p-8\">\n <span class=\"loading loading-spinner loading-lg\"></span>\n </div>\n <div v-else-if=\"form.loadError\" class=\"alert alert-error mb-4\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n class=\"stroke-current shrink-0 h-6 w-6\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n >\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z\"\n />\n </svg>\n <span>{{ form.loadError }}</span>\n </div>\n <div v-else 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\">Update User Profile</h1>\n\n <!-- Email & verification status -->\n <div v-if=\"session.userSession?.user.email\" class=\"mb-6 p-4 rounded-lg bg-base-300\">\n <div class=\"flex items-center justify-between gap-2\">\n <div>\n <p class=\"text-sm text-base-content/70\">Email</p>\n <p class=\"font-medium\">{{ session.userSession.user.email }}</p>\n <p\n v-if=\"emailVerificationMode !== 'disabled'\"\n class=\"text-sm mt-1\"\n :class=\"session.userSession.user.email_verified ? 'text-success' : 'text-warning'\"\n >\n {{ session.userSession.user.email_verified ? 'Verified' : 'Not verified' }}\n </p>\n </div>\n <button\n v-if=\"\n emailVerificationMode !== 'disabled' &&\n !session.userSession.user.email_verified\n \"\n type=\"button\"\n class=\"btn btn-outline btn-sm\"\n :disabled=\"resendLoading\"\n @click=\"resendVerification\"\n >\n {{ resendLoading ? 'Sending...' : 'Resend verification' }}\n </button>\n </div>\n </div>\n\n <ZiniaForm @handle-submit=\"handleSubmit\" @success=\"handleSuccess\" @error=\"handleError\">\n <zinia.FirstNameField />\n <zinia.LastNameField />\n <zinia.BioField />\n\n <ZiniaSubmitButton submitText=\"Update\" submittingText=\"Updating...\" />\n </ZiniaForm>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport type { DragoncoreApi } from '@dragonmastery/dragoncore-shared';\nimport type { EmailVerificationApi } from '@dragonmastery/dragoncore-shared';\nimport type { UserProfileUpdateDto } from '@dragonmastery/dragoncore-shared';\nimport { useForm } from '@dragonmastery/zinia-forms-core';\nimport { ref } from 'vue';\nimport { toast } from 'vue3-toastify';\nimport { useEnv } from '../../../../composables/useEnv';\nimport { useMutation } from '../../../../composables/useMutation';\nimport { useQuery } from '../../../../composables/useQuery';\nimport { useUserSessionStore } from '../../../../composables/useUserSessionStore';\nimport { userProfileSchemaWithMetadata } from './userProfileSchema';\n\n//user session\nconst session = useUserSessionStore();\nconst { emailVerificationMode } = useEnv();\nconst resendLoading = ref(false);\n\nconst { mutate: resendMutate } = useMutation(\n (api, _input?: unknown) => {\n const verifyEmail = (api as DragoncoreApi).verifyEmail;\n if (!verifyEmail) throw new Error('Email verification is not configured');\n return (verifyEmail as EmailVerificationApi).resendVerificationEmail();\n },\n { skipAuthCheck: false },\n);\n\nconst resendVerification = async () => {\n try {\n resendLoading.value = true;\n const result = await resendMutate(undefined);\n if (result?.ok) {\n toast.success('Verification email sent. Please check your inbox.');\n await session.refreshToken();\n } else {\n toast.error('Failed to resend verification email.');\n }\n } catch (error) {\n toast.error(error instanceof Error ? error.message : 'Failed to resend');\n } finally {\n resendLoading.value = false;\n }\n};\n\n// fetch user profile data\nconst { data: userProfileData, loading: userProfileFetching } = useQuery(\n (api) => api.userProfiles.getCurrentUserProfile(),\n {\n enabled: !!session.userSession?.user.userId,\n staleTime: 5 * 60 * 1000,\n },\n);\n\n// Create a type-safe form using our schema with metadata\nconst { form, zinia, ZiniaForm, ZiniaSubmitButton } = useForm(userProfileSchemaWithMetadata, {\n storeName: 'user-profile-form',\n persistToLocalStorage: false,\n renderStyle: 'daisy_ui',\n fetchData: async () => {\n while (userProfileFetching.value) {\n await new Promise((resolve) => setTimeout(resolve, 100));\n }\n\n if (!userProfileData.value) {\n return {\n user_id: session.userSession?.user.userId || '',\n bio: '',\n first_name: '',\n last_name: '',\n };\n }\n\n return {\n user_id: userProfileData.value.user_id,\n bio: userProfileData.value.bio || '',\n first_name: userProfileData.value.first_name || '',\n last_name: userProfileData.value.last_name || '',\n };\n },\n});\n\nconst { mutate: updateUserProfile } = useMutation(\n (api, input: UserProfileUpdateDto) => api.userProfiles.updateUserProfile(input),\n { invalidate: /^user:profile/ },\n);\n\n// Handle form submission\nconst handleSubmit = async (data: UserProfileUpdateDto) => {\n if (!session.userSession?.user.userId) {\n throw new Error('User session not found');\n }\n\n const result = await updateUserProfile({\n user_id: session.userSession?.user.userId,\n first_name: data.first_name,\n last_name: data.last_name,\n bio: data.bio,\n });\n if (!result) throw new Error('Update user profile failed');\n\n return result;\n};\n\n// Handle success\nconst handleSuccess = (_data: any) => {\n toast.success('User profile updated successfully!');\n};\n\n// Handle error\nconst handleError = (error: any) => {\n toast.error(error.message || 'Update user profile failed');\n};\n</script>\n"],"mappings":"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"}
1
+ {"version":3,"file":"UserProfilePage-X4z2lG-J.js","names":[],"sources":["../src/slices/user/features/user_profile/userProfileSchema.ts","../src/slices/user/features/user_profile/UserProfilePage.vue"],"sourcesContent":["import { withMetadata } from '@dragonmastery/zinia-forms-core';\nimport { UserProfileBaseSchema, UserProfileUpdateSchema } from '@dragonmastery/dragoncore-shared';\nimport { z } from 'zod';\n\n// Define the login form type\nexport type UserProfileForm = z.infer<typeof UserProfileBaseSchema>;\n\n// Enhance the schema with metadata\nexport const userProfileSchemaWithMetadata = withMetadata(\n UserProfileUpdateSchema,\n 'userProfileSchema',\n {\n first_name: {\n inputType: 'text',\n placeholder: 'Enter first name',\n helpText: 'Enter the first name',\n autocomplete: 'first-name',\n autofocus: true,\n },\n\n last_name: {\n inputType: 'text',\n placeholder: 'Enter last name',\n helpText: 'Enter the last name',\n autocomplete: 'last-name',\n },\n\n bio: {\n inputType: 'textarea',\n placeholder: 'Enter bio',\n helpText: 'Enter a short bio',\n },\n },\n);\n","<template>\n <div v-if=\"form.isLoading\" class=\"flex justify-center items-center p-8\">\n <span class=\"loading loading-spinner loading-lg\"></span>\n </div>\n <div v-else-if=\"form.loadError\" class=\"alert alert-error mb-4\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n class=\"stroke-current shrink-0 h-6 w-6\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n >\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z\"\n />\n </svg>\n <span>{{ form.loadError }}</span>\n </div>\n <div v-else 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\">Update User Profile</h1>\n\n <!-- Email & verification status -->\n <div v-if=\"session.userSession?.user.email\" class=\"mb-6 p-4 rounded-lg bg-base-300\">\n <div class=\"flex items-center justify-between gap-2\">\n <div>\n <p class=\"text-sm text-base-content/70\">Email</p>\n <p class=\"font-medium\">{{ session.userSession.user.email }}</p>\n <p\n v-if=\"emailVerificationMode !== 'disabled'\"\n class=\"text-sm mt-1\"\n :class=\"session.userSession.user.email_verified ? 'text-success' : 'text-warning'\"\n >\n {{ session.userSession.user.email_verified ? 'Verified' : 'Not verified' }}\n </p>\n </div>\n <button\n v-if=\"\n emailVerificationMode !== 'disabled' &&\n !session.userSession.user.email_verified\n \"\n type=\"button\"\n class=\"btn btn-outline btn-sm\"\n :disabled=\"resendLoading\"\n @click=\"resendVerification\"\n >\n {{ resendLoading ? 'Sending...' : 'Resend verification' }}\n </button>\n </div>\n </div>\n\n <ZiniaForm @handle-submit=\"handleSubmit\" @success=\"handleSuccess\" @error=\"handleError\">\n <zinia.FirstNameField />\n <zinia.LastNameField />\n <zinia.BioField />\n\n <ZiniaSubmitButton submitText=\"Update\" submittingText=\"Updating...\" />\n </ZiniaForm>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport type { DragoncoreApi } from '@dragonmastery/dragoncore-shared';\nimport type { EmailVerificationApi } from '@dragonmastery/dragoncore-shared';\nimport type { UserProfileUpdateDto } from '@dragonmastery/dragoncore-shared';\nimport { useForm } from '@dragonmastery/zinia-forms-core';\nimport { ref } from 'vue';\nimport { toast } from 'vue3-toastify';\nimport { useEnv } from '../../../../composables/useEnv';\nimport { useMutation } from '../../../../composables/useMutation';\nimport { useQuery } from '../../../../composables/useQuery';\nimport { useUserSessionStore } from '../../../../composables/useUserSessionStore';\nimport { userProfileSchemaWithMetadata } from './userProfileSchema';\n\n//user session\nconst session = useUserSessionStore();\nconst { emailVerificationMode } = useEnv();\nconst resendLoading = ref(false);\n\nconst { mutate: resendMutate } = useMutation(\n (api, _input?: unknown) => {\n const verifyEmail = (api as DragoncoreApi).verifyEmail;\n if (!verifyEmail) throw new Error('Email verification is not configured');\n return (verifyEmail as EmailVerificationApi).resendVerificationEmail();\n },\n { skipAuthCheck: false },\n);\n\nconst resendVerification = async () => {\n try {\n resendLoading.value = true;\n const result = await resendMutate(undefined);\n if (result?.ok) {\n toast.success('Verification email sent. Please check your inbox.');\n await session.refreshToken();\n } else {\n toast.error('Failed to resend verification email.');\n }\n } catch (error) {\n toast.error(error instanceof Error ? error.message : 'Failed to resend');\n } finally {\n resendLoading.value = false;\n }\n};\n\n// fetch user profile data\nconst { data: userProfileData, loading: userProfileFetching } = useQuery(\n (api) => api.userProfiles.getCurrentUserProfile(),\n {\n enabled: !!session.userSession?.user.userId,\n staleTime: 5 * 60 * 1000,\n },\n);\n\n// Create a type-safe form using our schema with metadata\nconst { form, zinia, ZiniaForm, ZiniaSubmitButton } = useForm(userProfileSchemaWithMetadata, {\n storeName: 'user-profile-form',\n persistToLocalStorage: false,\n renderStyle: 'daisy_ui',\n fetchData: async () => {\n while (userProfileFetching.value) {\n await new Promise((resolve) => setTimeout(resolve, 100));\n }\n\n if (!userProfileData.value) {\n return {\n user_id: session.userSession?.user.userId || '',\n bio: '',\n first_name: '',\n last_name: '',\n };\n }\n\n return {\n user_id: userProfileData.value.user_id,\n bio: userProfileData.value.bio || '',\n first_name: userProfileData.value.first_name || '',\n last_name: userProfileData.value.last_name || '',\n };\n },\n});\n\nconst { mutate: updateUserProfile } = useMutation(\n (api, input: UserProfileUpdateDto) => api.userProfiles.updateUserProfile(input),\n { invalidate: /^user:profile/ },\n);\n\n// Handle form submission\nconst handleSubmit = async (data: UserProfileUpdateDto) => {\n if (!session.userSession?.user.userId) {\n throw new Error('User session not found');\n }\n\n const result = await updateUserProfile({\n user_id: session.userSession?.user.userId,\n first_name: data.first_name,\n last_name: data.last_name,\n bio: data.bio,\n });\n if (!result) throw new Error('Update user profile failed');\n\n return result;\n};\n\n// Handle success\nconst handleSuccess = (_data: any) => {\n toast.success('User profile updated successfully!');\n};\n\n// Handle error\nconst handleError = (error: any) => {\n toast.error(error.message || 'Update user profile failed');\n};\n</script>\n"],"mappings":";;;;;;;;;AAQA,MAAa,gCAAgC,aAC3C,yBACA,qBACA;CACE,YAAY;EACV,WAAW;EACX,aAAa;EACb,UAAU;EACV,cAAc;EACd,WAAW;EACZ;CAED,WAAW;EACT,WAAW;EACX,aAAa;EACb,UAAU;EACV,cAAc;EACf;CAED,KAAK;EACH,WAAW;EACX,aAAa;EACb,UAAU;EACX;CACF,CACF;;;;;;;;;;;;;;;;;;;;;;;;;;EC2CD,MAAM,UAAU,qBAAqB;EACrC,MAAM,EAAE,0BAA0B,QAAQ;EAC1C,MAAM,gBAAgB,IAAI,MAAM;EAEhC,MAAM,EAAE,QAAQ,iBAAiB,aAC9B,KAAK,WAAqB;GACzB,MAAM,cAAe,IAAsB;AAC3C,OAAI,CAAC,YAAa,OAAM,IAAI,MAAM,uCAAuC;AACzE,UAAQ,YAAqC,yBAAyB;KAExE,EAAE,eAAe,OAAO,CACzB;EAED,MAAM,qBAAqB,YAAY;AACrC,OAAI;AACF,kBAAc,QAAQ;AAEtB,SADe,MAAM,aAAa,OAAU,GAChC,IAAI;AACd,WAAM,QAAQ,oDAAoD;AAClE,WAAM,QAAQ,cAAc;UAE5B,OAAM,MAAM,uCAAuC;YAE9C,OAAO;AACd,UAAM,MAAM,iBAAiB,QAAQ,MAAM,UAAU,mBAAmB;aAChE;AACR,kBAAc,QAAQ;;;EAK1B,MAAM,EAAE,MAAM,iBAAiB,SAAS,wBAAwB,UAC7D,QAAQ,IAAI,aAAa,uBAAuB,EACjD;GACE,SAAS,CAAC,CAAC,QAAQ,aAAa,KAAK;GACrC,WAAW,MAAS;GACrB,CACF;EAGD,MAAM,EAAE,MAAM,OAAO,WAAW,sBAAsB,QAAQ,+BAA+B;GAC3F,WAAW;GACX,uBAAuB;GACvB,aAAa;GACb,WAAW,YAAY;AACrB,WAAO,oBAAoB,MACzB,OAAM,IAAI,SAAS,YAAY,WAAW,SAAS,IAAI,CAAC;AAG1D,QAAI,CAAC,gBAAgB,MACnB,QAAO;KACL,SAAS,QAAQ,aAAa,KAAK,UAAU;KAC7C,KAAK;KACL,YAAY;KACZ,WAAW;KACZ;AAGH,WAAO;KACL,SAAS,gBAAgB,MAAM;KAC/B,KAAK,gBAAgB,MAAM,OAAO;KAClC,YAAY,gBAAgB,MAAM,cAAc;KAChD,WAAW,gBAAgB,MAAM,aAAa;KAC/C;;GAEJ,CAAC;EAEF,MAAM,EAAE,QAAQ,sBAAsB,aACnC,KAAK,UAAgC,IAAI,aAAa,kBAAkB,MAAM,EAC/E,EAAE,YAAY,iBAAiB,CAChC;EAGD,MAAM,eAAe,OAAO,SAA+B;AACzD,OAAI,CAAC,QAAQ,aAAa,KAAK,OAC7B,OAAM,IAAI,MAAM,yBAAyB;GAG3C,MAAM,SAAS,MAAM,kBAAkB;IACrC,SAAS,QAAQ,aAAa,KAAK;IACnC,YAAY,KAAK;IACjB,WAAW,KAAK;IAChB,KAAK,KAAK;IACX,CAAC;AACF,OAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,6BAA6B;AAE1D,UAAO;;EAIT,MAAM,iBAAiB,UAAe;AACpC,SAAM,QAAQ,qCAAqC;;EAIrD,MAAM,eAAe,UAAe;AAClC,SAAM,MAAM,MAAM,WAAW,6BAA6B;;;UA3K/C,MAAA,KAAI,CAAC,aAAA,WAAA,EAAhB,mBAEM,OAFN,YAEM,CAAA,GAAA,OAAA,OAAA,OAAA,KAAA,CADJ,mBAAwD,QAAA,EAAlD,OAAM,sCAAoC,EAAA,MAAA,GAAA,CAAA,EAAA,CAAA,IAElC,MAAA,KAAI,CAAC,aAAA,WAAA,EAArB,mBAeM,OAfN,YAeM,CAAA,OAAA,OAAA,OAAA,KAdJ,mBAYM,OAAA;IAXJ,OAAM;IACN,OAAM;IACN,MAAK;IACL,SAAQ;OAER,mBAKE,QAAA;IAJA,kBAAe;IACf,mBAAgB;IAChB,gBAAa;IACb,GAAE;cAGN,mBAAiC,QAAA,MAAA,gBAAxB,MAAA,KAAI,CAAC,UAAS,EAAA,EAAA,CAAA,CAAA,KAAA,WAAA,EAEzB,mBAuCM,OAvCN,YAuCM;8BAtCJ,mBAAwE,MAAA,EAApE,OAAM,uCAAqC,EAAC,uBAAmB,GAAA;IAEnE,mBAAA,gCAAoC;IACzB,MAAA,QAAO,CAAC,aAAa,KAAK,SAAA,WAAA,EAArC,mBA0BM,OA1BN,YA0BM,CAzBJ,mBAwBM,OAxBN,YAwBM,CAvBJ,mBAUM,OAAA,MAAA;+BATJ,mBAAiD,KAAA,EAA9C,OAAM,gCAA8B,EAAC,SAAK,GAAA;KAC7C,mBAA+D,KAA/D,YAA+D,gBAArC,MAAA,QAAO,CAAC,YAAY,KAAK,MAAK,EAAA,EAAA;KAEhD,MAAA,sBAAqB,KAAA,cAAA,WAAA,EAD7B,mBAMI,KAAA;;MAJF,OAAK,eAAA,CAAC,gBACE,MAAA,QAAO,CAAC,YAAY,KAAK,iBAAc,iBAAA,eAAA,CAAA;wBAE5C,MAAA,QAAO,CAAC,YAAY,KAAK,iBAAc,aAAA,eAAA,EAAA,EAAA,IAAA,mBAAA,QAAA,KAAA;QAIzB,MAAA,sBAAqB,KAAA,cAAA,CAAgC,MAAA,QAAO,CAAC,YAAY,KAAK,kBAAA,WAAA,EADnG,mBAWS,UAAA;;KANP,MAAK;KACL,OAAM;KACL,UAAU,cAAA;KACV,SAAO;uBAEL,cAAA,QAAa,eAAA,sBAAA,EAAA,GAAA,WAAA,IAAA,mBAAA,QAAA,KAAA,CAAA,CAAA,CAAA,CAAA,IAAA,mBAAA,QAAA,KAAA;IAKtB,YAMY,MAAA,UAAA,EAAA;KANA,gBAAe;KAAe,WAAS;KAAgB,SAAO;;4BAChD;MAAxB,YAAwB,MAAA,MAAA,CAAA,eAAA;MACxB,YAAuB,MAAA,MAAA,CAAA,cAAA;MACvB,YAAkB,MAAA,MAAA,CAAA,SAAA;MAElB,YAAsE,MAAA,kBAAA,EAAA;OAAnD,YAAW;OAAS,gBAAe"}
@@ -0,0 +1,7 @@
1
+ import "./useRpcAuth-8Byr6SSI.js";
2
+ import "./useQueryCache-CHG4-HGF.js";
3
+ import "./useMutation-DbzXtqf1.js";
4
+ import "./useQuery-BKb5JXVS.js";
5
+ import { t as UserProfilePage_default } from "./UserProfilePage-X4z2lG-J.js";
6
+
7
+ export { UserProfilePage_default as default };
@@ -1,9 +1,8 @@
1
- import { l as useUserSessionStore, m as useEnv } from "./useRpcAuth-SgNzCAPa.js";
2
- import { t as useMutation } from "./useMutation-DzRSXPB1.js";
3
- import { t as AppLink_default } from "./AppLink-CHMMrSFI.js";
4
- import { i as withReturnUrl } from "./useReturnUrl-BBoPnDR3.js";
1
+ import { l as useUserSessionStore, m as useEnv } from "./useRpcAuth-8Byr6SSI.js";
2
+ import { t as useMutation } from "./useMutation-DbzXtqf1.js";
3
+ import { o as withReturnUrl, s as AppLink_default, t as getAndClearEmailVerificationReturnUrl } from "./useReturnUrl-Da8PpLb9.js";
5
4
  import { computed, createCommentVNode, createElementBlock, createElementVNode, createStaticVNode, createTextVNode, createVNode, defineComponent, onMounted, openBlock, ref, toDisplayString, withCtx } from "vue";
6
- import { useRoute } from "vue-router";
5
+ import { useRoute, useRouter } from "vue-router";
7
6
  import { toast } from "vue3-toastify";
8
7
 
9
8
  //#region src/slices/auth/features/verify_email/VerifyEmail.vue
@@ -17,19 +16,31 @@ const _hoisted_4 = {
17
16
  key: 1,
18
17
  class: "space-y-4"
19
18
  };
20
- const _hoisted_5 = { class: "text-sm text-base-content/70" };
19
+ const _hoisted_5 = {
20
+ key: 0,
21
+ class: "text-sm text-base-content/70"
22
+ };
21
23
  const _hoisted_6 = {
24
+ key: 1,
25
+ class: "text-sm text-base-content/70"
26
+ };
27
+ const _hoisted_7 = {
28
+ key: 2,
29
+ class: "text-sm text-base-content/60"
30
+ };
31
+ const _hoisted_8 = {
22
32
  key: 2,
23
33
  class: "space-y-4"
24
34
  };
25
- const _hoisted_7 = { class: "text-sm text-base-content/70" };
26
- const _hoisted_8 = { class: "flex flex-col gap-2 items-center" };
27
- const _hoisted_9 = ["disabled"];
35
+ const _hoisted_9 = { class: "text-sm text-base-content/70" };
36
+ const _hoisted_10 = { class: "flex flex-col gap-2 items-center" };
37
+ const _hoisted_11 = ["disabled"];
28
38
  const AUTH_CHANNEL = "auth";
29
39
  const _sfc_main = /* @__PURE__ */ defineComponent({
30
40
  __name: "VerifyEmail",
31
41
  setup(__props) {
32
42
  const route = useRoute();
43
+ const router = useRouter();
33
44
  const returnUrl = computed(() => route.query.returnUrl);
34
45
  const loginLink = computed(() => withReturnUrl("/auth/login", returnUrl.value));
35
46
  const sessionStore = useUserSessionStore();
@@ -39,11 +50,15 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
39
50
  const errorMessage = ref("");
40
51
  const verifyEmailApi = ref(false);
41
52
  const resendLoading = ref(false);
53
+ const redirectTarget = ref(null);
42
54
  const { mutate: verifyMutate } = useMutation((api, tokenToVerify) => {
43
55
  const verifyEmail = api.verifyEmail;
44
56
  if (!verifyEmail) throw new Error("Email verification is not configured");
45
57
  return verifyEmail.verifyEmail(tokenToVerify);
46
- }, { skipAuthCheck: true });
58
+ }, {
59
+ skipAuthCheck: true,
60
+ credentials: "include"
61
+ });
47
62
  const { mutate: resendMutate } = useMutation((api, _input) => {
48
63
  const verifyEmail = api.verifyEmail;
49
64
  if (!verifyEmail) throw new Error("Email verification is not configured");
@@ -65,12 +80,21 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
65
80
  verifyEmailApi.value = true;
66
81
  if (result?.ok) {
67
82
  status.value = "success";
68
- try {
83
+ const hadSession = !!(result.session?.access_token && result.session?.user_details_token);
84
+ if (hadSession) {
85
+ sessionStore.setSession(result.session.user_details_token);
86
+ sessionStore.setAccessToken(result.session.access_token);
87
+ } else try {
69
88
  await sessionStore.refreshToken();
70
89
  } catch {}
71
90
  const channel = new BroadcastChannel(AUTH_CHANNEL);
72
91
  channel.postMessage({ type: "email_verified" });
73
92
  channel.close();
93
+ const target = getAndClearEmailVerificationReturnUrl() ?? (hadSession ? "/" : null);
94
+ if (target) {
95
+ redirectTarget.value = target;
96
+ setTimeout(() => router.push(target), 1e3);
97
+ }
74
98
  } else status.value = "error";
75
99
  } catch (error) {
76
100
  status.value = "error";
@@ -91,7 +115,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
91
115
  };
92
116
  return (_ctx, _cache) => {
93
117
  return openBlock(), createElementBlock("div", _hoisted_1, [createElementVNode("div", _hoisted_2, [status.value === "loading" ? (openBlock(), createElementBlock("div", _hoisted_3, [..._cache[0] || (_cache[0] = [createElementVNode("span", { class: "loading loading-spinner loading-lg text-primary" }, null, -1), createElementVNode("p", { class: "text-sm text-base-content/70" }, "Verifying your email...", -1)])])) : status.value === "success" ? (openBlock(), createElementBlock("div", _hoisted_4, [
94
- _cache[4] || (_cache[4] = createElementVNode("div", { class: "w-14 h-14 rounded-full bg-success/20 flex items-center justify-center mx-auto" }, [createElementVNode("svg", {
118
+ _cache[7] || (_cache[7] = createElementVNode("div", { class: "w-14 h-14 rounded-full bg-success/20 flex items-center justify-center mx-auto" }, [createElementVNode("svg", {
95
119
  xmlns: "http://www.w3.org/2000/svg",
96
120
  class: "w-7 h-7 text-success",
97
121
  viewBox: "0 0 24 24",
@@ -101,8 +125,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
101
125
  "stroke-linecap": "round",
102
126
  "stroke-linejoin": "round"
103
127
  }, [createElementVNode("polyline", { points: "20 6 9 17 4 12" })])], -1)),
104
- _cache[5] || (_cache[5] = createElementVNode("h3", { class: "text-lg font-semibold" }, "Email verified!", -1)),
105
- createElementVNode("p", _hoisted_5, [
128
+ _cache[8] || (_cache[8] = createElementVNode("h3", { class: "text-lg font-semibold" }, "Email verified!", -1)),
129
+ redirectTarget.value ? (openBlock(), createElementBlock("p", _hoisted_5, " Redirecting you... ")) : (openBlock(), createElementBlock("p", _hoisted_6, [
106
130
  _cache[2] || (_cache[2] = createTextVNode(" Your email has been verified. Switch back to your other tab to continue, or ", -1)),
107
131
  createVNode(AppLink_default, {
108
132
  to: loginLink.value,
@@ -112,15 +136,26 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
112
136
  _: 1
113
137
  }, 8, ["to"]),
114
138
  _cache[3] || (_cache[3] = createTextVNode(". ", -1))
115
- ])
116
- ])) : (openBlock(), createElementBlock("div", _hoisted_6, [
117
- _cache[7] || (_cache[7] = createStaticVNode("<div class=\"w-14 h-14 rounded-full bg-error/20 flex items-center justify-center mx-auto\"><svg xmlns=\"http://www.w3.org/2000/svg\" class=\"w-7 h-7 text-error\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"15\" y1=\"9\" x2=\"9\" y2=\"15\"></line><line x1=\"9\" y1=\"9\" x2=\"15\" y2=\"15\"></line></svg></div><h3 class=\"text-lg font-semibold\">Verification failed</h3>", 2)),
118
- createElementVNode("p", _hoisted_7, toDisplayString(errorMessage.value), 1),
119
- createElementVNode("div", _hoisted_8, [createVNode(AppLink_default, {
139
+ ])),
140
+ redirectTarget.value ? (openBlock(), createElementBlock("p", _hoisted_7, [
141
+ _cache[5] || (_cache[5] = createTextVNode(" If you aren't redirected automatically, ", -1)),
142
+ createVNode(AppLink_default, {
143
+ to: redirectTarget.value,
144
+ class: "link link-primary"
145
+ }, {
146
+ default: withCtx(() => [..._cache[4] || (_cache[4] = [createTextVNode("click here", -1)])]),
147
+ _: 1
148
+ }, 8, ["to"]),
149
+ _cache[6] || (_cache[6] = createTextVNode(". ", -1))
150
+ ])) : createCommentVNode("v-if", true)
151
+ ])) : (openBlock(), createElementBlock("div", _hoisted_8, [
152
+ _cache[10] || (_cache[10] = createStaticVNode("<div class=\"w-14 h-14 rounded-full bg-error/20 flex items-center justify-center mx-auto\"><svg xmlns=\"http://www.w3.org/2000/svg\" class=\"w-7 h-7 text-error\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"15\" y1=\"9\" x2=\"9\" y2=\"15\"></line><line x1=\"9\" y1=\"9\" x2=\"15\" y2=\"15\"></line></svg></div><h3 class=\"text-lg font-semibold\">Verification failed</h3>", 2)),
153
+ createElementVNode("p", _hoisted_9, toDisplayString(errorMessage.value), 1),
154
+ createElementVNode("div", _hoisted_10, [createVNode(AppLink_default, {
120
155
  to: loginLink.value,
121
156
  class: "btn btn-outline btn-sm"
122
157
  }, {
123
- default: withCtx(() => [..._cache[6] || (_cache[6] = [createTextVNode("Back to login", -1)])]),
158
+ default: withCtx(() => [..._cache[9] || (_cache[9] = [createTextVNode("Back to login", -1)])]),
124
159
  _: 1
125
160
  }, 8, ["to"]), verifyEmailApi.value ? (openBlock(), createElementBlock("button", {
126
161
  key: 0,
@@ -128,7 +163,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
128
163
  class: "btn btn-ghost btn-sm",
129
164
  disabled: resendLoading.value,
130
165
  onClick: resendVerification
131
- }, toDisplayString(resendLoading.value ? "Sending..." : "Resend verification email"), 9, _hoisted_9)) : createCommentVNode("v-if", true)])
166
+ }, toDisplayString(resendLoading.value ? "Sending..." : "Resend verification email"), 9, _hoisted_11)) : createCommentVNode("v-if", true)])
132
167
  ]))])]);
133
168
  };
134
169
  }
@@ -137,4 +172,4 @@ var VerifyEmail_default = _sfc_main;
137
172
 
138
173
  //#endregion
139
174
  export { VerifyEmail_default as t };
140
- //# sourceMappingURL=VerifyEmail-CHfTzrHg.js.map
175
+ //# sourceMappingURL=VerifyEmail-8bsvoDdM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VerifyEmail-8bsvoDdM.js","names":[],"sources":["../src/slices/auth/features/verify_email/VerifyEmail.vue"],"sourcesContent":["<template>\n <div class=\"card bg-base-100 shadow-lg border border-base-300 max-w-md mx-auto\">\n <div class=\"card-body p-4 sm:p-6 text-center\">\n <div v-if=\"status === 'loading'\" class=\"space-y-4\">\n <span class=\"loading loading-spinner loading-lg text-primary\"></span>\n <p class=\"text-sm text-base-content/70\">Verifying your email...</p>\n </div>\n <div v-else-if=\"status === 'success'\" class=\"space-y-4\">\n <div\n class=\"w-14 h-14 rounded-full bg-success/20 flex items-center justify-center mx-auto\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n class=\"w-7 h-7 text-success\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n </div>\n <h3 class=\"text-lg font-semibold\">Email verified!</h3>\n <p v-if=\"redirectTarget\" class=\"text-sm text-base-content/70\">\n Redirecting you...\n </p>\n <p v-else class=\"text-sm text-base-content/70\">\n Your email has been verified. Switch back to your other tab to continue, or\n <AppLink :to=\"loginLink\" class=\"link link-primary\">continue to login</AppLink>.\n </p>\n <p v-if=\"redirectTarget\" class=\"text-sm text-base-content/60\">\n If you aren't redirected automatically,\n <AppLink :to=\"redirectTarget\" class=\"link link-primary\">click here</AppLink>.\n </p>\n </div>\n <div v-else class=\"space-y-4\">\n <div\n class=\"w-14 h-14 rounded-full bg-error/20 flex items-center justify-center mx-auto\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n class=\"w-7 h-7 text-error\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <line x1=\"15\" y1=\"9\" x2=\"9\" y2=\"15\" />\n <line x1=\"9\" y1=\"9\" x2=\"15\" y2=\"15\" />\n </svg>\n </div>\n <h3 class=\"text-lg font-semibold\">Verification failed</h3>\n <p class=\"text-sm text-base-content/70\">{{ errorMessage }}</p>\n <div class=\"flex flex-col gap-2 items-center\">\n <AppLink :to=\"loginLink\" class=\"btn btn-outline btn-sm\">Back to login</AppLink>\n <button\n v-if=\"verifyEmailApi\"\n type=\"button\"\n class=\"btn btn-ghost btn-sm\"\n :disabled=\"resendLoading\"\n @click=\"resendVerification\"\n >\n {{ resendLoading ? 'Sending...' : 'Resend verification email' }}\n </button>\n </div>\n </div>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport AppLink from '../../../../components/AppLink.vue';\nimport { useEnv } from '../../../../composables/useEnv';\nimport { useMutation } from '../../../../composables/useMutation';\nimport { useUserSessionStore } from '../../../../composables/useUserSessionStore';\nimport { withReturnUrl, getAndClearEmailVerificationReturnUrl } from '../../../../utils/useReturnUrl';\nimport type { DragoncoreApi } from '@dragonmastery/dragoncore-shared';\nimport type { EmailVerificationApi } from '@dragonmastery/dragoncore-shared';\nimport { computed, ref, onMounted } from 'vue';\nimport { useRoute, useRouter } from 'vue-router';\nimport { toast } from 'vue3-toastify';\n\nconst AUTH_CHANNEL = 'auth';\n\nconst route = useRoute();\nconst router = useRouter();\nconst returnUrl = computed(() => route.query.returnUrl as string | undefined);\nconst loginLink = computed(() => withReturnUrl('/auth/login', returnUrl.value));\nconst sessionStore = useUserSessionStore();\nconst { emailVerificationMode } = useEnv();\n\n// Support token from query (?token=xxx) or params (/verify-email/:token)\nconst token = (route.query.token ?? route.params.token) as string;\n\nconst status = ref<'loading' | 'success' | 'error'>('loading');\nconst errorMessage = ref<string>('');\nconst verifyEmailApi = ref<boolean>(false);\nconst resendLoading = ref(false);\nconst redirectTarget = ref<string | null>(null);\n\nconst { mutate: verifyMutate } = useMutation(\n (api, tokenToVerify: string) => {\n const verifyEmail = (api as DragoncoreApi).verifyEmail;\n if (!verifyEmail) throw new Error('Email verification is not configured');\n return (verifyEmail as EmailVerificationApi).verifyEmail(tokenToVerify);\n },\n { skipAuthCheck: true, credentials: 'include' },\n);\n\nconst { mutate: resendMutate } = useMutation(\n (api, _input?: unknown) => {\n const verifyEmail = (api as DragoncoreApi).verifyEmail;\n if (!verifyEmail) throw new Error('Email verification is not configured');\n return (verifyEmail as EmailVerificationApi).resendVerificationEmail();\n },\n { skipAuthCheck: false },\n);\n\nonMounted(async () => {\n if (!token) {\n status.value = 'error';\n errorMessage.value = 'No verification token provided.';\n return;\n }\n\n if (emailVerificationMode === 'disabled') {\n status.value = 'error';\n errorMessage.value = 'Email verification is not enabled for this application.';\n return;\n }\n\n try {\n const result = await verifyMutate(token);\n verifyEmailApi.value = true;\n if (result?.ok) {\n status.value = 'success';\n const hadSession =\n !!(result.session?.access_token && result.session?.user_details_token);\n if (hadSession) {\n sessionStore.setSession(result.session!.user_details_token);\n sessionStore.setAccessToken(result.session!.access_token);\n } else {\n try {\n await sessionStore.refreshToken();\n } catch {\n // User may need to log in again; that's ok\n }\n }\n const channel = new BroadcastChannel(AUTH_CHANNEL);\n channel.postMessage({ type: 'email_verified' });\n channel.close();\n const storedReturnUrl = getAndClearEmailVerificationReturnUrl();\n const target = storedReturnUrl ?? (hadSession ? '/' : null);\n if (target) {\n redirectTarget.value = target;\n setTimeout(() => router.push(target), 1000);\n }\n } else {\n status.value = 'error';\n }\n } catch (error) {\n status.value = 'error';\n errorMessage.value = error instanceof Error ? error.message : 'Something went wrong. The link may have expired.';\n verifyEmailApi.value = true;\n }\n});\n\nconst resendVerification = async () => {\n try {\n resendLoading.value = true;\n const result = await resendMutate(undefined);\n if (result?.ok) {\n toast.success('Verification email sent. Please check your inbox.');\n } else {\n toast.error('Failed to resend verification email.');\n }\n } catch (error) {\n toast.error(error instanceof Error ? error.message : 'Failed to resend');\n } finally {\n resendLoading.value = false;\n }\n};\n</script>\n"],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import "./useRpcAuth-8Byr6SSI.js";
2
+ import "./useQueryCache-CHG4-HGF.js";
3
+ import "./useMutation-DbzXtqf1.js";
4
+ import "./useReturnUrl-Da8PpLb9.js";
5
+ import { t as VerifyEmail_default } from "./VerifyEmail-8bsvoDdM.js";
6
+
7
+ export { VerifyEmail_default as default };
@@ -1,9 +1,8 @@
1
- import { l as useUserSessionStore } from "./useRpcAuth-SgNzCAPa.js";
2
- import "./useQueryCache-DIGf3fCM.js";
3
- import { t as useMutation } from "./useMutation-DzRSXPB1.js";
4
- import { t as useQuery } from "./useQuery-bvJabe9Q.js";
5
- import { t as AppLink_default } from "./AppLink-CHMMrSFI.js";
6
- import { i as withReturnUrl } from "./useReturnUrl-BBoPnDR3.js";
1
+ import { l as useUserSessionStore } from "./useRpcAuth-8Byr6SSI.js";
2
+ import "./useQueryCache-CHG4-HGF.js";
3
+ import { t as useMutation } from "./useMutation-DbzXtqf1.js";
4
+ import { t as useQuery } from "./useQuery-BKb5JXVS.js";
5
+ import { o as withReturnUrl, s as AppLink_default } from "./useReturnUrl-Da8PpLb9.js";
7
6
  import { computed, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, openBlock, ref, toDisplayString, withCtx } from "vue";
8
7
  import { useRoute } from "vue-router";
9
8
  import { toast } from "vue3-toastify";
@@ -72,4 +71,4 @@ var VerifyEmailRequired_default = _sfc_main;
72
71
 
73
72
  //#endregion
74
73
  export { VerifyEmailRequired_default as default };
75
- //# sourceMappingURL=VerifyEmailRequired-BCKREd_C.js.map
74
+ //# sourceMappingURL=VerifyEmailRequired-CN1FU1AE.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"VerifyEmailRequired-BCKREd_C.js","names":[],"sources":["../src/slices/auth/features/verify_email_required/VerifyEmailRequired.vue"],"sourcesContent":["<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\">Check your email</h1>\n <p class=\"text-base-content/80 mb-6\">\n We sent a verification link to your email address. Click the link to verify your account,\n then you can log in.\n </p>\n <div class=\"flex flex-col gap-3\">\n <AppLink :to=\"loginLink\" class=\"btn btn-primary\">Continue to login</AppLink>\n <button\n v-if=\"isLoggedIn && verifyEmailApi\"\n type=\"button\"\n class=\"btn btn-outline btn-sm\"\n :disabled=\"resendLoading\"\n @click=\"resendVerification\"\n >\n {{ resendLoading ? 'Sending...' : 'Resend verification email' }}\n </button>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport AppLink from '../../../../components/AppLink.vue';\nimport type { DragoncoreApi } from '@dragonmastery/dragoncore-shared';\nimport type { EmailVerificationApi } from '@dragonmastery/dragoncore-shared';\nimport { computed, ref } from 'vue';\nimport { useRoute } from 'vue-router';\nimport { toast } from 'vue3-toastify';\nimport { useMutation } from '../../../../composables/useMutation';\nimport { useQuery } from '../../../../composables/useQuery';\nimport { useUserSessionStore } from '../../../../composables/useUserSessionStore';\nimport { withReturnUrl } from '../../../../utils/useReturnUrl';\n\nconst route = useRoute();\nconst session = useUserSessionStore();\n\nconst returnUrl = computed(() => route.query.returnUrl as string | undefined);\nconst loginLink = computed(() => withReturnUrl('/auth/login', returnUrl.value));\nconst resendLoading = ref(false);\nconst verifyEmailApi = ref(false);\n\nconst isLoggedIn = computed(() => !!session.userSession?.user.userId);\n\nuseQuery(\n (api) => {\n verifyEmailApi.value = !!(api as DragoncoreApi).verifyEmail;\n return Promise.resolve(true);\n },\n { enabled: isLoggedIn, staleTime: 60 * 60 * 1000 },\n);\n\nconst { mutate: resendMutate } = useMutation(\n (api, _input?: unknown) => {\n const verifyEmail = (api as DragoncoreApi).verifyEmail;\n if (!verifyEmail) throw new Error('Email verification is not configured');\n return (verifyEmail as EmailVerificationApi).resendVerificationEmail();\n },\n { skipAuthCheck: false },\n);\n\nconst resendVerification = async () => {\n try {\n resendLoading.value = true;\n const result = await resendMutate(undefined);\n if (result?.ok) {\n toast.success('Verification email sent. Please check your inbox.');\n await session.refreshToken();\n } else {\n toast.error('Failed to resend verification email.');\n }\n } catch (error) {\n toast.error(error instanceof Error ? error.message : 'Failed to resend');\n } finally {\n resendLoading.value = false;\n }\n};\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;;EAkCA,MAAM,QAAQ,UAAU;EACxB,MAAM,UAAU,qBAAqB;EAErC,MAAM,YAAY,eAAe,MAAM,MAAM,UAAgC;EAC7E,MAAM,YAAY,eAAe,cAAc,eAAe,UAAU,MAAM,CAAC;EAC/E,MAAM,gBAAgB,IAAI,MAAM;EAChC,MAAM,iBAAiB,IAAI,MAAM;EAEjC,MAAM,aAAa,eAAe,CAAC,CAAC,QAAQ,aAAa,KAAK,OAAO;AAErE,YACG,QAAQ;AACP,kBAAe,QAAQ,CAAC,CAAE,IAAsB;AAChD,UAAO,QAAQ,QAAQ,KAAK;KAE9B;GAAE,SAAS;GAAY,WAAW,OAAU;GAAM,CACnD;EAED,MAAM,EAAE,QAAQ,iBAAiB,aAC9B,KAAK,WAAqB;GACzB,MAAM,cAAe,IAAsB;AAC3C,OAAI,CAAC,YAAa,OAAM,IAAI,MAAM,uCAAuC;AACzE,UAAQ,YAAqC,yBAAyB;KAExE,EAAE,eAAe,OAAO,CACzB;EAED,MAAM,qBAAqB,YAAY;AACrC,OAAI;AACF,kBAAc,QAAQ;AAEtB,SADe,MAAM,aAAa,OAAU,GAChC,IAAI;AACd,WAAM,QAAQ,oDAAoD;AAClE,WAAM,QAAQ,cAAc;UAE5B,OAAM,MAAM,uCAAuC;YAE9C,OAAO;AACd,UAAM,MAAM,iBAAiB,QAAQ,MAAM,UAAU,mBAAmB;aAChE;AACR,kBAAc,QAAQ;;;;uBAzExB,mBAkBM,OAlBN,YAkBM;8BAjBJ,mBAAqE,MAAA,EAAjE,OAAM,uCAAqC,EAAC,oBAAgB,GAAA;8BAChE,mBAGI,KAAA,EAHD,OAAM,6BAA2B,EAAC,oHAGrC,GAAA;IACA,mBAWM,OAXN,YAWM,CAVJ,YAA4E,iBAAA;KAAlE,IAAI,UAAA;KAAW,OAAM;;4BAAmC,CAAA,GAAA,OAAA,OAAA,OAAA,KAAA,CAAA,gBAAjB,qBAAiB,GAAA,CAAA,EAAA,CAAA;;mBAE1D,WAAA,SAAc,eAAA,SAAA,WAAA,EADtB,mBAQS,UAAA;;KANP,MAAK;KACL,OAAM;KACL,UAAU,cAAA;KACV,SAAO;uBAEL,cAAA,QAAa,eAAA,4BAAA,EAAA,GAAA,WAAA,IAAA,mBAAA,QAAA,KAAA,CAAA,CAAA"}
1
+ {"version":3,"file":"VerifyEmailRequired-CN1FU1AE.js","names":[],"sources":["../src/slices/auth/features/verify_email_required/VerifyEmailRequired.vue"],"sourcesContent":["<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\">Check your email</h1>\n <p class=\"text-base-content/80 mb-6\">\n We sent a verification link to your email address. Click the link to verify your account,\n then you can log in.\n </p>\n <div class=\"flex flex-col gap-3\">\n <AppLink :to=\"loginLink\" class=\"btn btn-primary\">Continue to login</AppLink>\n <button\n v-if=\"isLoggedIn && verifyEmailApi\"\n type=\"button\"\n class=\"btn btn-outline btn-sm\"\n :disabled=\"resendLoading\"\n @click=\"resendVerification\"\n >\n {{ resendLoading ? 'Sending...' : 'Resend verification email' }}\n </button>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport AppLink from '../../../../components/AppLink.vue';\nimport type { DragoncoreApi } from '@dragonmastery/dragoncore-shared';\nimport type { EmailVerificationApi } from '@dragonmastery/dragoncore-shared';\nimport { computed, ref } from 'vue';\nimport { useRoute } from 'vue-router';\nimport { toast } from 'vue3-toastify';\nimport { useMutation } from '../../../../composables/useMutation';\nimport { useQuery } from '../../../../composables/useQuery';\nimport { useUserSessionStore } from '../../../../composables/useUserSessionStore';\nimport { withReturnUrl } from '../../../../utils/useReturnUrl';\n\nconst route = useRoute();\nconst session = useUserSessionStore();\n\nconst returnUrl = computed(() => route.query.returnUrl as string | undefined);\nconst loginLink = computed(() => withReturnUrl('/auth/login', returnUrl.value));\nconst resendLoading = ref(false);\nconst verifyEmailApi = ref(false);\n\nconst isLoggedIn = computed(() => !!session.userSession?.user.userId);\n\nuseQuery(\n (api) => {\n verifyEmailApi.value = !!(api as DragoncoreApi).verifyEmail;\n return Promise.resolve(true);\n },\n { enabled: isLoggedIn, staleTime: 60 * 60 * 1000 },\n);\n\nconst { mutate: resendMutate } = useMutation(\n (api, _input?: unknown) => {\n const verifyEmail = (api as DragoncoreApi).verifyEmail;\n if (!verifyEmail) throw new Error('Email verification is not configured');\n return (verifyEmail as EmailVerificationApi).resendVerificationEmail();\n },\n { skipAuthCheck: false },\n);\n\nconst resendVerification = async () => {\n try {\n resendLoading.value = true;\n const result = await resendMutate(undefined);\n if (result?.ok) {\n toast.success('Verification email sent. Please check your inbox.');\n await session.refreshToken();\n } else {\n toast.error('Failed to resend verification email.');\n }\n } catch (error) {\n toast.error(error instanceof Error ? error.message : 'Failed to resend');\n } finally {\n resendLoading.value = false;\n }\n};\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;EAkCA,MAAM,QAAQ,UAAU;EACxB,MAAM,UAAU,qBAAqB;EAErC,MAAM,YAAY,eAAe,MAAM,MAAM,UAAgC;EAC7E,MAAM,YAAY,eAAe,cAAc,eAAe,UAAU,MAAM,CAAC;EAC/E,MAAM,gBAAgB,IAAI,MAAM;EAChC,MAAM,iBAAiB,IAAI,MAAM;EAEjC,MAAM,aAAa,eAAe,CAAC,CAAC,QAAQ,aAAa,KAAK,OAAO;AAErE,YACG,QAAQ;AACP,kBAAe,QAAQ,CAAC,CAAE,IAAsB;AAChD,UAAO,QAAQ,QAAQ,KAAK;KAE9B;GAAE,SAAS;GAAY,WAAW,OAAU;GAAM,CACnD;EAED,MAAM,EAAE,QAAQ,iBAAiB,aAC9B,KAAK,WAAqB;GACzB,MAAM,cAAe,IAAsB;AAC3C,OAAI,CAAC,YAAa,OAAM,IAAI,MAAM,uCAAuC;AACzE,UAAQ,YAAqC,yBAAyB;KAExE,EAAE,eAAe,OAAO,CACzB;EAED,MAAM,qBAAqB,YAAY;AACrC,OAAI;AACF,kBAAc,QAAQ;AAEtB,SADe,MAAM,aAAa,OAAU,GAChC,IAAI;AACd,WAAM,QAAQ,oDAAoD;AAClE,WAAM,QAAQ,cAAc;UAE5B,OAAM,MAAM,uCAAuC;YAE9C,OAAO;AACd,UAAM,MAAM,iBAAiB,QAAQ,MAAM,UAAU,mBAAmB;aAChE;AACR,kBAAc,QAAQ;;;;uBAzExB,mBAkBM,OAlBN,YAkBM;8BAjBJ,mBAAqE,MAAA,EAAjE,OAAM,uCAAqC,EAAC,oBAAgB,GAAA;8BAChE,mBAGI,KAAA,EAHD,OAAM,6BAA2B,EAAC,oHAGrC,GAAA;IACA,mBAWM,OAXN,YAWM,CAVJ,YAA4E,iBAAA;KAAlE,IAAI,UAAA;KAAW,OAAM;;4BAAmC,CAAA,GAAA,OAAA,OAAA,OAAA,KAAA,CAAA,gBAAjB,qBAAiB,GAAA,CAAA,EAAA,CAAA;;mBAE1D,WAAA,SAAc,eAAA,SAAA,WAAA,EADtB,mBAQS,UAAA;;KANP,MAAK;KACL,OAAM;KACL,UAAU,cAAA;KACV,SAAO;uBAEL,cAAA,QAAa,eAAA,4BAAA,EAAA,GAAA,WAAA,IAAA,mBAAA,QAAA,KAAA,CAAA,CAAA"}
@@ -0,0 +1,32 @@
1
+ import "./useRpcAuth-8Byr6SSI.js";
2
+ import "./useQueryCache-CHG4-HGF.js";
3
+ import "./useMutation-DbzXtqf1.js";
4
+ import "./useQuery-BKb5JXVS.js";
5
+ import { st as ViewTeam_default } from "./src-CkgUIye9.js";
6
+ import "./useReturnUrl-Da8PpLb9.js";
7
+ import "./TimelineSystemEvent-Dj2TMOF6.js";
8
+ import "./TeamMembersTab-4gmnP9sD.js";
9
+ import "./Appearance-BfPdKMXw.js";
10
+ import "./useBreadcrumbs-DmgSucoe.js";
11
+ import "./EditTeamMemberForm-DJW7yRQW.js";
12
+ import "./TeamHistoryTab-BrC6FFIw.js";
13
+ import "./UserProfilePage-X4z2lG-J.js";
14
+ import "./ChangePasswordPage-DXzU3NI9.js";
15
+ import "./TeamNotesTab-B2eETkAz.js";
16
+ import "./CustomerSupportTicketParent-B09_iFpJ.js";
17
+ import "./SupportTicketDevLifecycleBadge-Ba-Rm6QW.js";
18
+ import "./StaffSupportTicketParent-BYxQPuhI.js";
19
+ import "./LoginForm-IEP-hEh0.js";
20
+ import "./Signup-C94alv87.js";
21
+ import "./ForgotPassword-CJjzm9GK.js";
22
+ import "./ResetPassword-DuLuXaNp.js";
23
+ import "./Logout-Cm9kEzgH.js";
24
+ import "./mfaSchema-nfNCcEhM.js";
25
+ import "./MfaSetup-Ch0w-gTN.js";
26
+ import "./MfaVerify-BwzjVrTj.js";
27
+ import "./VerifyEmail-8bsvoDdM.js";
28
+ import "./UserListPage-QSdxrJT6.js";
29
+ import "./CreateUserPage-bwR6fq5C.js";
30
+ import "./EditUserPage-aDygGmfD.js";
31
+
32
+ export { ViewTeam_default as default };
@@ -0,0 +1,32 @@
1
+ import "./useRpcAuth-8Byr6SSI.js";
2
+ import "./useQueryCache-CHG4-HGF.js";
3
+ import "./useMutation-DbzXtqf1.js";
4
+ import "./useQuery-BKb5JXVS.js";
5
+ import { tt as ViewTeamMember_default } from "./src-CkgUIye9.js";
6
+ import "./useReturnUrl-Da8PpLb9.js";
7
+ import "./TimelineSystemEvent-Dj2TMOF6.js";
8
+ import "./TeamMembersTab-4gmnP9sD.js";
9
+ import "./Appearance-BfPdKMXw.js";
10
+ import "./useBreadcrumbs-DmgSucoe.js";
11
+ import "./EditTeamMemberForm-DJW7yRQW.js";
12
+ import "./TeamHistoryTab-BrC6FFIw.js";
13
+ import "./UserProfilePage-X4z2lG-J.js";
14
+ import "./ChangePasswordPage-DXzU3NI9.js";
15
+ import "./TeamNotesTab-B2eETkAz.js";
16
+ import "./CustomerSupportTicketParent-B09_iFpJ.js";
17
+ import "./SupportTicketDevLifecycleBadge-Ba-Rm6QW.js";
18
+ import "./StaffSupportTicketParent-BYxQPuhI.js";
19
+ import "./LoginForm-IEP-hEh0.js";
20
+ import "./Signup-C94alv87.js";
21
+ import "./ForgotPassword-CJjzm9GK.js";
22
+ import "./ResetPassword-DuLuXaNp.js";
23
+ import "./Logout-Cm9kEzgH.js";
24
+ import "./mfaSchema-nfNCcEhM.js";
25
+ import "./MfaSetup-Ch0w-gTN.js";
26
+ import "./MfaVerify-BwzjVrTj.js";
27
+ import "./VerifyEmail-8bsvoDdM.js";
28
+ import "./UserListPage-QSdxrJT6.js";
29
+ import "./CreateUserPage-bwR6fq5C.js";
30
+ import "./EditUserPage-aDygGmfD.js";
31
+
32
+ export { ViewTeamMember_default as default };
@@ -118,4 +118,4 @@ function getTimezoneOffsetString(date) {
118
118
 
119
119
  //#endregion
120
120
  export { toStringWithLocalTimeZoneOffSet as a, getTimezoneOffsetString as i, formatToISODate as n, formatUserDate as r, formatSystemTimestamp as t };
121
- //# sourceMappingURL=convertToLocalDateTime-mKs5eC9T.js.map
121
+ //# sourceMappingURL=convertToLocalDateTime-DOSGtMn8.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"convertToLocalDateTime-mKs5eC9T.js","names":["date: Date"],"sources":["../src/utils/convertToLocalDateTime.ts"],"sourcesContent":["/**\n * Format a date value to ISO date string (YYYY-MM-DD)\n * Used as formatter for date input fields to ensure consistent ISO format\n * @param date - Date string or Date object\n * @returns ISO date string (YYYY-MM-DD) or null if invalid\n */\nexport function formatToISODate(date: string | Date | null): string | null {\n if (!date) {\n return null;\n }\n try {\n return new Date(date).toISOString().split('T')[0] ?? null;\n } catch (e) {\n console.error('Invalid date format:', e);\n return null;\n }\n}\n\n/**\n * Extracts YYYY-MM-DD from a date string (handles both date-only and ISO format)\n * Used to avoid timezone issues: ISO strings like \"2024-02-02T00:00:00.000Z\" are\n * interpreted as UTC by Date(), which shows wrong date in western timezones\n */\nfunction extractDateOnly(dateString: string): string | null {\n const match = dateString.match(/^(\\d{4}-\\d{2}-\\d{2})/);\n const datePart = match?.[1];\n return datePart != null ? datePart : null;\n}\n\n/**\n * Formats user-inputted date-only fields (YYYY-MM-DD format) or ISO timestamps\n * These represent calendar dates in the user's local context, not precise timestamps\n * @param dateString - Date string in YYYY-MM-DD format or ISO timestamp\n * @param dateOnly - If true, returns only the date portion without time (default: true)\n * @returns Formatted date string or empty string if no date provided\n */\nexport function formatUserDate(\n dateString: string | null | undefined,\n dateOnly: boolean = true,\n): string {\n if (!dateString) return '';\n\n try {\n let date: Date;\n\n // For date-only fields, extract YYYY-MM-DD and parse as local to avoid timezone issues.\n // ISO strings like \"2024-02-02T00:00:00.000Z\" would otherwise be parsed as UTC midnight,\n // showing the wrong day (e.g. Feb 1 instead of Feb 2) in western timezones.\n const dateOnlyPart = extractDateOnly(dateString);\n if (dateOnlyPart) {\n const [year, month, day] = dateOnlyPart.split('-').map(Number);\n date = new Date(year!, month! - 1, day!); // month is 0-indexed\n } else {\n // Fallback for non-standard formats\n date = new Date(dateString);\n }\n\n // Check if date is valid (e.g., catches invalid dates like 2023-02-31)\n if (isNaN(date.getTime())) {\n console.warn('formatUserDate received invalid date:', dateString);\n return dateString;\n }\n\n if (dateOnly) {\n return date.toLocaleDateString(undefined, {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n });\n }\n\n return date.toLocaleString(undefined, {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n timeZoneName: 'short',\n });\n } catch (error) {\n console.error('Error formatting user date:', error);\n return dateString;\n }\n}\n\n/**\n * Formats system-generated timestamps (ISO format with time)\n * These represent precise moments in time, typically in UTC\n * @param timestamp - ISO timestamp string or YYYY-MM-DD date string\n * @param dateOnly - If true, returns only the date portion without time (default: false)\n * @returns Formatted timestamp string or empty string if no timestamp provided\n */\nexport function formatSystemTimestamp(\n timestamp: string | null | undefined,\n dateOnly: boolean = false,\n): string {\n if (!timestamp) return '';\n\n try {\n let date: Date;\n\n // Handle YYYY-MM-DD format specially to avoid timezone issues\n if (dateOnly && /^\\d{4}-\\d{2}-\\d{2}$/.test(timestamp)) {\n // For date-only strings, parse as local date to avoid UTC interpretation\n const [year, month, day] = timestamp.split('-').map(Number);\n date = new Date(year!, month! - 1, day!); // month is 0-indexed\n } else {\n // Handle ISO timestamp or other formats\n date = new Date(timestamp);\n }\n\n // Check if date is valid\n if (isNaN(date.getTime())) {\n console.warn('formatSystemTimestamp received invalid timestamp:', timestamp);\n return timestamp;\n }\n\n if (dateOnly) {\n return date.toLocaleDateString(undefined, {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n });\n }\n\n return date.toLocaleString(undefined, {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n timeZoneName: 'short',\n });\n } catch (error) {\n console.error('Error formatting system timestamp:', error);\n return timestamp;\n }\n}\n\nexport const toStringWithLocalTimeZoneOffSet = (date?: string | null) => {\n if (!date) return null;\n date = date.split('Z')[0];\n if (!date) return null;\n if (date.includes('T')) {\n return date + getTimezoneOffsetString(date);\n } else {\n return date + 'T12:00:00.000' + getTimezoneOffsetString(date);\n }\n};\n\nexport function getTimezoneOffsetString(date: string) {\n let offset = -new Date(date).getTimezoneOffset();\n let sign = offset < 0 ? '-' : '+';\n let hours = Math.floor(Math.abs(offset / 60));\n let minutes = Math.abs(offset % 60);\n return sign + pad(hours) + ':' + pad(minutes);\n\n function pad(n: number) {\n return n < 10 ? '0' + n : '' + n;\n }\n}\n"],"mappings":";;;;;;;AAMA,SAAgB,gBAAgB,MAA2C;AACzE,KAAI,CAAC,KACH,QAAO;AAET,KAAI;AACF,SAAO,IAAI,KAAK,KAAK,CAAC,aAAa,CAAC,MAAM,IAAI,CAAC,MAAM;UAC9C,GAAG;AACV,UAAQ,MAAM,wBAAwB,EAAE;AACxC,SAAO;;;;;;;;AASX,SAAS,gBAAgB,YAAmC;CAE1D,MAAM,WADQ,WAAW,MAAM,uBAAuB,GAC7B;AACzB,QAAO,YAAY,OAAO,WAAW;;;;;;;;;AAUvC,SAAgB,eACd,YACA,WAAoB,MACZ;AACR,KAAI,CAAC,WAAY,QAAO;AAExB,KAAI;EACF,IAAIA;EAKJ,MAAM,eAAe,gBAAgB,WAAW;AAChD,MAAI,cAAc;GAChB,MAAM,CAAC,MAAM,OAAO,OAAO,aAAa,MAAM,IAAI,CAAC,IAAI,OAAO;AAC9D,UAAO,IAAI,KAAK,MAAO,QAAS,GAAG,IAAK;QAGxC,QAAO,IAAI,KAAK,WAAW;AAI7B,MAAI,MAAM,KAAK,SAAS,CAAC,EAAE;AACzB,WAAQ,KAAK,yCAAyC,WAAW;AACjE,UAAO;;AAGT,MAAI,SACF,QAAO,KAAK,mBAAmB,QAAW;GACxC,MAAM;GACN,OAAO;GACP,KAAK;GACN,CAAC;AAGJ,SAAO,KAAK,eAAe,QAAW;GACpC,MAAM;GACN,OAAO;GACP,KAAK;GACL,MAAM;GACN,QAAQ;GACR,cAAc;GACf,CAAC;UACK,OAAO;AACd,UAAQ,MAAM,+BAA+B,MAAM;AACnD,SAAO;;;;;;;;;;AAWX,SAAgB,sBACd,WACA,WAAoB,OACZ;AACR,KAAI,CAAC,UAAW,QAAO;AAEvB,KAAI;EACF,IAAIA;AAGJ,MAAI,YAAY,sBAAsB,KAAK,UAAU,EAAE;GAErD,MAAM,CAAC,MAAM,OAAO,OAAO,UAAU,MAAM,IAAI,CAAC,IAAI,OAAO;AAC3D,UAAO,IAAI,KAAK,MAAO,QAAS,GAAG,IAAK;QAGxC,QAAO,IAAI,KAAK,UAAU;AAI5B,MAAI,MAAM,KAAK,SAAS,CAAC,EAAE;AACzB,WAAQ,KAAK,qDAAqD,UAAU;AAC5E,UAAO;;AAGT,MAAI,SACF,QAAO,KAAK,mBAAmB,QAAW;GACxC,MAAM;GACN,OAAO;GACP,KAAK;GACN,CAAC;AAGJ,SAAO,KAAK,eAAe,QAAW;GACpC,MAAM;GACN,OAAO;GACP,KAAK;GACL,MAAM;GACN,QAAQ;GACR,cAAc;GACf,CAAC;UACK,OAAO;AACd,UAAQ,MAAM,sCAAsC,MAAM;AAC1D,SAAO;;;AAIX,MAAa,mCAAmC,SAAyB;AACvE,KAAI,CAAC,KAAM,QAAO;AAClB,QAAO,KAAK,MAAM,IAAI,CAAC;AACvB,KAAI,CAAC,KAAM,QAAO;AAClB,KAAI,KAAK,SAAS,IAAI,CACpB,QAAO,OAAO,wBAAwB,KAAK;KAE3C,QAAO,OAAO,kBAAkB,wBAAwB,KAAK;;AAIjE,SAAgB,wBAAwB,MAAc;CACpD,IAAI,SAAS,CAAC,IAAI,KAAK,KAAK,CAAC,mBAAmB;CAChD,IAAI,OAAO,SAAS,IAAI,MAAM;CAC9B,IAAI,QAAQ,KAAK,MAAM,KAAK,IAAI,SAAS,GAAG,CAAC;CAC7C,IAAI,UAAU,KAAK,IAAI,SAAS,GAAG;AACnC,QAAO,OAAO,IAAI,MAAM,GAAG,MAAM,IAAI,QAAQ;CAE7C,SAAS,IAAI,GAAW;AACtB,SAAO,IAAI,KAAK,MAAM,IAAI,KAAK"}
1
+ {"version":3,"file":"convertToLocalDateTime-DOSGtMn8.js","names":["date: Date"],"sources":["../src/utils/convertToLocalDateTime.ts"],"sourcesContent":["/**\n * Format a date value to ISO date string (YYYY-MM-DD)\n * Used as formatter for date input fields to ensure consistent ISO format\n * @param date - Date string or Date object\n * @returns ISO date string (YYYY-MM-DD) or null if invalid\n */\nexport function formatToISODate(date: string | Date | null): string | null {\n if (!date) {\n return null;\n }\n try {\n return new Date(date).toISOString().split('T')[0] ?? null;\n } catch (e) {\n console.error('Invalid date format:', e);\n return null;\n }\n}\n\n/**\n * Extracts YYYY-MM-DD from a date string (handles both date-only and ISO format)\n * Used to avoid timezone issues: ISO strings like \"2024-02-02T00:00:00.000Z\" are\n * interpreted as UTC by Date(), which shows wrong date in western timezones\n */\nfunction extractDateOnly(dateString: string): string | null {\n const match = dateString.match(/^(\\d{4}-\\d{2}-\\d{2})/);\n const datePart = match?.[1];\n return datePart != null ? datePart : null;\n}\n\n/**\n * Formats user-inputted date-only fields (YYYY-MM-DD format) or ISO timestamps\n * These represent calendar dates in the user's local context, not precise timestamps\n * @param dateString - Date string in YYYY-MM-DD format or ISO timestamp\n * @param dateOnly - If true, returns only the date portion without time (default: true)\n * @returns Formatted date string or empty string if no date provided\n */\nexport function formatUserDate(\n dateString: string | null | undefined,\n dateOnly: boolean = true,\n): string {\n if (!dateString) return '';\n\n try {\n let date: Date;\n\n // For date-only fields, extract YYYY-MM-DD and parse as local to avoid timezone issues.\n // ISO strings like \"2024-02-02T00:00:00.000Z\" would otherwise be parsed as UTC midnight,\n // showing the wrong day (e.g. Feb 1 instead of Feb 2) in western timezones.\n const dateOnlyPart = extractDateOnly(dateString);\n if (dateOnlyPart) {\n const [year, month, day] = dateOnlyPart.split('-').map(Number);\n date = new Date(year!, month! - 1, day!); // month is 0-indexed\n } else {\n // Fallback for non-standard formats\n date = new Date(dateString);\n }\n\n // Check if date is valid (e.g., catches invalid dates like 2023-02-31)\n if (isNaN(date.getTime())) {\n console.warn('formatUserDate received invalid date:', dateString);\n return dateString;\n }\n\n if (dateOnly) {\n return date.toLocaleDateString(undefined, {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n });\n }\n\n return date.toLocaleString(undefined, {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n timeZoneName: 'short',\n });\n } catch (error) {\n console.error('Error formatting user date:', error);\n return dateString;\n }\n}\n\n/**\n * Formats system-generated timestamps (ISO format with time)\n * These represent precise moments in time, typically in UTC\n * @param timestamp - ISO timestamp string or YYYY-MM-DD date string\n * @param dateOnly - If true, returns only the date portion without time (default: false)\n * @returns Formatted timestamp string or empty string if no timestamp provided\n */\nexport function formatSystemTimestamp(\n timestamp: string | null | undefined,\n dateOnly: boolean = false,\n): string {\n if (!timestamp) return '';\n\n try {\n let date: Date;\n\n // Handle YYYY-MM-DD format specially to avoid timezone issues\n if (dateOnly && /^\\d{4}-\\d{2}-\\d{2}$/.test(timestamp)) {\n // For date-only strings, parse as local date to avoid UTC interpretation\n const [year, month, day] = timestamp.split('-').map(Number);\n date = new Date(year!, month! - 1, day!); // month is 0-indexed\n } else {\n // Handle ISO timestamp or other formats\n date = new Date(timestamp);\n }\n\n // Check if date is valid\n if (isNaN(date.getTime())) {\n console.warn('formatSystemTimestamp received invalid timestamp:', timestamp);\n return timestamp;\n }\n\n if (dateOnly) {\n return date.toLocaleDateString(undefined, {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n });\n }\n\n return date.toLocaleString(undefined, {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n timeZoneName: 'short',\n });\n } catch (error) {\n console.error('Error formatting system timestamp:', error);\n return timestamp;\n }\n}\n\nexport const toStringWithLocalTimeZoneOffSet = (date?: string | null) => {\n if (!date) return null;\n date = date.split('Z')[0];\n if (!date) return null;\n if (date.includes('T')) {\n return date + getTimezoneOffsetString(date);\n } else {\n return date + 'T12:00:00.000' + getTimezoneOffsetString(date);\n }\n};\n\nexport function getTimezoneOffsetString(date: string) {\n let offset = -new Date(date).getTimezoneOffset();\n let sign = offset < 0 ? '-' : '+';\n let hours = Math.floor(Math.abs(offset / 60));\n let minutes = Math.abs(offset % 60);\n return sign + pad(hours) + ':' + pad(minutes);\n\n function pad(n: number) {\n return n < 10 ? '0' + n : '' + n;\n }\n}\n"],"mappings":";;;;;;;AAMA,SAAgB,gBAAgB,MAA2C;AACzE,KAAI,CAAC,KACH,QAAO;AAET,KAAI;AACF,SAAO,IAAI,KAAK,KAAK,CAAC,aAAa,CAAC,MAAM,IAAI,CAAC,MAAM;UAC9C,GAAG;AACV,UAAQ,MAAM,wBAAwB,EAAE;AACxC,SAAO;;;;;;;;AASX,SAAS,gBAAgB,YAAmC;CAE1D,MAAM,WADQ,WAAW,MAAM,uBAAuB,GAC7B;AACzB,QAAO,YAAY,OAAO,WAAW;;;;;;;;;AAUvC,SAAgB,eACd,YACA,WAAoB,MACZ;AACR,KAAI,CAAC,WAAY,QAAO;AAExB,KAAI;EACF,IAAIA;EAKJ,MAAM,eAAe,gBAAgB,WAAW;AAChD,MAAI,cAAc;GAChB,MAAM,CAAC,MAAM,OAAO,OAAO,aAAa,MAAM,IAAI,CAAC,IAAI,OAAO;AAC9D,UAAO,IAAI,KAAK,MAAO,QAAS,GAAG,IAAK;QAGxC,QAAO,IAAI,KAAK,WAAW;AAI7B,MAAI,MAAM,KAAK,SAAS,CAAC,EAAE;AACzB,WAAQ,KAAK,yCAAyC,WAAW;AACjE,UAAO;;AAGT,MAAI,SACF,QAAO,KAAK,mBAAmB,QAAW;GACxC,MAAM;GACN,OAAO;GACP,KAAK;GACN,CAAC;AAGJ,SAAO,KAAK,eAAe,QAAW;GACpC,MAAM;GACN,OAAO;GACP,KAAK;GACL,MAAM;GACN,QAAQ;GACR,cAAc;GACf,CAAC;UACK,OAAO;AACd,UAAQ,MAAM,+BAA+B,MAAM;AACnD,SAAO;;;;;;;;;;AAWX,SAAgB,sBACd,WACA,WAAoB,OACZ;AACR,KAAI,CAAC,UAAW,QAAO;AAEvB,KAAI;EACF,IAAIA;AAGJ,MAAI,YAAY,sBAAsB,KAAK,UAAU,EAAE;GAErD,MAAM,CAAC,MAAM,OAAO,OAAO,UAAU,MAAM,IAAI,CAAC,IAAI,OAAO;AAC3D,UAAO,IAAI,KAAK,MAAO,QAAS,GAAG,IAAK;QAGxC,QAAO,IAAI,KAAK,UAAU;AAI5B,MAAI,MAAM,KAAK,SAAS,CAAC,EAAE;AACzB,WAAQ,KAAK,qDAAqD,UAAU;AAC5E,UAAO;;AAGT,MAAI,SACF,QAAO,KAAK,mBAAmB,QAAW;GACxC,MAAM;GACN,OAAO;GACP,KAAK;GACN,CAAC;AAGJ,SAAO,KAAK,eAAe,QAAW;GACpC,MAAM;GACN,OAAO;GACP,KAAK;GACL,MAAM;GACN,QAAQ;GACR,cAAc;GACf,CAAC;UACK,OAAO;AACd,UAAQ,MAAM,sCAAsC,MAAM;AAC1D,SAAO;;;AAIX,MAAa,mCAAmC,SAAyB;AACvE,KAAI,CAAC,KAAM,QAAO;AAClB,QAAO,KAAK,MAAM,IAAI,CAAC;AACvB,KAAI,CAAC,KAAM,QAAO;AAClB,KAAI,KAAK,SAAS,IAAI,CACpB,QAAO,OAAO,wBAAwB,KAAK;KAE3C,QAAO,OAAO,kBAAkB,wBAAwB,KAAK;;AAIjE,SAAgB,wBAAwB,MAAc;CACpD,IAAI,SAAS,CAAC,IAAI,KAAK,KAAK,CAAC,mBAAmB;CAChD,IAAI,OAAO,SAAS,IAAI,MAAM;CAC9B,IAAI,QAAQ,KAAK,MAAM,KAAK,IAAI,SAAS,GAAG,CAAC;CAC7C,IAAI,UAAU,KAAK,IAAI,SAAS,GAAG;AACnC,QAAO,OAAO,IAAI,MAAM,GAAG,MAAM,IAAI,QAAQ;CAE7C,SAAS,IAAI,GAAW;AACtB,SAAO,IAAI,KAAK,MAAM,IAAI,KAAK"}
@@ -10,4 +10,4 @@ function formatTicketDisplayId(display_id, display_id_prefix, fallbackId) {
10
10
 
11
11
  //#endregion
12
12
  export { formatTicketDisplayId as t };
13
- //# sourceMappingURL=displayIdFormatter-rSbbsHIX.js.map
13
+ //# sourceMappingURL=displayIdFormatter-B1ZKgofu.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"displayIdFormatter-rSbbsHIX.js","names":[],"sources":["../src/slices/support_ticket/utils/displayIdFormatter.ts"],"sourcesContent":["/**\n * Formats a display ID with prefix (e.g., \"SP-123\")\n * Falls back to last 8 chars of ID if display_id not available\n */\nexport function formatTicketDisplayId(\n display_id: string | null | undefined,\n display_id_prefix: string | null | undefined,\n fallbackId: string,\n): string {\n if (display_id && display_id_prefix) {\n return `${display_id_prefix}-${display_id}`;\n }\n // Fallback to last 8 chars of ID\n return `#${fallbackId.slice(-8)}`;\n}\n"],"mappings":";;;;;AAIA,SAAgB,sBACd,YACA,mBACA,YACQ;AACR,KAAI,cAAc,kBAChB,QAAO,GAAG,kBAAkB,GAAG;AAGjC,QAAO,IAAI,WAAW,MAAM,GAAG"}
1
+ {"version":3,"file":"displayIdFormatter-B1ZKgofu.js","names":[],"sources":["../src/slices/support_ticket/utils/displayIdFormatter.ts"],"sourcesContent":["/**\n * Formats a display ID with prefix (e.g., \"SP-123\")\n * Falls back to last 8 chars of ID if display_id not available\n */\nexport function formatTicketDisplayId(\n display_id: string | null | undefined,\n display_id_prefix: string | null | undefined,\n fallbackId: string,\n): string {\n if (display_id && display_id_prefix) {\n return `${display_id_prefix}-${display_id}`;\n }\n // Fallback to last 8 chars of ID\n return `#${fallbackId.slice(-8)}`;\n}\n"],"mappings":";;;;;AAIA,SAAgB,sBACd,YACA,mBACA,YACQ;AACR,KAAI,cAAc,kBAChB,QAAO,GAAG,kBAAkB,GAAG;AAGjC,QAAO,IAAI,WAAW,MAAM,GAAG"}
@@ -17,4 +17,4 @@ function extractRpcErrorMessage(error, fallback = "An unknown error occurred.")
17
17
 
18
18
  //#endregion
19
19
  export { extractRpcErrorMessage as t };
20
- //# sourceMappingURL=extractRpcErrorMessage-pP3v8kKE.js.map
20
+ //# sourceMappingURL=extractRpcErrorMessage-C_UbKgHL.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"extractRpcErrorMessage-pP3v8kKE.js","names":[],"sources":["../src/utils/extractRpcErrorMessage.ts"],"sourcesContent":["/**\n * Extracts a user-friendly error message from RPC/API errors.\n * Handles various error shapes: Error instances, nested RPC payloads, etc.\n */\nexport function extractRpcErrorMessage(error: unknown, fallback = 'An unknown error occurred.'): string {\n if (error instanceof Error && error.message) {\n return error.message;\n }\n if (typeof error === 'object' && error !== null) {\n const obj = error as Record<string, unknown>;\n // RPC errors may nest: { error: { error_message: '...' } }\n const inner = obj.error as Record<string, unknown> | undefined;\n if (inner && typeof inner === 'object' && typeof inner.error_message === 'string') {\n return inner.error_message;\n }\n if (typeof obj.error_message === 'string') {\n return obj.error_message;\n }\n if (typeof obj.message === 'string') {\n return obj.message;\n }\n }\n return fallback;\n}\n"],"mappings":";;;;;AAIA,SAAgB,uBAAuB,OAAgB,WAAW,8BAAsC;AACtG,KAAI,iBAAiB,SAAS,MAAM,QAClC,QAAO,MAAM;AAEf,KAAI,OAAO,UAAU,YAAY,UAAU,MAAM;EAC/C,MAAM,MAAM;EAEZ,MAAM,QAAQ,IAAI;AAClB,MAAI,SAAS,OAAO,UAAU,YAAY,OAAO,MAAM,kBAAkB,SACvE,QAAO,MAAM;AAEf,MAAI,OAAO,IAAI,kBAAkB,SAC/B,QAAO,IAAI;AAEb,MAAI,OAAO,IAAI,YAAY,SACzB,QAAO,IAAI;;AAGf,QAAO"}
1
+ {"version":3,"file":"extractRpcErrorMessage-C_UbKgHL.js","names":[],"sources":["../src/utils/extractRpcErrorMessage.ts"],"sourcesContent":["/**\n * Extracts a user-friendly error message from RPC/API errors.\n * Handles various error shapes: Error instances, nested RPC payloads, etc.\n */\nexport function extractRpcErrorMessage(error: unknown, fallback = 'An unknown error occurred.'): string {\n if (error instanceof Error && error.message) {\n return error.message;\n }\n if (typeof error === 'object' && error !== null) {\n const obj = error as Record<string, unknown>;\n // RPC errors may nest: { error: { error_message: '...' } }\n const inner = obj.error as Record<string, unknown> | undefined;\n if (inner && typeof inner === 'object' && typeof inner.error_message === 'string') {\n return inner.error_message;\n }\n if (typeof obj.error_message === 'string') {\n return obj.error_message;\n }\n if (typeof obj.message === 'string') {\n return obj.message;\n }\n }\n return fallback;\n}\n"],"mappings":";;;;;AAIA,SAAgB,uBAAuB,OAAgB,WAAW,8BAAsC;AACtG,KAAI,iBAAiB,SAAS,MAAM,QAClC,QAAO,MAAM;AAEf,KAAI,OAAO,UAAU,YAAY,UAAU,MAAM;EAC/C,MAAM,MAAM;EAEZ,MAAM,QAAQ,IAAI;AAClB,MAAI,SAAS,OAAO,UAAU,YAAY,OAAO,MAAM,kBAAkB,SACvE,QAAO,MAAM;AAEf,MAAI,OAAO,IAAI,kBAAkB,SAC/B,QAAO,IAAI;AAEb,MAAI,OAAO,IAAI,YAAY,SACzB,QAAO,IAAI;;AAGf,QAAO"}