@dragonmastery/dragoncore-vue 0.0.30 → 0.0.31

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 (119) hide show
  1. package/dist/{ConsentFlowStep-DsVhXa91.js → ConsentRequired-Bhkxu0rv.js} +119 -11
  2. package/dist/ConsentRequired-Bhkxu0rv.js.map +1 -0
  3. package/dist/{CreateTeamForm-5V_ks5Ie.js → CreateTeamForm-BHgTTHAk.js} +2 -2
  4. package/dist/{CreateTeamForm-B7MsOsiV.js → CreateTeamForm-bpLbK18g.js} +2 -2
  5. package/dist/{CreateTeamForm-B7MsOsiV.js.map → CreateTeamForm-bpLbK18g.js.map} +1 -1
  6. package/dist/{CreateUserPage-DNi45YF4.js → CreateUserPage-C9uOeYDJ.js} +1 -1
  7. package/dist/{CreateUserPage-1WiLNGr_.js → CreateUserPage-CqKcY7_X.js} +1 -1
  8. package/dist/{CreateUserPage-1WiLNGr_.js.map → CreateUserPage-CqKcY7_X.js.map} +1 -1
  9. package/dist/{CreditBalanceDashboard-CoIEyZWh.js → CreditBalanceDashboard-BEsOr0Rw.js} +2 -2
  10. package/dist/{CreditBalanceDashboard-CoIEyZWh.js.map → CreditBalanceDashboard-BEsOr0Rw.js.map} +1 -1
  11. package/dist/{CreditBalanceDashboard-D_TsFlTp.js → CreditBalanceDashboard-DZQqekKa.js} +4 -4
  12. package/dist/{CreditManagement-CdkqQM7F.js → CreditManagement-ByFH6IHV.js} +4 -4
  13. package/dist/{CreditManagement-CCyU_yja.js → CreditManagement-DiVSMbWZ.js} +2 -2
  14. package/dist/{CreditManagement-CCyU_yja.js.map → CreditManagement-DiVSMbWZ.js.map} +1 -1
  15. package/dist/{CreditTransactionHistory-UPg9uDNy.js → CreditTransactionHistory-mcacl2xG.js} +2 -2
  16. package/dist/{CreditTransactionHistory-UPg9uDNy.js.map → CreditTransactionHistory-mcacl2xG.js.map} +1 -1
  17. package/dist/{CustomerCreateSupportTicketForm-CiTTUqtW.js → CustomerCreateSupportTicketForm-CroUyX15.js} +3 -3
  18. package/dist/{CustomerCreateSupportTicketForm-DFH1JtlA.js → CustomerCreateSupportTicketForm-IefplMnK.js} +2 -2
  19. package/dist/{CustomerCreateSupportTicketForm-DFH1JtlA.js.map → CustomerCreateSupportTicketForm-IefplMnK.js.map} +1 -1
  20. package/dist/{CustomerSupportTicketDetailPage-DAwiE2t6.js → CustomerSupportTicketDetailPage-Dengb4Zx.js} +2 -2
  21. package/dist/{CustomerSupportTicketDetailPage-DAwiE2t6.js.map → CustomerSupportTicketDetailPage-Dengb4Zx.js.map} +1 -1
  22. package/dist/{CustomerSupportTicketList-CKZl8jxx.js → CustomerSupportTicketList-CpOaBgNr.js} +30 -30
  23. package/dist/{CustomerSupportTicketSuccess-BJO2xsQR.js → CustomerSupportTicketSuccess-BPUwEn4h.js} +3 -3
  24. package/dist/{CustomerSupportTicketSuccess-BEhFZgtn.js → CustomerSupportTicketSuccess-RQskseXP.js} +2 -2
  25. package/dist/{CustomerSupportTicketSuccess-BEhFZgtn.js.map → CustomerSupportTicketSuccess-RQskseXP.js.map} +1 -1
  26. package/dist/{DefaultReferralTeamPage-D3UIrIZK.js → DefaultReferralTeamPage-Be7-RI3s.js} +1 -1
  27. package/dist/{DefaultReferralTeamPage-D3UIrIZK.js.map → DefaultReferralTeamPage-Be7-RI3s.js.map} +1 -1
  28. package/dist/{EditTeamForm-Bf4rSgQg.js → EditTeamForm-KX2cNn24.js} +2 -2
  29. package/dist/{EditTeamForm-C1_-p3lZ.js → EditTeamForm-RBO99ocN.js} +2 -2
  30. package/dist/{EditTeamForm-C1_-p3lZ.js.map → EditTeamForm-RBO99ocN.js.map} +1 -1
  31. package/dist/{EditUserPage-CQgp-08o.js → EditUserPage-AcRFhChk.js} +1 -1
  32. package/dist/{EditUserPage-CwsO8naT.js → EditUserPage-DGuV8pzp.js} +1 -1
  33. package/dist/{EditUserPage-CwsO8naT.js.map → EditUserPage-DGuV8pzp.js.map} +1 -1
  34. package/dist/{ForgotPassword-Dd-E3_o1.js → ForgotPassword-DZ-d8rWX.js} +2 -2
  35. package/dist/{ForgotPassword-Dd-E3_o1.js.map → ForgotPassword-DZ-d8rWX.js.map} +1 -1
  36. package/dist/{ForgotPassword-BhmO5Lfd.js → ForgotPassword-LnjRUIY7.js} +1 -1
  37. package/dist/{LoginForm-CFADKiln.js → LoginForm-D-gfB2hS.js} +1 -1
  38. package/dist/{LoginForm-CSMHsZrq.js → LoginForm-DEgTB9RF.js} +2 -2
  39. package/dist/{LoginForm-CSMHsZrq.js.map → LoginForm-DEgTB9RF.js.map} +1 -1
  40. package/dist/{Logout-Bdktl4NZ.js → Logout-Bb2xe5BM.js} +2 -2
  41. package/dist/{Logout-Bdktl4NZ.js.map → Logout-Bb2xe5BM.js.map} +1 -1
  42. package/dist/{Logout-CmKJK14I.js → Logout-Ctq-a1GS.js} +1 -1
  43. package/dist/{MfaSetup-BtfQXhLn.js → MfaSetup-6E6apXWC.js} +2 -2
  44. package/dist/{MfaSetup-Bjc3v0hs.js → MfaSetup-m080C6iX.js} +3 -3
  45. package/dist/{MfaSetup-Bjc3v0hs.js.map → MfaSetup-m080C6iX.js.map} +1 -1
  46. package/dist/{MfaVerify-SUfSRf4m.js → MfaVerify-C95WB9v2.js} +2 -2
  47. package/dist/{MfaVerify-uJlPz8xg.js → MfaVerify-D8Ch-8hN.js} +3 -3
  48. package/dist/{MfaVerify-uJlPz8xg.js.map → MfaVerify-D8Ch-8hN.js.map} +1 -1
  49. package/dist/{ResetPassword-Dz2N3pH4.js → ResetPassword-9DFz-Qt3.js} +1 -1
  50. package/dist/{ResetPassword-CyizBRob.js → ResetPassword-DflPd8Qg.js} +2 -2
  51. package/dist/{ResetPassword-CyizBRob.js.map → ResetPassword-DflPd8Qg.js.map} +1 -1
  52. package/dist/{SavedFiltersPage-Cz01ZeHx.js → SavedFiltersPage-ey8wOr0T.js} +31 -31
  53. package/dist/{SavedFiltersPage-Cz01ZeHx.js.map → SavedFiltersPage-ey8wOr0T.js.map} +1 -1
  54. package/dist/Signup-C052ykf5.js +9 -0
  55. package/dist/{Signup-CkhRQErA.js → Signup-KuiKHB4h.js} +22 -30
  56. package/dist/Signup-KuiKHB4h.js.map +1 -0
  57. package/dist/{SignupRequirementsPage-33z--rhH.js → SignupRequirementsPage-CwnsnQKb.js} +1 -1
  58. package/dist/{SignupRequirementsPage-33z--rhH.js.map → SignupRequirementsPage-CwnsnQKb.js.map} +1 -1
  59. package/dist/{StaffCreateSupportTicketForm-BtR-Aowv.js → StaffCreateSupportTicketForm-75Bo0jdz.js} +2 -2
  60. package/dist/{StaffCreateSupportTicketForm-BtR-Aowv.js.map → StaffCreateSupportTicketForm-75Bo0jdz.js.map} +1 -1
  61. package/dist/{StaffCreateSupportTicketForm-D7ctCaXe.js → StaffCreateSupportTicketForm-DYEddYii.js} +3 -3
  62. package/dist/{StaffSupportTicketDetailPage-LqnNfU34.js → StaffSupportTicketDetailPage-6VyPNdw7.js} +2 -2
  63. package/dist/{StaffSupportTicketDetailPage-LqnNfU34.js.map → StaffSupportTicketDetailPage-6VyPNdw7.js.map} +1 -1
  64. package/dist/{StaffSupportTicketList-GyzlONKe.js → StaffSupportTicketList-CxV6u2gF.js} +30 -30
  65. package/dist/{StaffSupportTicketSuccess-B3N-RMoT.js → StaffSupportTicketSuccess-BYoBXx1i.js} +2 -2
  66. package/dist/{StaffSupportTicketSuccess-B3N-RMoT.js.map → StaffSupportTicketSuccess-BYoBXx1i.js.map} +1 -1
  67. package/dist/{StaffSupportTicketSuccess-DvonYilY.js → StaffSupportTicketSuccess-FfnJXc_k.js} +3 -3
  68. package/dist/{SupportStaffPage-geoITTqt.js → SupportStaffPage-CLxWU628.js} +1 -1
  69. package/dist/{SupportStaffPage-geoITTqt.js.map → SupportStaffPage-CLxWU628.js.map} +1 -1
  70. package/dist/{SupportTicketMaintenancePage-CEKi8xQB.js → SupportTicketMaintenancePage-B07avInx.js} +1 -1
  71. package/dist/{SupportTicketMaintenancePage-CEKi8xQB.js.map → SupportTicketMaintenancePage-B07avInx.js.map} +1 -1
  72. package/dist/{TeamAttachmentsTab-ChP4DaUP.js → TeamAttachmentsTab-D0DOmdnr.js} +30 -30
  73. package/dist/{TeamList-_SsqJicG.js → TeamList-DXQj_Omo.js} +2 -2
  74. package/dist/{TeamList-_SsqJicG.js.map → TeamList-DXQj_Omo.js.map} +1 -1
  75. package/dist/{TeamList-cp8Pa2xg.js → TeamList-hmP44hfw.js} +2 -2
  76. package/dist/{TeamParent-BUnqP-dr.js → TeamParent-6JhqsYaO.js} +2 -2
  77. package/dist/{TeamParent-BUnqP-dr.js.map → TeamParent-6JhqsYaO.js.map} +1 -1
  78. package/dist/{TeamParent-BseZ6Zoi.js → TeamParent-BI9ItLoY.js} +2 -2
  79. package/dist/{TimelineNoteInput-BBZv3X4p.js → TimelineNoteInput-P3ycD18j.js} +1 -1
  80. package/dist/{TimelineNoteInput-BBZv3X4p.js.map → TimelineNoteInput-P3ycD18j.js.map} +1 -1
  81. package/dist/UserListPage-9jhUu3TH.js +5 -0
  82. package/dist/{UserListPage-CDMSZpXK.js → UserListPage-DelzxCID.js} +1 -1
  83. package/dist/{UserListPage-CDMSZpXK.js.map → UserListPage-DelzxCID.js.map} +1 -1
  84. package/dist/{VerifyEmail-CWUhRA1o.js → VerifyEmail-Cy2s4yP0.js} +3 -3
  85. package/dist/{VerifyEmail-CWUhRA1o.js.map → VerifyEmail-Cy2s4yP0.js.map} +1 -1
  86. package/dist/{VerifyEmail-CLDngljq.js → VerifyEmail-DBKMZJMx.js} +2 -2
  87. package/dist/{ViewTeam-ttqX2In8.js → ViewTeam-ByZdYEJG.js} +2 -2
  88. package/dist/{ViewTeam-ttqX2In8.js.map → ViewTeam-ByZdYEJG.js.map} +1 -1
  89. package/dist/{ViewTeam-rLNxVgS2.js → ViewTeam-DEOe7wqT.js} +2 -2
  90. package/dist/{customerSupportTicketRoutes-C-DKBy5g.js → customerSupportTicketRoutes-DvfXGaSC.js} +6 -6
  91. package/dist/{customerSupportTicketRoutes-C-DKBy5g.js.map → customerSupportTicketRoutes-DvfXGaSC.js.map} +1 -1
  92. package/dist/index.d.ts +889 -894
  93. package/dist/index.js +31 -32
  94. package/dist/{mfaSchema-C6PatIbY.js → mfaSchema-Ukqzdyck.js} +1 -1
  95. package/dist/{mfaSchema-C6PatIbY.js.map → mfaSchema-Ukqzdyck.js.map} +1 -1
  96. package/dist/{saved_filter-C2N9l_a9.js → saved_filter-erjEgsdK.js} +2 -2
  97. package/dist/{saved_filter-C2N9l_a9.js.map → saved_filter-erjEgsdK.js.map} +1 -1
  98. package/dist/{src-C8B9TJiH.js → src-DSF_hIBe.js} +23 -56
  99. package/dist/src-DSF_hIBe.js.map +1 -0
  100. package/dist/{staffSupportTicketRoutes-CyMecWpC.js → staffSupportTicketRoutes-73ceKhL-.js} +6 -6
  101. package/dist/{staffSupportTicketRoutes-CyMecWpC.js.map → staffSupportTicketRoutes-73ceKhL-.js.map} +1 -1
  102. package/dist/{teamRoutes-CFDsHPkd.js → teamRoutes-CSBq1DNq.js} +7 -7
  103. package/dist/{teamRoutes-CFDsHPkd.js.map → teamRoutes-CSBq1DNq.js.map} +1 -1
  104. package/dist/{useEmailVerificationChannel-QuMSgzzM.js → useEmailVerificationChannel-C76Gnyi1.js} +2 -2
  105. package/dist/{useEmailVerificationChannel-QuMSgzzM.js.map → useEmailVerificationChannel-C76Gnyi1.js.map} +1 -1
  106. package/dist/{useReturnUrl-B5V3SJf5.js → useReturnUrl-DnezAxBA.js} +2 -10
  107. package/dist/{useReturnUrl-B5V3SJf5.js.map → useReturnUrl-DnezAxBA.js.map} +1 -1
  108. package/package.json +2 -2
  109. package/dist/ConsentFlowStep-DsVhXa91.js.map +0 -1
  110. package/dist/ConsentRequired-B3eLxJgx.js +0 -114
  111. package/dist/ConsentRequired-B3eLxJgx.js.map +0 -1
  112. package/dist/Signup-CkhRQErA.js.map +0 -1
  113. package/dist/Signup-cOvXCtJj.js +0 -9
  114. package/dist/SignupConsentFlow-CKMFsnf5.js +0 -223
  115. package/dist/SignupConsentFlow-CKMFsnf5.js.map +0 -1
  116. package/dist/UserListPage-BABli3QG.js +0 -5
  117. package/dist/signupConsentStorage-pWSoHuhO.js +0 -35
  118. package/dist/signupConsentStorage-pWSoHuhO.js.map +0 -1
  119. package/dist/src-C8B9TJiH.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"TimelineNoteInput-BBZv3X4p.js","names":["events: SystemEvent[]","collectedChanges: Array<{\n action: string;\n oldValue: string | null;\n newValue: string | null;\n fieldName: string;\n }>","map: Record<AlertVariant, string>","copyTimeoutId: ReturnType<typeof setTimeout> | null"],"sources":["../src/slices/support_ticket/shared/SupportTicketAttachmentsCollapsible.vue","../src/slices/support_ticket/utils/parseRecordVersions.ts","../src/slices/support_ticket/shared/ActionBannerAlert.vue","../src/slices/support_ticket/shared/MetadataField.vue","../src/slices/support_ticket/shared/timelineNoteFormMetadata.ts","../src/slices/support_ticket/shared/TimelineNoteInput.vue"],"sourcesContent":["<template>\n <div v-if=\"recordId\" class=\"w-full\">\n <div class=\"collapse collapse-arrow bg-base-200\">\n <input type=\"checkbox\" v-model=\"attachmentsExpanded\" />\n <div class=\"collapse-title text-sm font-medium px-4 py-2 min-h-0\">\n <div class=\"flex items-center gap-2\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n class=\"h-4 w-4\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M15.172 7l-6.586 6.586a2 2 0 102.828 2.828l6.414-6.586a4 4 0 00-5.656-5.656l-6.415 6.585a6 6 0 108.486 8.486L20.5 13\"\n />\n </svg>\n <span>Attachments ({{ attachmentsCount }})</span>\n </div>\n </div>\n <div class=\"collapse-content px-0\">\n <div class=\"px-4 pb-4\">\n <InlineAttachments\n :record-id=\"recordId\"\n :can-upload=\"editable && !locked\"\n :can-delete=\"editable && !locked\"\n @update:attachments-count=\"attachmentsCount = $event\"\n @uploaded=\"emit('uploaded')\"\n @deleted=\"emit('deleted')\"\n />\n </div>\n </div>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport InlineAttachments from './InlineAttachments.vue';\n\nconst attachmentsCount = ref(0);\n\ninterface Props {\n recordId: string;\n locked: boolean;\n editable: boolean;\n}\n\ndefineProps<Props>();\n\nconst emit = defineEmits<{ uploaded: []; deleted: [] }>();\n\nconst attachmentsExpanded = ref(false);\n</script>\n","import {\n supportTicketNumberToPriority,\n type RecordVersionReadDto,\n} from '@dragonmastery/dragoncore-shared';\nimport { formatTicketDate } from './formatTicketDate';\n\nexport interface SystemEventChange {\n action: string;\n oldValue: string | null;\n newValue: string | null;\n fieldName?: string;\n}\n\nexport interface SystemEvent {\n id: string;\n timestamp: string;\n author: string;\n message: string;\n /** When set, used for structured display: action (italic) + type (badge) + details */\n action?: string;\n type?: string | null;\n details?: string | null;\n oldValue?: string | null;\n newValue?: string | null;\n fieldName?: string; // Field name that changed (for filtering)\n /** When multiple fields changed in same record version, grouped changes */\n changes?: SystemEventChange[];\n}\n\nconst SKIP_FIELDS = new Set(['updated_at', 'updated_by', 'id', 'display_id']);\n\n/** Fields that store user IDs - display names from lookup instead of raw IDs */\nconst USER_ID_FIELDS = new Set([\n 'assigned_to',\n 'created_by',\n 'updated_by',\n 'archived_by',\n 'deleted_by',\n]);\n\nfunction truncate(value: string, maxLength: number = 50): string {\n if (value.length <= maxLength) return value;\n return value.substring(0, maxLength) + '...';\n}\n\nfunction formatEnumValue(value: string): string {\n return value\n .split('_')\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join(' ');\n}\n\nfunction formatFieldValue(\n fieldName: string,\n value: unknown,\n truncateLong: boolean = false,\n displayMap?: Map<string, string>,\n): string {\n if (value === null || value === undefined) return '';\n if (typeof value === 'string' && /^\\d{4}-\\d{2}-\\d{2}/.test(value)) {\n return formatTicketDate(value).formatted;\n }\n if (typeof value === 'boolean') return value ? 'Yes' : 'No';\n // User ID fields: display name from lookup when available\n if (typeof value === 'string' && USER_ID_FIELDS.has(fieldName) && displayMap) {\n return displayMap.get(value) ?? value;\n }\n // Priority: DB stores number (1-4), record_versions may have legacy string or new number\n if (fieldName === 'priority') {\n if (typeof value === 'number') {\n return formatEnumValue(supportTicketNumberToPriority(value));\n }\n if (typeof value === 'string') return formatEnumValue(value);\n }\n if (typeof value === 'string') {\n if (\n fieldName.includes('status') ||\n fieldName.includes('type') ||\n fieldName.includes('lifecycle')\n ) {\n return formatEnumValue(value);\n }\n // Truncate title and description\n if (truncateLong && (fieldName === 'title' || fieldName === 'description')) {\n return truncate(value);\n }\n }\n return String(value);\n}\n\nfunction generateActionMessage(\n fieldName: string,\n oldValue: unknown,\n newValue: unknown,\n): string {\n switch (fieldName) {\n case 'assigned_to':\n if (oldValue === null || oldValue === undefined) return 'assigned to';\n return 'reassigned to';\n case 'title':\n return 'changed the title';\n case 'description':\n return 'updated the description';\n case 'type':\n return 'changed type';\n case 'priority':\n return 'changed priority';\n case 'approval_status':\n return 'changed status';\n case 'dev_lifecycle':\n return 'moved';\n case 'credit_value':\n if (oldValue === null || oldValue === undefined) return 'set credits';\n return 'changed credits';\n case 'delivered_value':\n if (oldValue === null || oldValue === undefined) return 'set delivered value';\n return 'changed delivered value';\n case 'start_at':\n if (oldValue === null || oldValue === undefined) return 'set start date';\n if (newValue === null || newValue === undefined) return 'cleared start date';\n return 'changed start date';\n case 'target_at':\n if (oldValue === null || oldValue === undefined) return 'set target date';\n if (newValue === null || newValue === undefined) return 'cleared target date';\n return 'changed target date';\n case 'completed_at':\n if (oldValue === null || oldValue === undefined) return 'marked as completed';\n if (newValue === null || newValue === undefined) return 'cleared completed date';\n return 'changed completed date';\n case 'locked_approval_at':\n if (\n oldValue === null ||\n (oldValue === undefined && newValue !== null && newValue !== undefined)\n ) {\n return 'locked the ticket';\n }\n return 'changed lock status';\n case 'archived_at':\n if (\n oldValue === null ||\n (oldValue === undefined && newValue !== null && newValue !== undefined)\n ) {\n return 'archived the ticket';\n }\n if (\n oldValue !== null &&\n oldValue !== undefined &&\n (newValue === null || newValue === undefined)\n ) {\n return 'unarchived the ticket';\n }\n return 'changed archive status';\n case 'requester_email':\n return 'changed requester email';\n case 'requester_name':\n return 'changed requester name';\n case 'attachment_added':\n return 'added attachment';\n case 'attachment_removed':\n return 'removed attachment';\n default:\n return `updated ${fieldName.replace(/_/g, ' ')}`;\n }\n}\n\nfunction parseRecord(recordJson: string | null | undefined): Record<string, unknown> | null {\n if (!recordJson) return null;\n try {\n return JSON.parse(recordJson);\n } catch {\n return null;\n }\n}\n\nexport function parseRecordVersions(\n versions: RecordVersionReadDto[],\n displayMap?: Map<string, string>,\n): SystemEvent[] {\n const events: SystemEvent[] = [];\n\n for (const version of versions) {\n const author = version.auth_username || 'Unknown';\n const timestamp = version.recorded_at;\n\n if (version.operation === 'insert') {\n events.push({\n id: `${version.id}-insert`,\n timestamp,\n author,\n message: 'created this ticket',\n action: 'created',\n type: 'ticket',\n });\n continue;\n }\n\n if (version.operation === 'update') {\n const oldRecord = parseRecord(version.old_record);\n const newRecord = parseRecord(version.record);\n\n if (!oldRecord || !newRecord) continue;\n\n const collectedChanges: Array<{\n action: string;\n oldValue: string | null;\n newValue: string | null;\n fieldName: string;\n }> = [];\n\n for (const [fieldName, newValue] of Object.entries(newRecord)) {\n if (SKIP_FIELDS.has(fieldName)) continue;\n\n const oldValue = oldRecord[fieldName];\n\n if (oldValue !== newValue) {\n const oldFormatted =\n oldValue !== null && oldValue !== undefined\n ? formatFieldValue(fieldName, oldValue, true, displayMap)\n : null;\n const newFormatted =\n newValue !== null && newValue !== undefined\n ? formatFieldValue(fieldName, newValue, true, displayMap)\n : null;\n\n const actionMsg = generateActionMessage(fieldName, oldValue, newValue);\n\n collectedChanges.push({\n action: actionMsg,\n oldValue: oldFormatted || null,\n newValue: newFormatted || null,\n fieldName,\n });\n }\n }\n\n if (collectedChanges.length > 0) {\n const primaryChange = collectedChanges[0]!;\n const details =\n primaryChange.oldValue != null && primaryChange.newValue != null\n ? `${primaryChange.oldValue} → ${primaryChange.newValue}`\n : primaryChange.newValue ?? null;\n\n events.push({\n id: version.id,\n timestamp,\n author,\n message: primaryChange.action,\n action: collectedChanges.length === 1 ? primaryChange.action : 'updated',\n type: 'ticket',\n details: collectedChanges.length === 1 ? details : null,\n oldValue: collectedChanges.length === 1 ? primaryChange.oldValue : undefined,\n newValue: collectedChanges.length === 1 ? primaryChange.newValue : undefined,\n fieldName: collectedChanges.length === 1 ? primaryChange.fieldName : undefined,\n changes:\n collectedChanges.length > 1\n ? collectedChanges.map((c) => ({\n action: c.action,\n oldValue: c.oldValue,\n newValue: c.newValue,\n fieldName: c.fieldName,\n }))\n : undefined,\n });\n }\n }\n }\n\n events.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());\n return events;\n}\n","<template>\n <div\n role=\"alert\"\n :class=\"[\n 'py-3 px-4 w-full rounded-lg border border-base-300 border-l-4 bg-base-200/60',\n variantBorderClass,\n ]\"\n >\n <!-- Mobile-first: stack vertically on small screens, row on desktop -->\n <div\n class=\"flex flex-col gap-3 sm:flex-row sm:items-center sm:gap-3\"\n >\n <div class=\"flex items-start gap-3 min-w-0\">\n <component :is=\"iconComponent\" v-if=\"icon\" class=\"shrink-0 w-5 h-5 opacity-90 mt-0.5\" />\n <span class=\"flex-1 min-w-0\">\n <slot />\n </span>\n </div>\n <div\n v-if=\"hasActions\"\n class=\"grid grid-cols-2 gap-2 sm:flex sm:flex-row sm:flex-wrap sm:ml-auto sm:shrink-0 sm:[&>*]:w-auto\"\n >\n <slot name=\"actions\" />\n </div>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, useSlots, h } from 'vue';\n\ntype AlertVariant = 'warning' | 'success' | 'error' | 'info' | 'neutral';\ntype IconType = 'lock' | 'clock' | 'info' | 'archive';\n\ninterface Props {\n variant: AlertVariant;\n icon?: IconType;\n}\n\nconst props = defineProps<Props>();\n\nconst slots = useSlots();\n\nconst variantBorderClass = computed(() => {\n const map: Record<AlertVariant, string> = {\n warning: 'border-l-warning',\n success: 'border-l-success',\n error: 'border-l-error',\n info: 'border-l-info',\n neutral: 'border-l-base-content/30',\n };\n return map[props.variant];\n});\n\nconst hasActions = computed(() => {\n const actionsSlot = slots.actions;\n if (!actionsSlot) return false;\n const vnodes = actionsSlot();\n return !!vnodes?.length;\n});\n\nconst iconComponent = computed(() => {\n if (!props.icon) return null;\n const icons = {\n lock: () =>\n h(\n 'svg',\n {\n xmlns: 'http://www.w3.org/2000/svg',\n fill: 'none',\n viewBox: '0 0 24 24',\n 'stroke-width': '1.5',\n stroke: 'currentColor',\n class: 'w-5 h-5',\n },\n [\n h('path', {\n 'stroke-linecap': 'round',\n 'stroke-linejoin': 'round',\n d: 'M16.5 10.5V6.75a4.5 4.5 0 10-9 0v3.75m-.75 11.25h10.5a2.25 2.25 0 002.25-2.25v-6.75a2.25 2.25 0 00-2.25-2.25H6.75a2.25 2.25 0 00-2.25 2.25v6.75a2.25 2.25 0 002.25 2.25z',\n }),\n ],\n ),\n clock: () =>\n h(\n 'svg',\n {\n xmlns: 'http://www.w3.org/2000/svg',\n fill: 'none',\n viewBox: '0 0 24 24',\n 'stroke-width': '1.5',\n stroke: 'currentColor',\n class: 'w-5 h-5',\n },\n [\n h('path', {\n 'stroke-linecap': 'round',\n 'stroke-linejoin': 'round',\n d: 'M12 6v6h4.5m4.5 0a9 9 0 11-18 0 9 9 0 0118 0z',\n }),\n ],\n ),\n info: () =>\n h(\n 'svg',\n {\n xmlns: 'http://www.w3.org/2000/svg',\n fill: 'none',\n viewBox: '0 0 24 24',\n 'stroke-width': '1.5',\n stroke: 'currentColor',\n class: 'w-5 h-5',\n },\n [\n h('path', {\n 'stroke-linecap': 'round',\n 'stroke-linejoin': 'round',\n d: 'M11.25 11.25l.041-.02a.75.75 0 011.063.852l-.708 2.836a.75.75 0 001.063.853l.041-.021M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-9-3.75h.008v.008H12V8.25z',\n }),\n ],\n ),\n archive: () =>\n h(\n 'svg',\n {\n xmlns: 'http://www.w3.org/2000/svg',\n fill: 'none',\n viewBox: '0 0 24 24',\n 'stroke-width': '1.5',\n stroke: 'currentColor',\n class: 'w-5 h-5',\n },\n [\n h('path', {\n 'stroke-linecap': 'round',\n 'stroke-linejoin': 'round',\n d: 'M20.25 7.5l-.625 10.632a2.25 2.25 0 01-2.247 2.118H6.622a2.25 2.25 0 01-2.247-2.118L3.75 7.5M10 11.25h4M3.375 7.5h17.25c.621 0 1.125-.504 1.125-1.125v-1.5c0-.621-.504-1.125-1.125-1.125H3.375c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125z',\n }),\n ],\n ),\n };\n return icons[props.icon] ?? null;\n});\n</script>\n","<template>\n <div class=\"flex flex-col\">\n <span class=\"text-xs font-semibold uppercase tracking-wide text-base-content/50 mb-0.5\">\n {{ label }}\n </span>\n <template v-if=\"hasContent\">\n <span\n v-if=\"copyable\"\n ref=\"valueRef\"\n role=\"button\"\n tabindex=\"0\"\n class=\"font-mono cursor-pointer select-all\"\n @click=\"handleCopy\"\n @keydown.enter=\"handleCopy\"\n @keydown.space.prevent=\"handleCopy\"\n >\n {{ copied ? 'Copied!' : undefined }}\n <template v-if=\"!copied\"><slot /></template>\n </span>\n <span v-else>\n <slot />\n </span>\n </template>\n <template v-else>\n <slot name=\"empty\">\n <span class=\"text-base-content/50 italic text-sm\">Not set</span>\n </slot>\n </template>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { Comment } from 'vue';\nimport { ref, computed, useSlots } from 'vue';\n\ninterface Props {\n label: string;\n copyable?: boolean;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n copyable: false,\n});\n\nconst slots = useSlots();\nconst valueRef = ref<HTMLSpanElement | null>(null);\nconst copied = ref(false);\nlet copyTimeoutId: ReturnType<typeof setTimeout> | null = null;\n\nconst hasContent = computed(() => {\n const defaultSlot = slots.default;\n if (!defaultSlot) return false;\n const vnodes = defaultSlot();\n if (!vnodes || !Array.isArray(vnodes)) return false;\n return vnodes.some((v) => v.type !== Comment);\n});\n\nasync function handleCopy() {\n if (!props.copyable) return;\n const text = valueRef.value?.textContent?.trim();\n if (!text) return;\n try {\n await navigator.clipboard.writeText(text);\n copied.value = true;\n if (copyTimeoutId) clearTimeout(copyTimeoutId);\n copyTimeoutId = setTimeout(() => {\n copied.value = false;\n copyTimeoutId = null;\n }, 1500);\n } catch {\n // ignore clipboard errors\n }\n}\n</script>\n","import { withMetadata } from '@dragonmastery/zinia-forms-core';\nimport { z } from 'zod';\n\n/** Schema for adding a comment/note on support ticket timeline. */\nconst TimelineNoteCreateSchema = z.object({\n body: z.string().min(1, 'Comment is required').trim(),\n is_internal: z.boolean().optional().default(false),\n});\n\nexport const timelineNoteCreateMetadata = withMetadata(\n TimelineNoteCreateSchema,\n 'timelineNoteCreateForm',\n {\n body: {\n label: 'Comment',\n placeholder: 'Add a comment...',\n inputType: 'textarea',\n },\n is_internal: {\n label: 'Internal Note',\n helpText: 'Internal notes are not visible to the customer',\n },\n },\n);\n\nexport type TimelineNoteCreateDto = z.infer<typeof TimelineNoteCreateSchema>;\n","<template>\n <div class=\"border-t border-base-200 pt-4 mt-4 w-full\">\n <template v-if=\"disabled\">\n <div class=\"bg-base-200/50 rounded-lg p-4 text-center\">\n <span class=\"text-base-content/50 text-sm inline-flex items-center gap-1.5\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke-width=\"1.5\"\n stroke=\"currentColor\"\n class=\"w-4 h-4\"\n >\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n d=\"M16.5 10.5V6.75a4.5 4.5 0 10-9 0v3.75m-.75 11.25h10.5a2.25 2.25 0 002.25-2.25v-6.75a2.25 2.25 0 00-2.25-2.25H6.75a2.25 2.25 0 00-2.25 2.25v6.75a2.25 2.25 0 002.25 2.25z\"\n />\n </svg>\n This ticket has been locked. You can no longer add comments.\n </span>\n </div>\n </template>\n <ZiniaForm\n v-else\n @handle-submit=\"handleSubmit\"\n @success=\"handleSuccess\"\n @error=\"handleError\"\n title=\"\"\n subtitle=\"\"\n >\n <div ref=\"formWrapperRef\" class=\"grid grid-cols-1 gap-4 w-full\" @keydown=\"handleKeydown\">\n <p\n v-if=\"showTypeToggle\"\n class=\"col-span-full text-xs mb-1\"\n :class=\"form.values.is_internal ? 'text-warning' : 'text-info'\"\n >\n {{\n form.values.is_internal\n ? '🔒 Internal — not visible to customer'\n : 'Visible to customer'\n }}\n </p>\n <div class=\"col-span-full\">\n <zinia.BodyField class=\"textarea w-full\" />\n </div>\n <div class=\"col-span-full flex flex-wrap gap-2 justify-between items-center\">\n <div v-if=\"showTypeToggle\" class=\"join\">\n <button\n type=\"button\"\n :class=\"[\n 'btn btn-sm join-item',\n !form.values.is_internal ? 'btn-info btn-active' : '',\n ]\"\n :disabled=\"form.isSubmitting\"\n @click=\"form.setValue('is_internal', false)\"\n >\n Customer Note\n </button>\n <button\n type=\"button\"\n :class=\"[\n 'btn btn-sm join-item',\n form.values.is_internal ? 'btn-warning btn-active' : '',\n ]\"\n :disabled=\"form.isSubmitting\"\n @click=\"form.setValue('is_internal', true)\"\n >\n Internal Note\n </button>\n </div>\n <div v-else></div>\n <ZiniaSubmitButton submitText=\"Comment\" submittingText=\"Adding...\" />\n </div>\n </div>\n </ZiniaForm>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { useForm } from '@dragonmastery/zinia-forms-core';\nimport { ref, watch } from 'vue';\nimport { timelineNoteCreateMetadata } from './timelineNoteFormMetadata';\n\ninterface Props {\n showTypeToggle: boolean;\n disabled: boolean;\n /** When provided, noteType is controlled (e.g. synced with URL query param) */\n noteType?: 'customer' | 'internal';\n /** Called when form submits with validated data. Must return a Promise. */\n onSubmit: (payload: { content: string; noteType: 'customer' | 'internal' }) => Promise<void>;\n}\n\nconst props = defineProps<Props>();\nconst formWrapperRef = ref<HTMLElement | null>(null);\n\nconst emit = defineEmits<{\n 'update:noteType': [value: 'customer' | 'internal'];\n}>();\n\nconst { form, zinia, ZiniaForm, ZiniaSubmitButton, refreshFormData } = useForm(\n timelineNoteCreateMetadata,\n {\n storeName: 'timeline-note-input',\n persistToLocalStorage: false,\n renderStyle: 'daisy_ui',\n fetchData: async () => ({\n body: '',\n is_internal: props.noteType === 'internal',\n }),\n },\n);\n\n// Sync form's is_internal when controlled noteType prop changes (e.g. from URL)\nwatch(\n () => props.noteType,\n (noteType) => {\n if (noteType !== undefined) {\n form.setValue('is_internal', noteType === 'internal');\n }\n },\n { immediate: true },\n);\n\n// Emit when user toggles note type (for URL sync in StaffTimeline)\nwatch(\n () => form.values.is_internal,\n (isInternal) => {\n if (props.showTypeToggle) {\n emit('update:noteType', isInternal ? 'internal' : 'customer');\n }\n },\n);\n\nfunction handleKeydown(e: KeyboardEvent) {\n if ((e.ctrlKey || e.metaKey) && e.key === 'Enter') {\n e.preventDefault();\n const form = formWrapperRef.value?.closest('form');\n form?.requestSubmit();\n }\n}\n\nasync function handleSubmit(formData: { body: string; is_internal: boolean }) {\n await props.onSubmit({\n content: (formData.body ?? '').trim(),\n noteType: props.showTypeToggle && formData.is_internal ? 'internal' : 'customer',\n });\n}\n\nfunction handleSuccess() {\n refreshFormData();\n (document.activeElement as HTMLElement)?.blur();\n}\n\nfunction handleError(_error: Error | unknown) {\n // Form displays errors via ZiniaFormErrorsSummary\n}\n\nfunction reset() {\n refreshFormData();\n}\n\ndefineExpose({ reset });\n</script>\n"],"mappings":"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"}
1
+ {"version":3,"file":"TimelineNoteInput-P3ycD18j.js","names":["events: SystemEvent[]","collectedChanges: Array<{\n action: string;\n oldValue: string | null;\n newValue: string | null;\n fieldName: string;\n }>","map: Record<AlertVariant, string>","copyTimeoutId: ReturnType<typeof setTimeout> | null"],"sources":["../src/slices/support_ticket/shared/SupportTicketAttachmentsCollapsible.vue","../src/slices/support_ticket/utils/parseRecordVersions.ts","../src/slices/support_ticket/shared/ActionBannerAlert.vue","../src/slices/support_ticket/shared/MetadataField.vue","../src/slices/support_ticket/shared/timelineNoteFormMetadata.ts","../src/slices/support_ticket/shared/TimelineNoteInput.vue"],"sourcesContent":["<template>\n <div v-if=\"recordId\" class=\"w-full\">\n <div class=\"collapse collapse-arrow bg-base-200\">\n <input type=\"checkbox\" v-model=\"attachmentsExpanded\" />\n <div class=\"collapse-title text-sm font-medium px-4 py-2 min-h-0\">\n <div class=\"flex items-center gap-2\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n class=\"h-4 w-4\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M15.172 7l-6.586 6.586a2 2 0 102.828 2.828l6.414-6.586a4 4 0 00-5.656-5.656l-6.415 6.585a6 6 0 108.486 8.486L20.5 13\"\n />\n </svg>\n <span>Attachments ({{ attachmentsCount }})</span>\n </div>\n </div>\n <div class=\"collapse-content px-0\">\n <div class=\"px-4 pb-4\">\n <InlineAttachments\n :record-id=\"recordId\"\n :can-upload=\"editable && !locked\"\n :can-delete=\"editable && !locked\"\n @update:attachments-count=\"attachmentsCount = $event\"\n @uploaded=\"emit('uploaded')\"\n @deleted=\"emit('deleted')\"\n />\n </div>\n </div>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport InlineAttachments from './InlineAttachments.vue';\n\nconst attachmentsCount = ref(0);\n\ninterface Props {\n recordId: string;\n locked: boolean;\n editable: boolean;\n}\n\ndefineProps<Props>();\n\nconst emit = defineEmits<{ uploaded: []; deleted: [] }>();\n\nconst attachmentsExpanded = ref(false);\n</script>\n","import {\n supportTicketNumberToPriority,\n type RecordVersionReadDto,\n} from '@dragonmastery/dragoncore-shared';\nimport { formatTicketDate } from './formatTicketDate';\n\nexport interface SystemEventChange {\n action: string;\n oldValue: string | null;\n newValue: string | null;\n fieldName?: string;\n}\n\nexport interface SystemEvent {\n id: string;\n timestamp: string;\n author: string;\n message: string;\n /** When set, used for structured display: action (italic) + type (badge) + details */\n action?: string;\n type?: string | null;\n details?: string | null;\n oldValue?: string | null;\n newValue?: string | null;\n fieldName?: string; // Field name that changed (for filtering)\n /** When multiple fields changed in same record version, grouped changes */\n changes?: SystemEventChange[];\n}\n\nconst SKIP_FIELDS = new Set(['updated_at', 'updated_by', 'id', 'display_id']);\n\n/** Fields that store user IDs - display names from lookup instead of raw IDs */\nconst USER_ID_FIELDS = new Set([\n 'assigned_to',\n 'created_by',\n 'updated_by',\n 'archived_by',\n 'deleted_by',\n]);\n\nfunction truncate(value: string, maxLength: number = 50): string {\n if (value.length <= maxLength) return value;\n return value.substring(0, maxLength) + '...';\n}\n\nfunction formatEnumValue(value: string): string {\n return value\n .split('_')\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join(' ');\n}\n\nfunction formatFieldValue(\n fieldName: string,\n value: unknown,\n truncateLong: boolean = false,\n displayMap?: Map<string, string>,\n): string {\n if (value === null || value === undefined) return '';\n if (typeof value === 'string' && /^\\d{4}-\\d{2}-\\d{2}/.test(value)) {\n return formatTicketDate(value).formatted;\n }\n if (typeof value === 'boolean') return value ? 'Yes' : 'No';\n // User ID fields: display name from lookup when available\n if (typeof value === 'string' && USER_ID_FIELDS.has(fieldName) && displayMap) {\n return displayMap.get(value) ?? value;\n }\n // Priority: DB stores number (1-4), record_versions may have legacy string or new number\n if (fieldName === 'priority') {\n if (typeof value === 'number') {\n return formatEnumValue(supportTicketNumberToPriority(value));\n }\n if (typeof value === 'string') return formatEnumValue(value);\n }\n if (typeof value === 'string') {\n if (\n fieldName.includes('status') ||\n fieldName.includes('type') ||\n fieldName.includes('lifecycle')\n ) {\n return formatEnumValue(value);\n }\n // Truncate title and description\n if (truncateLong && (fieldName === 'title' || fieldName === 'description')) {\n return truncate(value);\n }\n }\n return String(value);\n}\n\nfunction generateActionMessage(\n fieldName: string,\n oldValue: unknown,\n newValue: unknown,\n): string {\n switch (fieldName) {\n case 'assigned_to':\n if (oldValue === null || oldValue === undefined) return 'assigned to';\n return 'reassigned to';\n case 'title':\n return 'changed the title';\n case 'description':\n return 'updated the description';\n case 'type':\n return 'changed type';\n case 'priority':\n return 'changed priority';\n case 'approval_status':\n return 'changed status';\n case 'dev_lifecycle':\n return 'moved';\n case 'credit_value':\n if (oldValue === null || oldValue === undefined) return 'set credits';\n return 'changed credits';\n case 'delivered_value':\n if (oldValue === null || oldValue === undefined) return 'set delivered value';\n return 'changed delivered value';\n case 'start_at':\n if (oldValue === null || oldValue === undefined) return 'set start date';\n if (newValue === null || newValue === undefined) return 'cleared start date';\n return 'changed start date';\n case 'target_at':\n if (oldValue === null || oldValue === undefined) return 'set target date';\n if (newValue === null || newValue === undefined) return 'cleared target date';\n return 'changed target date';\n case 'completed_at':\n if (oldValue === null || oldValue === undefined) return 'marked as completed';\n if (newValue === null || newValue === undefined) return 'cleared completed date';\n return 'changed completed date';\n case 'locked_approval_at':\n if (\n oldValue === null ||\n (oldValue === undefined && newValue !== null && newValue !== undefined)\n ) {\n return 'locked the ticket';\n }\n return 'changed lock status';\n case 'archived_at':\n if (\n oldValue === null ||\n (oldValue === undefined && newValue !== null && newValue !== undefined)\n ) {\n return 'archived the ticket';\n }\n if (\n oldValue !== null &&\n oldValue !== undefined &&\n (newValue === null || newValue === undefined)\n ) {\n return 'unarchived the ticket';\n }\n return 'changed archive status';\n case 'requester_email':\n return 'changed requester email';\n case 'requester_name':\n return 'changed requester name';\n case 'attachment_added':\n return 'added attachment';\n case 'attachment_removed':\n return 'removed attachment';\n default:\n return `updated ${fieldName.replace(/_/g, ' ')}`;\n }\n}\n\nfunction parseRecord(recordJson: string | null | undefined): Record<string, unknown> | null {\n if (!recordJson) return null;\n try {\n return JSON.parse(recordJson);\n } catch {\n return null;\n }\n}\n\nexport function parseRecordVersions(\n versions: RecordVersionReadDto[],\n displayMap?: Map<string, string>,\n): SystemEvent[] {\n const events: SystemEvent[] = [];\n\n for (const version of versions) {\n const author = version.auth_username || 'Unknown';\n const timestamp = version.recorded_at;\n\n if (version.operation === 'insert') {\n events.push({\n id: `${version.id}-insert`,\n timestamp,\n author,\n message: 'created this ticket',\n action: 'created',\n type: 'ticket',\n });\n continue;\n }\n\n if (version.operation === 'update') {\n const oldRecord = parseRecord(version.old_record);\n const newRecord = parseRecord(version.record);\n\n if (!oldRecord || !newRecord) continue;\n\n const collectedChanges: Array<{\n action: string;\n oldValue: string | null;\n newValue: string | null;\n fieldName: string;\n }> = [];\n\n for (const [fieldName, newValue] of Object.entries(newRecord)) {\n if (SKIP_FIELDS.has(fieldName)) continue;\n\n const oldValue = oldRecord[fieldName];\n\n if (oldValue !== newValue) {\n const oldFormatted =\n oldValue !== null && oldValue !== undefined\n ? formatFieldValue(fieldName, oldValue, true, displayMap)\n : null;\n const newFormatted =\n newValue !== null && newValue !== undefined\n ? formatFieldValue(fieldName, newValue, true, displayMap)\n : null;\n\n const actionMsg = generateActionMessage(fieldName, oldValue, newValue);\n\n collectedChanges.push({\n action: actionMsg,\n oldValue: oldFormatted || null,\n newValue: newFormatted || null,\n fieldName,\n });\n }\n }\n\n if (collectedChanges.length > 0) {\n const primaryChange = collectedChanges[0]!;\n const details =\n primaryChange.oldValue != null && primaryChange.newValue != null\n ? `${primaryChange.oldValue} → ${primaryChange.newValue}`\n : primaryChange.newValue ?? null;\n\n events.push({\n id: version.id,\n timestamp,\n author,\n message: primaryChange.action,\n action: collectedChanges.length === 1 ? primaryChange.action : 'updated',\n type: 'ticket',\n details: collectedChanges.length === 1 ? details : null,\n oldValue: collectedChanges.length === 1 ? primaryChange.oldValue : undefined,\n newValue: collectedChanges.length === 1 ? primaryChange.newValue : undefined,\n fieldName: collectedChanges.length === 1 ? primaryChange.fieldName : undefined,\n changes:\n collectedChanges.length > 1\n ? collectedChanges.map((c) => ({\n action: c.action,\n oldValue: c.oldValue,\n newValue: c.newValue,\n fieldName: c.fieldName,\n }))\n : undefined,\n });\n }\n }\n }\n\n events.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());\n return events;\n}\n","<template>\n <div\n role=\"alert\"\n :class=\"[\n 'py-3 px-4 w-full rounded-lg border border-base-300 border-l-4 bg-base-200/60',\n variantBorderClass,\n ]\"\n >\n <!-- Mobile-first: stack vertically on small screens, row on desktop -->\n <div\n class=\"flex flex-col gap-3 sm:flex-row sm:items-center sm:gap-3\"\n >\n <div class=\"flex items-start gap-3 min-w-0\">\n <component :is=\"iconComponent\" v-if=\"icon\" class=\"shrink-0 w-5 h-5 opacity-90 mt-0.5\" />\n <span class=\"flex-1 min-w-0\">\n <slot />\n </span>\n </div>\n <div\n v-if=\"hasActions\"\n class=\"grid grid-cols-2 gap-2 sm:flex sm:flex-row sm:flex-wrap sm:ml-auto sm:shrink-0 sm:[&>*]:w-auto\"\n >\n <slot name=\"actions\" />\n </div>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, useSlots, h } from 'vue';\n\ntype AlertVariant = 'warning' | 'success' | 'error' | 'info' | 'neutral';\ntype IconType = 'lock' | 'clock' | 'info' | 'archive';\n\ninterface Props {\n variant: AlertVariant;\n icon?: IconType;\n}\n\nconst props = defineProps<Props>();\n\nconst slots = useSlots();\n\nconst variantBorderClass = computed(() => {\n const map: Record<AlertVariant, string> = {\n warning: 'border-l-warning',\n success: 'border-l-success',\n error: 'border-l-error',\n info: 'border-l-info',\n neutral: 'border-l-base-content/30',\n };\n return map[props.variant];\n});\n\nconst hasActions = computed(() => {\n const actionsSlot = slots.actions;\n if (!actionsSlot) return false;\n const vnodes = actionsSlot();\n return !!vnodes?.length;\n});\n\nconst iconComponent = computed(() => {\n if (!props.icon) return null;\n const icons = {\n lock: () =>\n h(\n 'svg',\n {\n xmlns: 'http://www.w3.org/2000/svg',\n fill: 'none',\n viewBox: '0 0 24 24',\n 'stroke-width': '1.5',\n stroke: 'currentColor',\n class: 'w-5 h-5',\n },\n [\n h('path', {\n 'stroke-linecap': 'round',\n 'stroke-linejoin': 'round',\n d: 'M16.5 10.5V6.75a4.5 4.5 0 10-9 0v3.75m-.75 11.25h10.5a2.25 2.25 0 002.25-2.25v-6.75a2.25 2.25 0 00-2.25-2.25H6.75a2.25 2.25 0 00-2.25 2.25v6.75a2.25 2.25 0 002.25 2.25z',\n }),\n ],\n ),\n clock: () =>\n h(\n 'svg',\n {\n xmlns: 'http://www.w3.org/2000/svg',\n fill: 'none',\n viewBox: '0 0 24 24',\n 'stroke-width': '1.5',\n stroke: 'currentColor',\n class: 'w-5 h-5',\n },\n [\n h('path', {\n 'stroke-linecap': 'round',\n 'stroke-linejoin': 'round',\n d: 'M12 6v6h4.5m4.5 0a9 9 0 11-18 0 9 9 0 0118 0z',\n }),\n ],\n ),\n info: () =>\n h(\n 'svg',\n {\n xmlns: 'http://www.w3.org/2000/svg',\n fill: 'none',\n viewBox: '0 0 24 24',\n 'stroke-width': '1.5',\n stroke: 'currentColor',\n class: 'w-5 h-5',\n },\n [\n h('path', {\n 'stroke-linecap': 'round',\n 'stroke-linejoin': 'round',\n d: 'M11.25 11.25l.041-.02a.75.75 0 011.063.852l-.708 2.836a.75.75 0 001.063.853l.041-.021M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-9-3.75h.008v.008H12V8.25z',\n }),\n ],\n ),\n archive: () =>\n h(\n 'svg',\n {\n xmlns: 'http://www.w3.org/2000/svg',\n fill: 'none',\n viewBox: '0 0 24 24',\n 'stroke-width': '1.5',\n stroke: 'currentColor',\n class: 'w-5 h-5',\n },\n [\n h('path', {\n 'stroke-linecap': 'round',\n 'stroke-linejoin': 'round',\n d: 'M20.25 7.5l-.625 10.632a2.25 2.25 0 01-2.247 2.118H6.622a2.25 2.25 0 01-2.247-2.118L3.75 7.5M10 11.25h4M3.375 7.5h17.25c.621 0 1.125-.504 1.125-1.125v-1.5c0-.621-.504-1.125-1.125-1.125H3.375c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125z',\n }),\n ],\n ),\n };\n return icons[props.icon] ?? null;\n});\n</script>\n","<template>\n <div class=\"flex flex-col\">\n <span class=\"text-xs font-semibold uppercase tracking-wide text-base-content/50 mb-0.5\">\n {{ label }}\n </span>\n <template v-if=\"hasContent\">\n <span\n v-if=\"copyable\"\n ref=\"valueRef\"\n role=\"button\"\n tabindex=\"0\"\n class=\"font-mono cursor-pointer select-all\"\n @click=\"handleCopy\"\n @keydown.enter=\"handleCopy\"\n @keydown.space.prevent=\"handleCopy\"\n >\n {{ copied ? 'Copied!' : undefined }}\n <template v-if=\"!copied\"><slot /></template>\n </span>\n <span v-else>\n <slot />\n </span>\n </template>\n <template v-else>\n <slot name=\"empty\">\n <span class=\"text-base-content/50 italic text-sm\">Not set</span>\n </slot>\n </template>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { Comment } from 'vue';\nimport { ref, computed, useSlots } from 'vue';\n\ninterface Props {\n label: string;\n copyable?: boolean;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n copyable: false,\n});\n\nconst slots = useSlots();\nconst valueRef = ref<HTMLSpanElement | null>(null);\nconst copied = ref(false);\nlet copyTimeoutId: ReturnType<typeof setTimeout> | null = null;\n\nconst hasContent = computed(() => {\n const defaultSlot = slots.default;\n if (!defaultSlot) return false;\n const vnodes = defaultSlot();\n if (!vnodes || !Array.isArray(vnodes)) return false;\n return vnodes.some((v) => v.type !== Comment);\n});\n\nasync function handleCopy() {\n if (!props.copyable) return;\n const text = valueRef.value?.textContent?.trim();\n if (!text) return;\n try {\n await navigator.clipboard.writeText(text);\n copied.value = true;\n if (copyTimeoutId) clearTimeout(copyTimeoutId);\n copyTimeoutId = setTimeout(() => {\n copied.value = false;\n copyTimeoutId = null;\n }, 1500);\n } catch {\n // ignore clipboard errors\n }\n}\n</script>\n","import { withMetadata } from '@dragonmastery/zinia-forms-core';\nimport { z } from 'zod';\n\n/** Schema for adding a comment/note on support ticket timeline. */\nconst TimelineNoteCreateSchema = z.object({\n body: z.string().min(1, 'Comment is required').trim(),\n is_internal: z.boolean().optional().default(false),\n});\n\nexport const timelineNoteCreateMetadata = withMetadata(\n TimelineNoteCreateSchema,\n 'timelineNoteCreateForm',\n {\n body: {\n label: 'Comment',\n placeholder: 'Add a comment...',\n inputType: 'textarea',\n },\n is_internal: {\n label: 'Internal Note',\n helpText: 'Internal notes are not visible to the customer',\n },\n },\n);\n\nexport type TimelineNoteCreateDto = z.infer<typeof TimelineNoteCreateSchema>;\n","<template>\n <div class=\"border-t border-base-200 pt-4 mt-4 w-full\">\n <template v-if=\"disabled\">\n <div class=\"bg-base-200/50 rounded-lg p-4 text-center\">\n <span class=\"text-base-content/50 text-sm inline-flex items-center gap-1.5\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke-width=\"1.5\"\n stroke=\"currentColor\"\n class=\"w-4 h-4\"\n >\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n d=\"M16.5 10.5V6.75a4.5 4.5 0 10-9 0v3.75m-.75 11.25h10.5a2.25 2.25 0 002.25-2.25v-6.75a2.25 2.25 0 00-2.25-2.25H6.75a2.25 2.25 0 00-2.25 2.25v6.75a2.25 2.25 0 002.25 2.25z\"\n />\n </svg>\n This ticket has been locked. You can no longer add comments.\n </span>\n </div>\n </template>\n <ZiniaForm\n v-else\n @handle-submit=\"handleSubmit\"\n @success=\"handleSuccess\"\n @error=\"handleError\"\n title=\"\"\n subtitle=\"\"\n >\n <div ref=\"formWrapperRef\" class=\"grid grid-cols-1 gap-4 w-full\" @keydown=\"handleKeydown\">\n <p\n v-if=\"showTypeToggle\"\n class=\"col-span-full text-xs mb-1\"\n :class=\"form.values.is_internal ? 'text-warning' : 'text-info'\"\n >\n {{\n form.values.is_internal\n ? '🔒 Internal — not visible to customer'\n : 'Visible to customer'\n }}\n </p>\n <div class=\"col-span-full\">\n <zinia.BodyField class=\"textarea w-full\" />\n </div>\n <div class=\"col-span-full flex flex-wrap gap-2 justify-between items-center\">\n <div v-if=\"showTypeToggle\" class=\"join\">\n <button\n type=\"button\"\n :class=\"[\n 'btn btn-sm join-item',\n !form.values.is_internal ? 'btn-info btn-active' : '',\n ]\"\n :disabled=\"form.isSubmitting\"\n @click=\"form.setValue('is_internal', false)\"\n >\n Customer Note\n </button>\n <button\n type=\"button\"\n :class=\"[\n 'btn btn-sm join-item',\n form.values.is_internal ? 'btn-warning btn-active' : '',\n ]\"\n :disabled=\"form.isSubmitting\"\n @click=\"form.setValue('is_internal', true)\"\n >\n Internal Note\n </button>\n </div>\n <div v-else></div>\n <ZiniaSubmitButton submitText=\"Comment\" submittingText=\"Adding...\" />\n </div>\n </div>\n </ZiniaForm>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { useForm } from '@dragonmastery/zinia-forms-core';\nimport { ref, watch } from 'vue';\nimport { timelineNoteCreateMetadata } from './timelineNoteFormMetadata';\n\ninterface Props {\n showTypeToggle: boolean;\n disabled: boolean;\n /** When provided, noteType is controlled (e.g. synced with URL query param) */\n noteType?: 'customer' | 'internal';\n /** Called when form submits with validated data. Must return a Promise. */\n onSubmit: (payload: { content: string; noteType: 'customer' | 'internal' }) => Promise<void>;\n}\n\nconst props = defineProps<Props>();\nconst formWrapperRef = ref<HTMLElement | null>(null);\n\nconst emit = defineEmits<{\n 'update:noteType': [value: 'customer' | 'internal'];\n}>();\n\nconst { form, zinia, ZiniaForm, ZiniaSubmitButton, refreshFormData } = useForm(\n timelineNoteCreateMetadata,\n {\n storeName: 'timeline-note-input',\n persistToLocalStorage: false,\n renderStyle: 'daisy_ui',\n fetchData: async () => ({\n body: '',\n is_internal: props.noteType === 'internal',\n }),\n },\n);\n\n// Sync form's is_internal when controlled noteType prop changes (e.g. from URL)\nwatch(\n () => props.noteType,\n (noteType) => {\n if (noteType !== undefined) {\n form.setValue('is_internal', noteType === 'internal');\n }\n },\n { immediate: true },\n);\n\n// Emit when user toggles note type (for URL sync in StaffTimeline)\nwatch(\n () => form.values.is_internal,\n (isInternal) => {\n if (props.showTypeToggle) {\n emit('update:noteType', isInternal ? 'internal' : 'customer');\n }\n },\n);\n\nfunction handleKeydown(e: KeyboardEvent) {\n if ((e.ctrlKey || e.metaKey) && e.key === 'Enter') {\n e.preventDefault();\n const form = formWrapperRef.value?.closest('form');\n form?.requestSubmit();\n }\n}\n\nasync function handleSubmit(formData: { body: string; is_internal: boolean }) {\n await props.onSubmit({\n content: (formData.body ?? '').trim(),\n noteType: props.showTypeToggle && formData.is_internal ? 'internal' : 'customer',\n });\n}\n\nfunction handleSuccess() {\n refreshFormData();\n (document.activeElement as HTMLElement)?.blur();\n}\n\nfunction handleError(_error: Error | unknown) {\n // Form displays errors via ZiniaFormErrorsSummary\n}\n\nfunction reset() {\n refreshFormData();\n}\n\ndefineExpose({ reset });\n</script>\n"],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import "./useRpcAuth-CJtq1dqM.js";
2
+ import "./EnhancedRefreshTokenHandler-C6tZCcfX.js";
3
+ import { t as UserListPage_default } from "./UserListPage-DelzxCID.js";
4
+
5
+ export { UserListPage_default as default };
@@ -151,4 +151,4 @@ var UserListPage_default = _sfc_main;
151
151
 
152
152
  //#endregion
153
153
  export { userRowSchemaWithMetadata as n, UserTypeBadge_default as r, UserListPage_default as t };
154
- //# sourceMappingURL=UserListPage-CDMSZpXK.js.map
154
+ //# sourceMappingURL=UserListPage-DelzxCID.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"UserListPage-CDMSZpXK.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-DelzxCID.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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"}
@@ -2,8 +2,8 @@ import { d as useEnv, o as useUserSessionStore } from "./useRpcAuth-CJtq1dqM.js"
2
2
  import { t as useMutation } from "./useMutation-BLNuJoYl.js";
3
3
  import { t as useQuery } from "./useQuery-BzUGEOj0.js";
4
4
  import { t as AppLink_default } from "./AppLink-FcNGKgvG.js";
5
- import { o as withReturnUrl, r as getValidReturnUrl, t as getAndClearEmailVerificationReturnUrl } from "./useReturnUrl-B5V3SJf5.js";
6
- import { t as useEmailVerificationChannel } from "./useEmailVerificationChannel-QuMSgzzM.js";
5
+ import { a as withReturnUrl, r as getValidReturnUrl, t as getAndClearEmailVerificationReturnUrl } from "./useReturnUrl-DnezAxBA.js";
6
+ import { t as useEmailVerificationChannel } from "./useEmailVerificationChannel-C76Gnyi1.js";
7
7
  import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createStaticVNode, createTextVNode, createVNode, defineComponent, onMounted, onUnmounted, openBlock, ref, toDisplayString, unref, withCtx } from "vue";
8
8
  import { useRoute, useRouter } from "vue-router";
9
9
  import { toast } from "vue3-toastify";
@@ -259,4 +259,4 @@ var VerifyEmail_default = _sfc_main;
259
259
 
260
260
  //#endregion
261
261
  export { VerifyEmail_default as t };
262
- //# sourceMappingURL=VerifyEmail-CWUhRA1o.js.map
262
+ //# sourceMappingURL=VerifyEmail-Cy2s4yP0.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"VerifyEmail-CWUhRA1o.js","names":["resendCountdownInterval: ReturnType<typeof setInterval> | null"],"sources":["../src/slices/auth/features/verify_email/VerifyEmail.vue"],"sourcesContent":["<template>\n <div class=\"max-w-md mx-auto bg-base-200 p-6 rounded-xl shadow-md container\">\n <div class=\"text-center\">\n <!-- State A: No token (after signup, waiting for email) -->\n <div v-if=\"!token && status !== 'loading' && status !== 'success'\" class=\"space-y-4\">\n <h3 class=\"text-lg font-semibold\">Check your email</h3>\n <p class=\"text-sm text-base-content/70 text-left\">\n We've sent a verification email to your inbox. It may take a couple of minutes to\n arrive. Be sure to check your junk or spam folder if you don't see it.\n </p>\n <p class=\"text-sm text-base-content/70 text-left\">\n When you receive the email, click the link inside. You'll land on a page where you\n need to click the \"Verify email\" button to complete verification.\n </p>\n <p\n v-if=\"emailVerificationMode === 'strict'\"\n class=\"text-sm text-base-content/80 text-left font-medium\"\n >\n Application access is restricted until email verification is completed.\n </p>\n <div class=\"flex flex-col gap-2 items-center pt-2\">\n <AppLink\n v-if=\"emailVerificationMode !== 'strict'\"\n :to=\"appLink\"\n class=\"btn btn-outline btn-sm\"\n >\n Continue to app\n </AppLink>\n <button\n v-if=\"isLoggedIn && verifyEmailApi\"\n type=\"button\"\n class=\"btn btn-outline btn-sm\"\n :disabled=\"resendLoading || resendCountdown > 0\"\n @click=\"resendVerification\"\n >\n {{\n resendLoading\n ? 'Sending...'\n : resendCountdown > 0\n ? `Try again in ${resendCountdown}`\n : 'Resend verification email'\n }}\n </button>\n </div>\n </div>\n\n <!-- State B: Token present, waiting for user to click verify -->\n <div\n v-else-if=\"token && status !== 'loading' && status !== 'success' && status !== 'error'\"\n class=\"space-y-4\"\n >\n <h3 class=\"text-lg font-semibold\">Verify your email</h3>\n <p class=\"text-sm text-base-content/70\">\n Click the button below to complete verification. You'll be redirected once it's done.\n </p>\n <p\n v-if=\"emailVerificationMode === 'strict'\"\n class=\"text-sm text-base-content/80 font-medium\"\n >\n Application access is restricted until email verification is completed.\n </p>\n <button\n type=\"button\"\n class=\"btn btn-primary\"\n :disabled=\"verifyLoading\"\n @click=\"handleVerify\"\n >\n {{ verifyLoading ? 'Verifying...' : 'Verify email' }}\n </button>\n </div>\n\n <!-- Loading (after clicking verify) -->\n <div v-else-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\n <!-- Success -->\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\">Redirecting you...</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=\"appLink\" class=\"link link-primary\">continue to the app</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\n <!-- Error -->\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-outline btn-sm\"\n :disabled=\"resendLoading || resendCountdown > 0\"\n @click=\"resendVerification\"\n >\n {{\n resendLoading\n ? 'Sending...'\n : resendCountdown > 0\n ? `Try again in ${resendCountdown}`\n : 'Resend verification email'\n }}\n </button>\n </div>\n </div>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport type { DragoncoreApi, EmailVerificationApi } from '@dragonmastery/dragoncore-shared';\nimport { computed, onMounted, onUnmounted, ref } from 'vue';\nimport { useRoute, useRouter } from 'vue-router';\nimport { toast } from 'vue3-toastify';\nimport AppLink from '../../../../components/AppLink.vue';\nimport { useEnv } from '../../../../composables/useEnv';\nimport { useMutation } from '../../../../composables/useMutation';\nimport { useQuery } from '../../../../composables/useQuery';\nimport { useUserSessionStore } from '../../../../composables/useUserSessionStore';\nimport {\n getAndClearEmailVerificationReturnUrl,\n getValidReturnUrl,\n withReturnUrl,\n} from '../../../../utils/useReturnUrl';\nimport { useEmailVerificationChannel } from '../../useEmailVerificationChannel';\n\nconst AUTH_CHANNEL = 'auth';\n/** Frontend countdown (60s). Backend uses 59s so it's ready when button enables. */\nconst RESEND_COOLDOWN_SECONDS = 60;\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 appLink = computed(() => getValidReturnUrl(route, '/'));\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<'idle' | 'loading' | 'success' | 'error'>('idle');\nconst errorMessage = ref('');\nconst verifyEmailApi = ref(false);\nconst resendLoading = ref(false);\nconst resendCountdown = ref(0);\nlet resendCountdownInterval: ReturnType<typeof setInterval> | null = null;\nconst verifyLoading = ref(false);\nconst redirectTarget = ref<string | null>(null);\n\nconst isLoggedIn = computed(() => !!sessionStore.userSession?.user.userId);\n\n// When on \"Check your email\" (no token), listen for verification in another tab\nconst isAwaitingVerification = computed(\n () => !token && status.value !== 'loading' && status.value !== 'success',\n);\nuseEmailVerificationChannel(\n isAwaitingVerification,\n (targetUrl) => router.push(targetUrl),\n () => getValidReturnUrl(route, '/'),\n);\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\nasync function handleVerify() {\n if (!token) return;\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 status.value = 'loading';\n verifyLoading.value = true;\n errorMessage.value = '';\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 );\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 errorMessage.value =\n 'The link may have expired. Please try again or resend the verification email.';\n }\n } catch (error) {\n status.value = 'error';\n errorMessage.value =\n error instanceof Error\n ? error.message\n : 'Something went wrong. The link may have expired.';\n verifyEmailApi.value = true;\n } finally {\n verifyLoading.value = false;\n }\n}\n\nfunction startResendCountdown(seconds: number) {\n if (resendCountdownInterval) {\n clearInterval(resendCountdownInterval);\n resendCountdownInterval = null;\n }\n resendCountdown.value = seconds;\n resendCountdownInterval = setInterval(() => {\n resendCountdown.value = Math.max(0, resendCountdown.value - 1);\n if (resendCountdown.value <= 0 && resendCountdownInterval) {\n clearInterval(resendCountdownInterval);\n resendCountdownInterval = null;\n }\n }, 1000);\n}\n\nconst resendVerification = async () => {\n try {\n resendLoading.value = true;\n const result = await resendMutate(undefined);\n if (result?.ok) {\n if (result.sent) {\n toast.success('Verification email sent. Please check your inbox.');\n startResendCountdown(RESEND_COOLDOWN_SECONDS);\n } else if (result.seconds_until_next_send != null) {\n toast.info(`Please wait ${result.seconds_until_next_send} seconds before resending.`);\n startResendCountdown(result.seconds_until_next_send);\n } else {\n toast.success('Verification email sent. Please check your inbox.');\n startResendCountdown(RESEND_COOLDOWN_SECONDS);\n }\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// When landing on \"Check your email\" (no token), we just sent the email at signup.\n// Start resend button disabled with countdown to match backend cooldown.\nonMounted(() => {\n if (!token && status.value !== 'loading' && status.value !== 'success') {\n startResendCountdown(RESEND_COOLDOWN_SECONDS);\n }\n});\n\nonUnmounted(() => {\n resendCountdownInterval && clearInterval(resendCountdownInterval);\n});\n\n// Detect if verifyEmail API is available (for resend button)\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</script>\n"],"mappings":"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"}
1
+ {"version":3,"file":"VerifyEmail-Cy2s4yP0.js","names":["resendCountdownInterval: ReturnType<typeof setInterval> | null"],"sources":["../src/slices/auth/features/verify_email/VerifyEmail.vue"],"sourcesContent":["<template>\n <div class=\"max-w-md mx-auto bg-base-200 p-6 rounded-xl shadow-md container\">\n <div class=\"text-center\">\n <!-- State A: No token (after signup, waiting for email) -->\n <div v-if=\"!token && status !== 'loading' && status !== 'success'\" class=\"space-y-4\">\n <h3 class=\"text-lg font-semibold\">Check your email</h3>\n <p class=\"text-sm text-base-content/70 text-left\">\n We've sent a verification email to your inbox. It may take a couple of minutes to\n arrive. Be sure to check your junk or spam folder if you don't see it.\n </p>\n <p class=\"text-sm text-base-content/70 text-left\">\n When you receive the email, click the link inside. You'll land on a page where you\n need to click the \"Verify email\" button to complete verification.\n </p>\n <p\n v-if=\"emailVerificationMode === 'strict'\"\n class=\"text-sm text-base-content/80 text-left font-medium\"\n >\n Application access is restricted until email verification is completed.\n </p>\n <div class=\"flex flex-col gap-2 items-center pt-2\">\n <AppLink\n v-if=\"emailVerificationMode !== 'strict'\"\n :to=\"appLink\"\n class=\"btn btn-outline btn-sm\"\n >\n Continue to app\n </AppLink>\n <button\n v-if=\"isLoggedIn && verifyEmailApi\"\n type=\"button\"\n class=\"btn btn-outline btn-sm\"\n :disabled=\"resendLoading || resendCountdown > 0\"\n @click=\"resendVerification\"\n >\n {{\n resendLoading\n ? 'Sending...'\n : resendCountdown > 0\n ? `Try again in ${resendCountdown}`\n : 'Resend verification email'\n }}\n </button>\n </div>\n </div>\n\n <!-- State B: Token present, waiting for user to click verify -->\n <div\n v-else-if=\"token && status !== 'loading' && status !== 'success' && status !== 'error'\"\n class=\"space-y-4\"\n >\n <h3 class=\"text-lg font-semibold\">Verify your email</h3>\n <p class=\"text-sm text-base-content/70\">\n Click the button below to complete verification. You'll be redirected once it's done.\n </p>\n <p\n v-if=\"emailVerificationMode === 'strict'\"\n class=\"text-sm text-base-content/80 font-medium\"\n >\n Application access is restricted until email verification is completed.\n </p>\n <button\n type=\"button\"\n class=\"btn btn-primary\"\n :disabled=\"verifyLoading\"\n @click=\"handleVerify\"\n >\n {{ verifyLoading ? 'Verifying...' : 'Verify email' }}\n </button>\n </div>\n\n <!-- Loading (after clicking verify) -->\n <div v-else-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\n <!-- Success -->\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\">Redirecting you...</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=\"appLink\" class=\"link link-primary\">continue to the app</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\n <!-- Error -->\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-outline btn-sm\"\n :disabled=\"resendLoading || resendCountdown > 0\"\n @click=\"resendVerification\"\n >\n {{\n resendLoading\n ? 'Sending...'\n : resendCountdown > 0\n ? `Try again in ${resendCountdown}`\n : 'Resend verification email'\n }}\n </button>\n </div>\n </div>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport type { DragoncoreApi, EmailVerificationApi } from '@dragonmastery/dragoncore-shared';\nimport { computed, onMounted, onUnmounted, ref } from 'vue';\nimport { useRoute, useRouter } from 'vue-router';\nimport { toast } from 'vue3-toastify';\nimport AppLink from '../../../../components/AppLink.vue';\nimport { useEnv } from '../../../../composables/useEnv';\nimport { useMutation } from '../../../../composables/useMutation';\nimport { useQuery } from '../../../../composables/useQuery';\nimport { useUserSessionStore } from '../../../../composables/useUserSessionStore';\nimport {\n getAndClearEmailVerificationReturnUrl,\n getValidReturnUrl,\n withReturnUrl,\n} from '../../../../utils/useReturnUrl';\nimport { useEmailVerificationChannel } from '../../useEmailVerificationChannel';\n\nconst AUTH_CHANNEL = 'auth';\n/** Frontend countdown (60s). Backend uses 59s so it's ready when button enables. */\nconst RESEND_COOLDOWN_SECONDS = 60;\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 appLink = computed(() => getValidReturnUrl(route, '/'));\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<'idle' | 'loading' | 'success' | 'error'>('idle');\nconst errorMessage = ref('');\nconst verifyEmailApi = ref(false);\nconst resendLoading = ref(false);\nconst resendCountdown = ref(0);\nlet resendCountdownInterval: ReturnType<typeof setInterval> | null = null;\nconst verifyLoading = ref(false);\nconst redirectTarget = ref<string | null>(null);\n\nconst isLoggedIn = computed(() => !!sessionStore.userSession?.user.userId);\n\n// When on \"Check your email\" (no token), listen for verification in another tab\nconst isAwaitingVerification = computed(\n () => !token && status.value !== 'loading' && status.value !== 'success',\n);\nuseEmailVerificationChannel(\n isAwaitingVerification,\n (targetUrl) => router.push(targetUrl),\n () => getValidReturnUrl(route, '/'),\n);\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\nasync function handleVerify() {\n if (!token) return;\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 status.value = 'loading';\n verifyLoading.value = true;\n errorMessage.value = '';\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 );\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 errorMessage.value =\n 'The link may have expired. Please try again or resend the verification email.';\n }\n } catch (error) {\n status.value = 'error';\n errorMessage.value =\n error instanceof Error\n ? error.message\n : 'Something went wrong. The link may have expired.';\n verifyEmailApi.value = true;\n } finally {\n verifyLoading.value = false;\n }\n}\n\nfunction startResendCountdown(seconds: number) {\n if (resendCountdownInterval) {\n clearInterval(resendCountdownInterval);\n resendCountdownInterval = null;\n }\n resendCountdown.value = seconds;\n resendCountdownInterval = setInterval(() => {\n resendCountdown.value = Math.max(0, resendCountdown.value - 1);\n if (resendCountdown.value <= 0 && resendCountdownInterval) {\n clearInterval(resendCountdownInterval);\n resendCountdownInterval = null;\n }\n }, 1000);\n}\n\nconst resendVerification = async () => {\n try {\n resendLoading.value = true;\n const result = await resendMutate(undefined);\n if (result?.ok) {\n if (result.sent) {\n toast.success('Verification email sent. Please check your inbox.');\n startResendCountdown(RESEND_COOLDOWN_SECONDS);\n } else if (result.seconds_until_next_send != null) {\n toast.info(`Please wait ${result.seconds_until_next_send} seconds before resending.`);\n startResendCountdown(result.seconds_until_next_send);\n } else {\n toast.success('Verification email sent. Please check your inbox.');\n startResendCountdown(RESEND_COOLDOWN_SECONDS);\n }\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// When landing on \"Check your email\" (no token), we just sent the email at signup.\n// Start resend button disabled with countdown to match backend cooldown.\nonMounted(() => {\n if (!token && status.value !== 'loading' && status.value !== 'success') {\n startResendCountdown(RESEND_COOLDOWN_SECONDS);\n }\n});\n\nonUnmounted(() => {\n resendCountdownInterval && clearInterval(resendCountdownInterval);\n});\n\n// Detect if verifyEmail API is available (for resend button)\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</script>\n"],"mappings":"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"}
@@ -4,7 +4,7 @@ import "./useQueryCache-alzaRWEb.js";
4
4
  import "./useMutation-BLNuJoYl.js";
5
5
  import "./useQuery-BzUGEOj0.js";
6
6
  import "./AppLink-FcNGKgvG.js";
7
- import "./useEmailVerificationChannel-QuMSgzzM.js";
8
- import { t as VerifyEmail_default } from "./VerifyEmail-CWUhRA1o.js";
7
+ import "./useEmailVerificationChannel-C76Gnyi1.js";
8
+ import { t as VerifyEmail_default } from "./VerifyEmail-Cy2s4yP0.js";
9
9
 
10
10
  export { VerifyEmail_default as default };
@@ -1,6 +1,6 @@
1
1
  import { t as ZiniaContainer_default } from "./ZiniaContainer-BPIfQOc7.js";
2
2
  import { t as formatSystemTimestamp } from "./convertToLocalDateTime-BKBxm2Rc.js";
3
- import { t as teamPaths } from "./teamRoutes-CFDsHPkd.js";
3
+ import { t as teamPaths } from "./teamRoutes-CSBq1DNq.js";
4
4
  import { computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, inject, openBlock, resolveComponent, toDisplayString, unref, withCtx } from "vue";
5
5
  import { useRoute } from "vue-router";
6
6
  import { toast } from "vue3-toastify";
@@ -316,4 +316,4 @@ var ViewTeam_default = _sfc_main;
316
316
 
317
317
  //#endregion
318
318
  export { ViewTeam_default as t };
319
- //# sourceMappingURL=ViewTeam-ttqX2In8.js.map
319
+ //# sourceMappingURL=ViewTeam-ByZdYEJG.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ViewTeam-ttqX2In8.js","names":[],"sources":["../src/slices/team/ViewTeam.vue"],"sourcesContent":["<template>\n <div v-if=\"isLoading\" class=\"flex justify-center items-center p-8\">\n <span class=\"loading loading-spinner loading-lg\"></span>\n </div>\n\n <div v-else-if=\"error\" 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>{{ error.message }}</span>\n </div>\n\n <ZiniaContainer v-else-if=\"teamData\">\n <!-- Header with Title -->\n <div class=\"mb-4\">\n <h1 class=\"text-xl sm:text-2xl font-bold text-base-content break-words leading-tight\">\n {{ teamData.display_name }}\n </h1>\n <div class=\"flex flex-wrap items-center gap-2 mt-2\">\n <span class=\"badge badge-sm badge-primary\">{{ teamData.unique_name }}</span>\n <span v-if=\"teamData.archived_at\" class=\"badge badge-sm badge-error\">Archived</span>\n <span v-else class=\"badge badge-sm badge-success\">Active</span>\n </div>\n </div>\n\n <!-- Description -->\n <div v-if=\"teamData.description\" class=\"prose prose-sm sm:prose-base max-w-none mb-4\">\n <p class=\"text-base-content/80 whitespace-pre-wrap text-sm sm:text-base leading-relaxed\">\n {{ teamData.description }}\n </p>\n </div>\n\n <!-- Team Information Grid -->\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4 mt-6\">\n <!-- Basic Information -->\n <div v-if=\"teamData.legal_name\" class=\"card bg-base-100 shadow-sm\">\n <div class=\"card-body\">\n <h3 class=\"card-title text-base mb-3\">Basic Information</h3>\n <div v-if=\"teamData.legal_name\" class=\"text-sm\">\n <span class=\"font-medium text-base-content/70\">Legal Name:</span>\n <span class=\"ml-2\">{{ teamData.legal_name }}</span>\n </div>\n </div>\n </div>\n\n <!-- Contact Information -->\n <div\n v-if=\"\n teamData.contact_name ||\n teamData.contact_email ||\n teamData.contact_business_phone ||\n teamData.contact_mobile_phone\n \"\n class=\"card bg-base-100 shadow-sm\"\n >\n <div class=\"card-body\">\n <h3 class=\"card-title text-base mb-3\">Contact Information</h3>\n <div v-if=\"teamData.contact_name\" class=\"text-sm\">\n <span class=\"font-medium text-base-content/70\">Name:</span>\n <span class=\"ml-2\">{{ teamData.contact_name }}</span>\n </div>\n <div v-if=\"teamData.contact_email\" class=\"text-sm mt-2\">\n <span class=\"font-medium text-base-content/70\">Email:</span>\n <a :href=\"`mailto:${teamData.contact_email}`\" class=\"ml-2 link link-primary\">\n {{ teamData.contact_email }}\n </a>\n </div>\n <div v-if=\"teamData.contact_business_phone\" class=\"text-sm mt-2\">\n <span class=\"font-medium text-base-content/70\">Business Phone:</span>\n <span class=\"ml-2\">{{ teamData.contact_business_phone }}</span>\n </div>\n <div v-if=\"teamData.contact_mobile_phone\" class=\"text-sm mt-2\">\n <span class=\"font-medium text-base-content/70\">Mobile Phone:</span>\n <span class=\"ml-2\">{{ teamData.contact_mobile_phone }}</span>\n </div>\n <div v-if=\"teamData.contact_time_zone\" class=\"text-sm mt-2\">\n <span class=\"font-medium text-base-content/70\">Time Zone:</span>\n <span class=\"ml-2\">{{ teamData.contact_time_zone }}</span>\n </div>\n </div>\n </div>\n\n <!-- Address Information -->\n <div\n v-if=\"teamData.address_full || teamData.address_city || teamData.address_zip\"\n class=\"card bg-base-100 shadow-sm\"\n >\n <div class=\"card-body\">\n <h3 class=\"card-title text-base mb-3\">Address</h3>\n <div v-if=\"teamData.address_full\" class=\"text-sm\">\n <span class=\"font-medium text-base-content/70\">Address:</span>\n <span class=\"ml-2\">{{ teamData.address_full }}</span>\n </div>\n <div v-if=\"teamData.address_city\" class=\"text-sm mt-2\">\n <span class=\"font-medium text-base-content/70\">City:</span>\n <span class=\"ml-2\">{{ teamData.address_city }}</span>\n </div>\n <div v-if=\"teamData.address_zip\" class=\"text-sm mt-2\">\n <span class=\"font-medium text-base-content/70\">Zip:</span>\n <span class=\"ml-2\">{{ teamData.address_zip }}</span>\n </div>\n </div>\n </div>\n\n <!-- Web Presence -->\n <div v-if=\"teamData.twitter_username || teamData.url\" class=\"card bg-base-100 shadow-sm\">\n <div class=\"card-body\">\n <h3 class=\"card-title text-base mb-3\">Web Presence</h3>\n <div v-if=\"teamData.twitter_username\" class=\"text-sm\">\n <span class=\"font-medium text-base-content/70\">Twitter:</span>\n <span class=\"ml-2\">@{{ teamData.twitter_username }}</span>\n </div>\n <div v-if=\"teamData.url\" class=\"text-sm mt-2\">\n <span class=\"font-medium text-base-content/70\">URL:</span>\n <a\n :href=\"teamData.url\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n class=\"ml-2 link link-primary\"\n >\n {{ teamData.url }}\n </a>\n </div>\n </div>\n </div>\n\n <!-- Referral Tag -->\n <div v-if=\"teamData.referral_tag\" class=\"card bg-base-100 shadow-sm\">\n <div class=\"card-body\">\n <h3 class=\"card-title text-base mb-3\">Referral Tag</h3>\n <p class=\"text-sm text-base-content/70 mb-3\">\n Share a link so referral events are routed to this team. The <code class=\"text-xs\">ref</code> parameter tags visitors for attribution.\n </p>\n\n <div v-if=\"referralAppLink\" class=\"mb-3\">\n <div class=\"text-xs font-medium text-base-content/60 mb-1\">App link (direct)</div>\n <div class=\"flex items-center gap-2\">\n <code class=\"flex-1 px-3 py-2 bg-base-200 rounded-lg text-sm font-mono break-all\">\n {{ referralAppLink }}\n </code>\n <button\n type=\"button\"\n class=\"btn btn-sm btn-ghost shrink-0\"\n title=\"Copy app link\"\n @click=\"copyToClipboard(referralAppLink, 'App link copied')\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\" />\n </svg>\n </button>\n </div>\n </div>\n\n <div v-if=\"referralMarketingLink\">\n <div class=\"text-xs font-medium text-base-content/60 mb-1\">Marketing link</div>\n <div class=\"flex items-center gap-2\">\n <code class=\"flex-1 px-3 py-2 bg-base-200 rounded-lg text-sm font-mono break-all\">\n {{ referralMarketingLink }}\n </code>\n <button\n type=\"button\"\n class=\"btn btn-sm btn-ghost shrink-0\"\n title=\"Copy marketing link\"\n @click=\"copyToClipboard(referralMarketingLink, 'Marketing link copied')\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\" />\n </svg>\n </button>\n </div>\n </div>\n\n <div v-if=\"!referralAppLink && !referralMarketingLink\" class=\"flex items-center gap-2\">\n <code class=\"flex-1 px-3 py-2 bg-base-200 rounded-lg text-sm font-mono\">\n {{ teamData.referral_tag }}\n </code>\n <button\n type=\"button\"\n class=\"btn btn-sm btn-ghost shrink-0\"\n title=\"Copy tag\"\n @click=\"copyToClipboard(teamData.referral_tag!, 'Referral tag copied')\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\" />\n </svg>\n </button>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Metadata -->\n <div class=\"mt-4 pt-4 border-t border-base-300 text-xs sm:text-sm text-base-content/50\">\n <div class=\"flex flex-col sm:flex-row sm:items-center gap-1 sm:gap-4\">\n <span v-if=\"teamData.created_by\"\n >Created by {{ teamData.created_by_display_name ?? teamData.created_by }}</span\n >\n <span v-if=\"teamData.created_at\">\n Created {{ formatSystemTimestamp(teamData.created_at) }}\n </span>\n <span\n v-if=\"teamData.updated_at && teamData.updated_at !== teamData.created_at\"\n class=\"text-xs\"\n >\n Updated {{ formatSystemTimestamp(teamData.updated_at) }}\n </span>\n </div>\n </div>\n\n <!-- Action Buttons -->\n <div class=\"flex flex-col sm:flex-row gap-3 justify-center mt-6\">\n <router-link\n :to=\"{\n name: teamPaths.edit.name,\n params: { id: team_id },\n }\"\n class=\"btn btn-primary\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke-width=\"1.5\"\n stroke=\"currentColor\"\n class=\"w-4 h-4 mr-2\"\n >\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n d=\"M16.862 4.487l1.687-1.688a1.875 1.875 0 112.652 2.652L10.582 16.07a4.5 4.5 0 01-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 011.13-1.897l8.932-8.931zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0115.75 21H5.25A2.25 2.25 0 013 18.75V8.25A2.25 2.25 0 015.25 6H10\"\n />\n </svg>\n Edit Team\n </router-link>\n </div>\n </ZiniaContainer>\n</template>\n\n<script setup lang=\"ts\">\nimport type { TeamReadDto } from '@dragonmastery/dragoncore-shared';\nimport { computed, inject } from 'vue';\nimport { useRoute } from 'vue-router';\nimport { toast } from 'vue3-toastify';\nimport ZiniaContainer from '../../components/ui/ZiniaContainer.vue';\nimport { formatSystemTimestamp } from '../../utils/convertToLocalDateTime';\nimport { teamPaths } from './teamRoutes';\n\ninterface Props {\n team: TeamReadDto | null;\n isLoading?: boolean;\n error?: Error | null;\n}\n\nconst props = defineProps<Props>();\n\nconst route = useRoute();\nconst team_id = route.params.id as string;\n\nconst referralAppBaseUrl = inject<string>('referralAppBaseUrl') ?? '';\nconst referralMarketingBaseUrl = inject<string>('referralMarketingBaseUrl') ?? '';\n\nconst teamData = computed(() => props.team);\n\nfunction buildRefLink(base: string): string {\n const tag = teamData.value?.referral_tag;\n if (!tag) return '';\n const b = base.trim().replace(/\\/$/, '');\n if (!b) return '';\n const sep = b.includes('?') ? '&' : '?';\n return `${b}${sep}ref=${encodeURIComponent(tag)}`;\n}\n\nconst referralAppLink = computed(() => buildRefLink(referralAppBaseUrl));\nconst referralMarketingLink = computed(() => buildRefLink(referralMarketingBaseUrl));\n\nasync function copyToClipboard(text: string, successMessage: string) {\n try {\n await navigator.clipboard.writeText(text);\n toast.success(successMessage);\n } catch {\n toast.error('Failed to copy');\n }\n}\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuQA,MAAM,QAAQ;EAGd,MAAM,UADQ,UAAU,CACF,OAAO;EAE7B,MAAM,qBAAqB,OAAe,qBAAqB,IAAI;EACnE,MAAM,2BAA2B,OAAe,2BAA2B,IAAI;EAE/E,MAAM,WAAW,eAAe,MAAM,KAAK;EAE3C,SAAS,aAAa,MAAsB;GAC1C,MAAM,MAAM,SAAS,OAAO;AAC5B,OAAI,CAAC,IAAK,QAAO;GACjB,MAAM,IAAI,KAAK,MAAM,CAAC,QAAQ,OAAO,GAAG;AACxC,OAAI,CAAC,EAAG,QAAO;AAEf,UAAO,GAAG,IADE,EAAE,SAAS,IAAI,GAAG,MAAM,IAClB,MAAM,mBAAmB,IAAI;;EAGjD,MAAM,kBAAkB,eAAe,aAAa,mBAAmB,CAAC;EACxE,MAAM,wBAAwB,eAAe,aAAa,yBAAyB,CAAC;EAEpF,eAAe,gBAAgB,MAAc,gBAAwB;AACnE,OAAI;AACF,UAAM,UAAU,UAAU,UAAU,KAAK;AACzC,UAAM,QAAQ,eAAe;WACvB;AACN,UAAM,MAAM,iBAAiB;;;;;UAjSpB,QAAA,aAAA,WAAA,EAAX,mBAEM,OAFN,YAEM,CAAA,GAAA,OAAA,OAAA,OAAA,KAAA,CADJ,mBAAwD,QAAA,EAAlD,OAAM,sCAAoC,EAAA,MAAA,GAAA,CAAA,EAAA,CAAA,IAGlC,QAAA,SAAA,WAAA,EAAhB,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,mBAAgC,QAAA,MAAA,gBAAvB,QAAA,MAAM,QAAO,EAAA,EAAA,CAAA,CAAA,IAGG,SAAA,SAAA,WAAA,EAA3B,YA+NiB,wBAAA,EAAA,KAAA,GAAA,EAAA;2BA9NW;KAA1B,mBAAA,sBAA0B;KAC1B,mBASM,OATN,YASM,CARJ,mBAEK,MAFL,YAEK,gBADA,SAAA,MAAS,aAAY,EAAA,EAAA,EAE1B,mBAIM,OAJN,YAIM,CAHJ,mBAA4E,QAA5E,YAA4E,gBAA9B,SAAA,MAAS,YAAW,EAAA,EAAA,EACtD,SAAA,MAAS,eAAA,WAAA,EAArB,mBAAoF,QAApF,YAAqE,WAAQ,KAAA,WAAA,EAC7E,mBAA+D,QAA/D,YAAkD,SAAM,EAAA,CAAA,CAAA,CAAA;KAI5D,mBAAA,gBAAoB;KACT,SAAA,MAAS,eAAA,WAAA,EAApB,mBAIM,OAJN,YAIM,CAHJ,mBAEI,KAFJ,aAEI,gBADC,SAAA,MAAS,YAAW,EAAA,EAAA,CAAA,CAAA,IAAA,mBAAA,QAAA,KAAA;KAI3B,mBAAA,0BAA8B;KAC9B,mBA4JM,OA5JN,aA4JM;MA3JJ,mBAAA,sBAA0B;MACf,SAAA,MAAS,cAAA,WAAA,EAApB,mBAQM,OARN,aAQM,CAPJ,mBAMM,OANN,aAMM,CAAA,OAAA,OAAA,OAAA,KALJ,mBAA4D,MAAA,EAAxD,OAAM,6BAA2B,EAAC,qBAAiB,GAAA,GAC5C,SAAA,MAAS,cAAA,WAAA,EAApB,mBAGM,OAHN,aAGM,CAAA,OAAA,OAAA,OAAA,KAFJ,mBAAiE,QAAA,EAA3D,OAAM,oCAAkC,EAAC,eAAW,GAAA,GAC1D,mBAAmD,QAAnD,aAAmD,gBAA7B,SAAA,MAAS,WAAU,EAAA,EAAA,CAAA,CAAA,IAAA,mBAAA,QAAA,KAAA,CAAA,CAAA,CAAA,CAAA,IAAA,mBAAA,QAAA,KAAA;MAK/C,mBAAA,wBAA4B;MAET,SAAA,MAAS,gBAA0B,SAAA,MAAS,iBAA2B,SAAA,MAAS,0BAAoC,SAAA,MAAS,wBAAA,WAAA,EADhJ,mBAkCM,OAlCN,aAkCM,CAzBJ,mBAwBM,OAxBN,aAwBM;mCAvBJ,mBAA8D,MAAA,EAA1D,OAAM,6BAA2B,EAAC,uBAAmB,GAAA;OAC9C,SAAA,MAAS,gBAAA,WAAA,EAApB,mBAGM,OAHN,aAGM,CAAA,OAAA,OAAA,OAAA,KAFJ,mBAA2D,QAAA,EAArD,OAAM,oCAAkC,EAAC,SAAK,GAAA,GACpD,mBAAqD,QAArD,aAAqD,gBAA/B,SAAA,MAAS,aAAY,EAAA,EAAA,CAAA,CAAA,IAAA,mBAAA,QAAA,KAAA;OAElC,SAAA,MAAS,iBAAA,WAAA,EAApB,mBAKM,OALN,aAKM,CAAA,OAAA,OAAA,OAAA,KAJJ,mBAA4D,QAAA,EAAtD,OAAM,oCAAkC,EAAC,UAAM,GAAA,GACrD,mBAEI,KAAA;QAFA,MAAI,UAAY,SAAA,MAAS;QAAiB,OAAM;0BAC/C,SAAA,MAAS,cAAa,EAAA,GAAA,YAAA,CAAA,CAAA,IAAA,mBAAA,QAAA,KAAA;OAGlB,SAAA,MAAS,0BAAA,WAAA,EAApB,mBAGM,OAHN,aAGM,CAAA,OAAA,OAAA,OAAA,KAFJ,mBAAqE,QAAA,EAA/D,OAAM,oCAAkC,EAAC,mBAAe,GAAA,GAC9D,mBAA+D,QAA/D,aAA+D,gBAAzC,SAAA,MAAS,uBAAsB,EAAA,EAAA,CAAA,CAAA,IAAA,mBAAA,QAAA,KAAA;OAE5C,SAAA,MAAS,wBAAA,WAAA,EAApB,mBAGM,OAHN,aAGM,CAAA,OAAA,QAAA,OAAA,MAFJ,mBAAmE,QAAA,EAA7D,OAAM,oCAAkC,EAAC,iBAAa,GAAA,GAC5D,mBAA6D,QAA7D,aAA6D,gBAAvC,SAAA,MAAS,qBAAoB,EAAA,EAAA,CAAA,CAAA,IAAA,mBAAA,QAAA,KAAA;OAE1C,SAAA,MAAS,qBAAA,WAAA,EAApB,mBAGM,OAHN,aAGM,CAAA,OAAA,QAAA,OAAA,MAFJ,mBAAgE,QAAA,EAA1D,OAAM,oCAAkC,EAAC,cAAU,GAAA,GACzD,mBAA0D,QAA1D,aAA0D,gBAApC,SAAA,MAAS,kBAAiB,EAAA,EAAA,CAAA,CAAA,IAAA,mBAAA,QAAA,KAAA;;MAKtD,mBAAA,wBAA4B;MAEpB,SAAA,MAAS,gBAAgB,SAAA,MAAS,gBAAgB,SAAA,MAAS,eAAA,WAAA,EADnE,mBAmBM,OAnBN,aAmBM,CAfJ,mBAcM,OAdN,aAcM;mCAbJ,mBAAkD,MAAA,EAA9C,OAAM,6BAA2B,EAAC,WAAO,GAAA;OAClC,SAAA,MAAS,gBAAA,WAAA,EAApB,mBAGM,OAHN,aAGM,CAAA,OAAA,QAAA,OAAA,MAFJ,mBAA8D,QAAA,EAAxD,OAAM,oCAAkC,EAAC,YAAQ,GAAA,GACvD,mBAAqD,QAArD,aAAqD,gBAA/B,SAAA,MAAS,aAAY,EAAA,EAAA,CAAA,CAAA,IAAA,mBAAA,QAAA,KAAA;OAElC,SAAA,MAAS,gBAAA,WAAA,EAApB,mBAGM,OAHN,aAGM,CAAA,OAAA,QAAA,OAAA,MAFJ,mBAA2D,QAAA,EAArD,OAAM,oCAAkC,EAAC,SAAK,GAAA,GACpD,mBAAqD,QAArD,aAAqD,gBAA/B,SAAA,MAAS,aAAY,EAAA,EAAA,CAAA,CAAA,IAAA,mBAAA,QAAA,KAAA;OAElC,SAAA,MAAS,eAAA,WAAA,EAApB,mBAGM,OAHN,aAGM,CAAA,OAAA,QAAA,OAAA,MAFJ,mBAA0D,QAAA,EAApD,OAAM,oCAAkC,EAAC,QAAI,GAAA,GACnD,mBAAoD,QAApD,aAAoD,gBAA9B,SAAA,MAAS,YAAW,EAAA,EAAA,CAAA,CAAA,IAAA,mBAAA,QAAA,KAAA;;MAKhD,mBAAA,iBAAqB;MACV,SAAA,MAAS,oBAAoB,SAAA,MAAS,OAAA,WAAA,EAAjD,mBAmBM,OAnBN,aAmBM,CAlBJ,mBAiBM,OAjBN,aAiBM;mCAhBJ,mBAAuD,MAAA,EAAnD,OAAM,6BAA2B,EAAC,gBAAY,GAAA;OACvC,SAAA,MAAS,oBAAA,WAAA,EAApB,mBAGM,OAHN,aAGM,CAAA,OAAA,QAAA,OAAA,MAFJ,mBAA8D,QAAA,EAAxD,OAAM,oCAAkC,EAAC,YAAQ,GAAA,GACvD,mBAA0D,QAA1D,aAAmB,MAAC,gBAAG,SAAA,MAAS,iBAAgB,EAAA,EAAA,CAAA,CAAA,IAAA,mBAAA,QAAA,KAAA;OAEvC,SAAA,MAAS,OAAA,WAAA,EAApB,mBAUM,OAVN,aAUM,CAAA,OAAA,QAAA,OAAA,MATJ,mBAA0D,QAAA,EAApD,OAAM,oCAAkC,EAAC,QAAI,GAAA,GACnD,mBAOI,KAAA;QAND,MAAM,SAAA,MAAS;QAChB,QAAO;QACP,KAAI;QACJ,OAAM;0BAEH,SAAA,MAAS,IAAG,EAAA,GAAA,YAAA,CAAA,CAAA,IAAA,mBAAA,QAAA,KAAA;;MAMvB,mBAAA,iBAAqB;MACV,SAAA,MAAS,gBAAA,WAAA,EAApB,mBA6DM,OA7DN,aA6DM,CA5DJ,mBA2DM,OA3DN,aA2DM;mCA1DJ,mBAAuD,MAAA,EAAnD,OAAM,6BAA2B,EAAC,gBAAY,GAAA;mCAClD,mBAEI,KAAA,EAFD,OAAM,qCAAmC,EAAA;wBAAC,iEACkB;QAAA,mBAAgC,QAAA,EAA1B,OAAM,WAAS,EAAC,MAAG;wBAAO,6CAC/F;;OAEW,gBAAA,SAAA,WAAA,EAAX,mBAiBM,OAjBN,aAiBM,CAAA,OAAA,QAAA,OAAA,MAhBJ,mBAAkF,OAAA,EAA7E,OAAM,iDAA+C,EAAC,qBAAiB,GAAA,GAC5E,mBAcM,OAdN,aAcM,CAbJ,mBAEO,QAFP,aAEO,gBADF,gBAAA,MAAe,EAAA,EAAA,EAEpB,mBASS,UAAA;QARP,MAAK;QACL,OAAM;QACN,OAAM;QACL,SAAK,OAAA,OAAA,OAAA,MAAA,WAAE,gBAAgB,gBAAA,OAAe,kBAAA;2CAEvC,mBAEM,OAAA;QAFD,OAAM;QAA6B,OAAM;QAAU,MAAK;QAAO,SAAQ;QAAY,QAAO;WAC7F,mBAAkM,QAAA;QAA5L,kBAAe;QAAQ,mBAAgB;QAAQ,gBAAa;QAAI,GAAE;;OAMrE,sBAAA,SAAA,WAAA,EAAX,mBAiBM,OAAA,aAAA,CAAA,OAAA,QAAA,OAAA,MAhBJ,mBAA+E,OAAA,EAA1E,OAAM,iDAA+C,EAAC,kBAAc,GAAA,GACzE,mBAcM,OAdN,aAcM,CAbJ,mBAEO,QAFP,aAEO,gBADF,sBAAA,MAAqB,EAAA,EAAA,EAE1B,mBASS,UAAA;QARP,MAAK;QACL,OAAM;QACN,OAAM;QACL,SAAK,OAAA,OAAA,OAAA,MAAA,WAAE,gBAAgB,sBAAA,OAAqB,wBAAA;2CAE7C,mBAEM,OAAA;QAFD,OAAM;QAA6B,OAAM;QAAU,MAAK;QAAO,SAAQ;QAAY,QAAO;WAC7F,mBAAkM,QAAA;QAA5L,kBAAe;QAAQ,mBAAgB;QAAQ,gBAAa;QAAI,GAAE;;QAMpE,gBAAA,SAAe,CAAK,sBAAA,SAAA,WAAA,EAAhC,mBAcM,OAdN,aAcM,CAbJ,mBAEO,QAFP,aAEO,gBADF,SAAA,MAAS,aAAY,EAAA,EAAA,EAE1B,mBASS,UAAA;QARP,MAAK;QACL,OAAM;QACN,OAAM;QACL,SAAK,OAAA,OAAA,OAAA,MAAA,WAAE,gBAAgB,SAAA,MAAS,cAAY,sBAAA;2CAE7C,mBAEM,OAAA;QAFD,OAAM;QAA6B,OAAM;QAAU,MAAK;QAAO,SAAQ;QAAY,QAAO;WAC7F,mBAAkM,QAAA;QAA5L,kBAAe;QAAQ,mBAAgB;QAAQ,gBAAa;QAAI,GAAE;;;;KAQpF,mBAAA,aAAiB;KACjB,mBAeM,OAfN,aAeM,CAdJ,mBAaM,OAbN,aAaM;MAZQ,SAAA,MAAS,cAAA,WAAA,EAArB,mBAEC,QAAA,aADE,gBAAW,gBAAG,SAAA,MAAS,2BAA2B,SAAA,MAAS,WAAU,EAAA,EAAA,IAAA,mBAAA,QAAA,KAAA;MAE5D,SAAA,MAAS,cAAA,WAAA,EAArB,mBAEO,QAAA,aAF0B,cACvB,gBAAG,MAAA,sBAAqB,CAAC,SAAA,MAAS,WAAU,CAAA,EAAA,EAAA,IAAA,mBAAA,QAAA,KAAA;MAG9C,SAAA,MAAS,cAAc,SAAA,MAAS,eAAe,SAAA,MAAS,cAAA,WAAA,EADhE,mBAKO,QALP,aAGC,cACS,gBAAG,MAAA,sBAAqB,CAAC,SAAA,MAAS,WAAU,CAAA,EAAA,EAAA,IAAA,mBAAA,QAAA,KAAA;;KAK1D,mBAAA,mBAAuB;KACvB,mBAwBM,OAxBN,aAwBM,CAvBJ,YAsBc,wBAAA;MArBX,IAAE;aAAoB,MAAA,UAAS,CAAC,KAAK;qBAA8B,MAAA,QAAO,EAAA;;MAI3E,OAAM;;6BAeA,CAAA,GAAA,OAAA,QAAA,OAAA,MAAA,CAbN,mBAaM,OAAA;OAZJ,OAAM;OACN,MAAK;OACL,SAAQ;OACR,gBAAa;OACb,QAAO;OACP,OAAM;UAEN,mBAIE,QAAA;OAHA,kBAAe;OACf,mBAAgB;OAChB,GAAE;gCAEA,eAER,GAAA,CAAA,EAAA,CAAA"}
1
+ {"version":3,"file":"ViewTeam-ByZdYEJG.js","names":[],"sources":["../src/slices/team/ViewTeam.vue"],"sourcesContent":["<template>\n <div v-if=\"isLoading\" class=\"flex justify-center items-center p-8\">\n <span class=\"loading loading-spinner loading-lg\"></span>\n </div>\n\n <div v-else-if=\"error\" 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>{{ error.message }}</span>\n </div>\n\n <ZiniaContainer v-else-if=\"teamData\">\n <!-- Header with Title -->\n <div class=\"mb-4\">\n <h1 class=\"text-xl sm:text-2xl font-bold text-base-content break-words leading-tight\">\n {{ teamData.display_name }}\n </h1>\n <div class=\"flex flex-wrap items-center gap-2 mt-2\">\n <span class=\"badge badge-sm badge-primary\">{{ teamData.unique_name }}</span>\n <span v-if=\"teamData.archived_at\" class=\"badge badge-sm badge-error\">Archived</span>\n <span v-else class=\"badge badge-sm badge-success\">Active</span>\n </div>\n </div>\n\n <!-- Description -->\n <div v-if=\"teamData.description\" class=\"prose prose-sm sm:prose-base max-w-none mb-4\">\n <p class=\"text-base-content/80 whitespace-pre-wrap text-sm sm:text-base leading-relaxed\">\n {{ teamData.description }}\n </p>\n </div>\n\n <!-- Team Information Grid -->\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4 mt-6\">\n <!-- Basic Information -->\n <div v-if=\"teamData.legal_name\" class=\"card bg-base-100 shadow-sm\">\n <div class=\"card-body\">\n <h3 class=\"card-title text-base mb-3\">Basic Information</h3>\n <div v-if=\"teamData.legal_name\" class=\"text-sm\">\n <span class=\"font-medium text-base-content/70\">Legal Name:</span>\n <span class=\"ml-2\">{{ teamData.legal_name }}</span>\n </div>\n </div>\n </div>\n\n <!-- Contact Information -->\n <div\n v-if=\"\n teamData.contact_name ||\n teamData.contact_email ||\n teamData.contact_business_phone ||\n teamData.contact_mobile_phone\n \"\n class=\"card bg-base-100 shadow-sm\"\n >\n <div class=\"card-body\">\n <h3 class=\"card-title text-base mb-3\">Contact Information</h3>\n <div v-if=\"teamData.contact_name\" class=\"text-sm\">\n <span class=\"font-medium text-base-content/70\">Name:</span>\n <span class=\"ml-2\">{{ teamData.contact_name }}</span>\n </div>\n <div v-if=\"teamData.contact_email\" class=\"text-sm mt-2\">\n <span class=\"font-medium text-base-content/70\">Email:</span>\n <a :href=\"`mailto:${teamData.contact_email}`\" class=\"ml-2 link link-primary\">\n {{ teamData.contact_email }}\n </a>\n </div>\n <div v-if=\"teamData.contact_business_phone\" class=\"text-sm mt-2\">\n <span class=\"font-medium text-base-content/70\">Business Phone:</span>\n <span class=\"ml-2\">{{ teamData.contact_business_phone }}</span>\n </div>\n <div v-if=\"teamData.contact_mobile_phone\" class=\"text-sm mt-2\">\n <span class=\"font-medium text-base-content/70\">Mobile Phone:</span>\n <span class=\"ml-2\">{{ teamData.contact_mobile_phone }}</span>\n </div>\n <div v-if=\"teamData.contact_time_zone\" class=\"text-sm mt-2\">\n <span class=\"font-medium text-base-content/70\">Time Zone:</span>\n <span class=\"ml-2\">{{ teamData.contact_time_zone }}</span>\n </div>\n </div>\n </div>\n\n <!-- Address Information -->\n <div\n v-if=\"teamData.address_full || teamData.address_city || teamData.address_zip\"\n class=\"card bg-base-100 shadow-sm\"\n >\n <div class=\"card-body\">\n <h3 class=\"card-title text-base mb-3\">Address</h3>\n <div v-if=\"teamData.address_full\" class=\"text-sm\">\n <span class=\"font-medium text-base-content/70\">Address:</span>\n <span class=\"ml-2\">{{ teamData.address_full }}</span>\n </div>\n <div v-if=\"teamData.address_city\" class=\"text-sm mt-2\">\n <span class=\"font-medium text-base-content/70\">City:</span>\n <span class=\"ml-2\">{{ teamData.address_city }}</span>\n </div>\n <div v-if=\"teamData.address_zip\" class=\"text-sm mt-2\">\n <span class=\"font-medium text-base-content/70\">Zip:</span>\n <span class=\"ml-2\">{{ teamData.address_zip }}</span>\n </div>\n </div>\n </div>\n\n <!-- Web Presence -->\n <div v-if=\"teamData.twitter_username || teamData.url\" class=\"card bg-base-100 shadow-sm\">\n <div class=\"card-body\">\n <h3 class=\"card-title text-base mb-3\">Web Presence</h3>\n <div v-if=\"teamData.twitter_username\" class=\"text-sm\">\n <span class=\"font-medium text-base-content/70\">Twitter:</span>\n <span class=\"ml-2\">@{{ teamData.twitter_username }}</span>\n </div>\n <div v-if=\"teamData.url\" class=\"text-sm mt-2\">\n <span class=\"font-medium text-base-content/70\">URL:</span>\n <a\n :href=\"teamData.url\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n class=\"ml-2 link link-primary\"\n >\n {{ teamData.url }}\n </a>\n </div>\n </div>\n </div>\n\n <!-- Referral Tag -->\n <div v-if=\"teamData.referral_tag\" class=\"card bg-base-100 shadow-sm\">\n <div class=\"card-body\">\n <h3 class=\"card-title text-base mb-3\">Referral Tag</h3>\n <p class=\"text-sm text-base-content/70 mb-3\">\n Share a link so referral events are routed to this team. The <code class=\"text-xs\">ref</code> parameter tags visitors for attribution.\n </p>\n\n <div v-if=\"referralAppLink\" class=\"mb-3\">\n <div class=\"text-xs font-medium text-base-content/60 mb-1\">App link (direct)</div>\n <div class=\"flex items-center gap-2\">\n <code class=\"flex-1 px-3 py-2 bg-base-200 rounded-lg text-sm font-mono break-all\">\n {{ referralAppLink }}\n </code>\n <button\n type=\"button\"\n class=\"btn btn-sm btn-ghost shrink-0\"\n title=\"Copy app link\"\n @click=\"copyToClipboard(referralAppLink, 'App link copied')\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\" />\n </svg>\n </button>\n </div>\n </div>\n\n <div v-if=\"referralMarketingLink\">\n <div class=\"text-xs font-medium text-base-content/60 mb-1\">Marketing link</div>\n <div class=\"flex items-center gap-2\">\n <code class=\"flex-1 px-3 py-2 bg-base-200 rounded-lg text-sm font-mono break-all\">\n {{ referralMarketingLink }}\n </code>\n <button\n type=\"button\"\n class=\"btn btn-sm btn-ghost shrink-0\"\n title=\"Copy marketing link\"\n @click=\"copyToClipboard(referralMarketingLink, 'Marketing link copied')\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\" />\n </svg>\n </button>\n </div>\n </div>\n\n <div v-if=\"!referralAppLink && !referralMarketingLink\" class=\"flex items-center gap-2\">\n <code class=\"flex-1 px-3 py-2 bg-base-200 rounded-lg text-sm font-mono\">\n {{ teamData.referral_tag }}\n </code>\n <button\n type=\"button\"\n class=\"btn btn-sm btn-ghost shrink-0\"\n title=\"Copy tag\"\n @click=\"copyToClipboard(teamData.referral_tag!, 'Referral tag copied')\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\" />\n </svg>\n </button>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Metadata -->\n <div class=\"mt-4 pt-4 border-t border-base-300 text-xs sm:text-sm text-base-content/50\">\n <div class=\"flex flex-col sm:flex-row sm:items-center gap-1 sm:gap-4\">\n <span v-if=\"teamData.created_by\"\n >Created by {{ teamData.created_by_display_name ?? teamData.created_by }}</span\n >\n <span v-if=\"teamData.created_at\">\n Created {{ formatSystemTimestamp(teamData.created_at) }}\n </span>\n <span\n v-if=\"teamData.updated_at && teamData.updated_at !== teamData.created_at\"\n class=\"text-xs\"\n >\n Updated {{ formatSystemTimestamp(teamData.updated_at) }}\n </span>\n </div>\n </div>\n\n <!-- Action Buttons -->\n <div class=\"flex flex-col sm:flex-row gap-3 justify-center mt-6\">\n <router-link\n :to=\"{\n name: teamPaths.edit.name,\n params: { id: team_id },\n }\"\n class=\"btn btn-primary\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke-width=\"1.5\"\n stroke=\"currentColor\"\n class=\"w-4 h-4 mr-2\"\n >\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n d=\"M16.862 4.487l1.687-1.688a1.875 1.875 0 112.652 2.652L10.582 16.07a4.5 4.5 0 01-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 011.13-1.897l8.932-8.931zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0115.75 21H5.25A2.25 2.25 0 013 18.75V8.25A2.25 2.25 0 015.25 6H10\"\n />\n </svg>\n Edit Team\n </router-link>\n </div>\n </ZiniaContainer>\n</template>\n\n<script setup lang=\"ts\">\nimport type { TeamReadDto } from '@dragonmastery/dragoncore-shared';\nimport { computed, inject } from 'vue';\nimport { useRoute } from 'vue-router';\nimport { toast } from 'vue3-toastify';\nimport ZiniaContainer from '../../components/ui/ZiniaContainer.vue';\nimport { formatSystemTimestamp } from '../../utils/convertToLocalDateTime';\nimport { teamPaths } from './teamRoutes';\n\ninterface Props {\n team: TeamReadDto | null;\n isLoading?: boolean;\n error?: Error | null;\n}\n\nconst props = defineProps<Props>();\n\nconst route = useRoute();\nconst team_id = route.params.id as string;\n\nconst referralAppBaseUrl = inject<string>('referralAppBaseUrl') ?? '';\nconst referralMarketingBaseUrl = inject<string>('referralMarketingBaseUrl') ?? '';\n\nconst teamData = computed(() => props.team);\n\nfunction buildRefLink(base: string): string {\n const tag = teamData.value?.referral_tag;\n if (!tag) return '';\n const b = base.trim().replace(/\\/$/, '');\n if (!b) return '';\n const sep = b.includes('?') ? '&' : '?';\n return `${b}${sep}ref=${encodeURIComponent(tag)}`;\n}\n\nconst referralAppLink = computed(() => buildRefLink(referralAppBaseUrl));\nconst referralMarketingLink = computed(() => buildRefLink(referralMarketingBaseUrl));\n\nasync function copyToClipboard(text: string, successMessage: string) {\n try {\n await navigator.clipboard.writeText(text);\n toast.success(successMessage);\n } catch {\n toast.error('Failed to copy');\n }\n}\n</script>\n"],"mappings":"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"}
@@ -2,7 +2,7 @@ import "./useRpcAuth-CJtq1dqM.js";
2
2
  import "./ZiniaContainer-BPIfQOc7.js";
3
3
  import "./userAuthorized-3RiCDXxr.js";
4
4
  import "./team_memberRoutes-BgjY9Kwq.js";
5
- import "./teamRoutes-CFDsHPkd.js";
6
- import { t as ViewTeam_default } from "./ViewTeam-ttqX2In8.js";
5
+ import "./teamRoutes-CSBq1DNq.js";
6
+ import { t as ViewTeam_default } from "./ViewTeam-ByZdYEJG.js";
7
7
 
8
8
  export { ViewTeam_default as default };
@@ -1,4 +1,4 @@
1
- import { o as createLastUsedPresetGuard } from "./saved_filter-C2N9l_a9.js";
1
+ import { o as createLastUsedPresetGuard } from "./saved_filter-erjEgsdK.js";
2
2
  import { c as userAuthenticated } from "./userAuthorized-3RiCDXxr.js";
3
3
 
4
4
  //#region src/slices/support_ticket/customer/customerSupportTicketRoutes.ts
@@ -55,7 +55,7 @@ const customerSupportTicketRoutes = [{
55
55
  {
56
56
  path: customerSupportPaths.customer_list.path,
57
57
  name: customerSupportPaths.customer_list.name,
58
- component: () => import("./CustomerSupportTicketList-CKZl8jxx.js"),
58
+ component: () => import("./CustomerSupportTicketList-CpOaBgNr.js"),
59
59
  beforeEnter: (to) => customerListPresetGuard(to),
60
60
  meta: {
61
61
  title: "Tickets",
@@ -74,7 +74,7 @@ const customerSupportTicketRoutes = [{
74
74
  {
75
75
  path: customerSupportPaths.customer_create.path,
76
76
  name: customerSupportPaths.customer_create.name,
77
- component: () => import("./CustomerCreateSupportTicketForm-CiTTUqtW.js"),
77
+ component: () => import("./CustomerCreateSupportTicketForm-CroUyX15.js"),
78
78
  meta: {
79
79
  title: "Create Support Ticket",
80
80
  description: "Create new support ticket",
@@ -90,7 +90,7 @@ const customerSupportTicketRoutes = [{
90
90
  {
91
91
  path: customerSupportPaths.customer_create_success.path,
92
92
  name: customerSupportPaths.customer_create_success.name,
93
- component: () => import("./CustomerSupportTicketSuccess-BJO2xsQR.js"),
93
+ component: () => import("./CustomerSupportTicketSuccess-BPUwEn4h.js"),
94
94
  meta: {
95
95
  title: "Support Ticket Submitted",
96
96
  description: "Support ticket submitted successfully",
@@ -120,7 +120,7 @@ const customerSupportTicketRoutes = [{
120
120
  children: [{
121
121
  path: "",
122
122
  name: customerSupportPaths.customer_view.name,
123
- component: () => import("./CustomerSupportTicketDetailPage-DAwiE2t6.js"),
123
+ component: () => import("./CustomerSupportTicketDetailPage-Dengb4Zx.js"),
124
124
  meta: {
125
125
  title: "View Support Ticket",
126
126
  description: "View support ticket details"
@@ -139,4 +139,4 @@ const customerSupportTicketRoutes = [{
139
139
 
140
140
  //#endregion
141
141
  export { customerSupportTicketRoutes as n, customerSupportPaths as t };
142
- //# sourceMappingURL=customerSupportTicketRoutes-C-DKBy5g.js.map
142
+ //# sourceMappingURL=customerSupportTicketRoutes-DvfXGaSC.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"customerSupportTicketRoutes-C-DKBy5g.js","names":["customerSupportTicketRoutes: Array<ExtendedRouteRecordRaw>"],"sources":["../src/slices/support_ticket/customer/customerSupportTicketRoutes.ts"],"sourcesContent":["import { createLastUsedPresetGuard } from '../../../slices/saved_filter';\nimport { userAuthenticated } from '../../../middleware/userAuthorized';\nimport type { ExtendedRouteRecordRaw } from '../../../types/ExtendedRoute';\n\nconst customerListPresetGuard = createLastUsedPresetGuard('support_ticket_customer', 'CustomerSupportTicketList');\n\nexport const customerSupportPaths = {\n customer_list: {\n path: '',\n full_path: '/support',\n name: 'CustomerSupportTicketList',\n },\n customer_create: {\n path: 'create',\n full_path: '/support/create',\n name: 'CustomerCreateSupportTicket',\n },\n customer_create_success: {\n path: 'create/success',\n full_path: '/support/create/success',\n name: 'CustomerSupportTicketSuccess',\n },\n customer_view: {\n path: ':id',\n full_path: '/support/:id',\n name: 'CustomerViewSupportTicket',\n },\n customer_edit: {\n path: 'edit',\n full_path: '/support/:id/edit',\n name: 'CustomerEditSupportTicket',\n },\n customer_customer_notes: {\n path: 'customer-notes',\n full_path: '/support/:id/customer-notes',\n name: 'CustomerSupportTicketCustomerNotes',\n },\n customer_history: {\n path: 'history',\n full_path: '/support/:id/history',\n name: 'CustomerSupportTicketHistory',\n },\n customer_attachments: {\n path: 'attachments',\n full_path: '/support/:id/attachments',\n name: 'CustomerSupportTicketAttachments',\n },\n} as const;\n\nexport const customerSupportTicketRoutes: Array<ExtendedRouteRecordRaw> = [\n {\n path: '/support',\n name: 'CustomerSupportTicket',\n redirect: { name: customerSupportPaths.customer_list.name },\n beforeEnter: [userAuthenticated],\n meta: {},\n children: [\n {\n path: customerSupportPaths.customer_list.path,\n name: customerSupportPaths.customer_list.name,\n component: () => import('./CustomerSupportTicketList.vue'),\n beforeEnter: (to) => customerListPresetGuard(to),\n meta: {\n title: 'Tickets',\n description: 'Support tickets',\n side_bar: {\n section: 'Support',\n visible_to: ['consumer', 'lead', 'staff', 'super_admin'],\n },\n },\n },\n {\n path: customerSupportPaths.customer_create.path,\n name: customerSupportPaths.customer_create.name,\n component: () => import('./CustomerCreateSupportTicketForm.vue'),\n meta: {\n title: 'Create Support Ticket',\n description: 'Create new support ticket',\n breadcrumbs: [\n {\n label: 'Support',\n to: { name: customerSupportPaths.customer_list.name },\n },\n {\n label: 'Create',\n to: { name: customerSupportPaths.customer_create.name },\n },\n ],\n },\n },\n {\n path: customerSupportPaths.customer_create_success.path,\n name: customerSupportPaths.customer_create_success.name,\n component: () => import('./CustomerSupportTicketSuccess.vue'),\n meta: {\n title: 'Support Ticket Submitted',\n description: 'Support ticket submitted successfully',\n breadcrumbs: [\n {\n label: 'Support',\n to: { name: customerSupportPaths.customer_list.name },\n },\n {\n label: 'Create',\n to: { name: customerSupportPaths.customer_create.name },\n },\n {\n label: 'Success',\n to: { name: customerSupportPaths.customer_create_success.name },\n },\n ],\n },\n },\n {\n path: customerSupportPaths.customer_view.path,\n component: () => import('./CustomerSupportTicketParent.vue'),\n meta: {\n title: 'View Support Ticket',\n description: 'View support ticket details',\n },\n children: [\n {\n path: '',\n name: customerSupportPaths.customer_view.name,\n component: () => import('./CustomerSupportTicketDetailPage.vue'),\n meta: {\n title: 'View Support Ticket',\n description: 'View support ticket details',\n },\n },\n {\n path: customerSupportPaths.customer_edit.path,\n redirect: (to) => ({\n name: customerSupportPaths.customer_view.name,\n params: { id: to.params.id },\n query: { mode: 'edit' },\n }),\n },\n ],\n },\n ],\n },\n];\n"],"mappings":";;;;AAIA,MAAM,0BAA0B,0BAA0B,2BAA2B,4BAA4B;AAEjH,MAAa,uBAAuB;CAClC,eAAe;EACb,MAAM;EACN,WAAW;EACX,MAAM;EACP;CACD,iBAAiB;EACf,MAAM;EACN,WAAW;EACX,MAAM;EACP;CACD,yBAAyB;EACvB,MAAM;EACN,WAAW;EACX,MAAM;EACP;CACD,eAAe;EACb,MAAM;EACN,WAAW;EACX,MAAM;EACP;CACD,eAAe;EACb,MAAM;EACN,WAAW;EACX,MAAM;EACP;CACD,yBAAyB;EACvB,MAAM;EACN,WAAW;EACX,MAAM;EACP;CACD,kBAAkB;EAChB,MAAM;EACN,WAAW;EACX,MAAM;EACP;CACD,sBAAsB;EACpB,MAAM;EACN,WAAW;EACX,MAAM;EACP;CACF;AAED,MAAaA,8BAA6D,CACxE;CACE,MAAM;CACN,MAAM;CACN,UAAU,EAAE,MAAM,qBAAqB,cAAc,MAAM;CAC3D,aAAa,CAAC,kBAAkB;CAChC,MAAM,EAAE;CACR,UAAU;EACR;GACE,MAAM,qBAAqB,cAAc;GACzC,MAAM,qBAAqB,cAAc;GACzC,iBAAiB,OAAO;GACxB,cAAc,OAAO,wBAAwB,GAAG;GAChD,MAAM;IACJ,OAAO;IACP,aAAa;IACb,UAAU;KACR,SAAS;KACT,YAAY;MAAC;MAAY;MAAQ;MAAS;MAAc;KACzD;IACF;GACF;EACD;GACE,MAAM,qBAAqB,gBAAgB;GAC3C,MAAM,qBAAqB,gBAAgB;GAC3C,iBAAiB,OAAO;GACxB,MAAM;IACJ,OAAO;IACP,aAAa;IACb,aAAa,CACX;KACE,OAAO;KACP,IAAI,EAAE,MAAM,qBAAqB,cAAc,MAAM;KACtD,EACD;KACE,OAAO;KACP,IAAI,EAAE,MAAM,qBAAqB,gBAAgB,MAAM;KACxD,CACF;IACF;GACF;EACD;GACE,MAAM,qBAAqB,wBAAwB;GACnD,MAAM,qBAAqB,wBAAwB;GACnD,iBAAiB,OAAO;GACxB,MAAM;IACJ,OAAO;IACP,aAAa;IACb,aAAa;KACX;MACE,OAAO;MACP,IAAI,EAAE,MAAM,qBAAqB,cAAc,MAAM;MACtD;KACD;MACE,OAAO;MACP,IAAI,EAAE,MAAM,qBAAqB,gBAAgB,MAAM;MACxD;KACD;MACE,OAAO;MACP,IAAI,EAAE,MAAM,qBAAqB,wBAAwB,MAAM;MAChE;KACF;IACF;GACF;EACD;GACE,MAAM,qBAAqB,cAAc;GACzC,iBAAiB,OAAO;GACxB,MAAM;IACJ,OAAO;IACP,aAAa;IACd;GACD,UAAU,CACR;IACE,MAAM;IACN,MAAM,qBAAqB,cAAc;IACzC,iBAAiB,OAAO;IACxB,MAAM;KACJ,OAAO;KACP,aAAa;KACd;IACF,EACD;IACE,MAAM,qBAAqB,cAAc;IACzC,WAAW,QAAQ;KACjB,MAAM,qBAAqB,cAAc;KACzC,QAAQ,EAAE,IAAI,GAAG,OAAO,IAAI;KAC5B,OAAO,EAAE,MAAM,QAAQ;KACxB;IACF,CACF;GACF;EACF;CACF,CACF"}
1
+ {"version":3,"file":"customerSupportTicketRoutes-DvfXGaSC.js","names":["customerSupportTicketRoutes: Array<ExtendedRouteRecordRaw>"],"sources":["../src/slices/support_ticket/customer/customerSupportTicketRoutes.ts"],"sourcesContent":["import { createLastUsedPresetGuard } from '../../../slices/saved_filter';\nimport { userAuthenticated } from '../../../middleware/userAuthorized';\nimport type { ExtendedRouteRecordRaw } from '../../../types/ExtendedRoute';\n\nconst customerListPresetGuard = createLastUsedPresetGuard('support_ticket_customer', 'CustomerSupportTicketList');\n\nexport const customerSupportPaths = {\n customer_list: {\n path: '',\n full_path: '/support',\n name: 'CustomerSupportTicketList',\n },\n customer_create: {\n path: 'create',\n full_path: '/support/create',\n name: 'CustomerCreateSupportTicket',\n },\n customer_create_success: {\n path: 'create/success',\n full_path: '/support/create/success',\n name: 'CustomerSupportTicketSuccess',\n },\n customer_view: {\n path: ':id',\n full_path: '/support/:id',\n name: 'CustomerViewSupportTicket',\n },\n customer_edit: {\n path: 'edit',\n full_path: '/support/:id/edit',\n name: 'CustomerEditSupportTicket',\n },\n customer_customer_notes: {\n path: 'customer-notes',\n full_path: '/support/:id/customer-notes',\n name: 'CustomerSupportTicketCustomerNotes',\n },\n customer_history: {\n path: 'history',\n full_path: '/support/:id/history',\n name: 'CustomerSupportTicketHistory',\n },\n customer_attachments: {\n path: 'attachments',\n full_path: '/support/:id/attachments',\n name: 'CustomerSupportTicketAttachments',\n },\n} as const;\n\nexport const customerSupportTicketRoutes: Array<ExtendedRouteRecordRaw> = [\n {\n path: '/support',\n name: 'CustomerSupportTicket',\n redirect: { name: customerSupportPaths.customer_list.name },\n beforeEnter: [userAuthenticated],\n meta: {},\n children: [\n {\n path: customerSupportPaths.customer_list.path,\n name: customerSupportPaths.customer_list.name,\n component: () => import('./CustomerSupportTicketList.vue'),\n beforeEnter: (to) => customerListPresetGuard(to),\n meta: {\n title: 'Tickets',\n description: 'Support tickets',\n side_bar: {\n section: 'Support',\n visible_to: ['consumer', 'lead', 'staff', 'super_admin'],\n },\n },\n },\n {\n path: customerSupportPaths.customer_create.path,\n name: customerSupportPaths.customer_create.name,\n component: () => import('./CustomerCreateSupportTicketForm.vue'),\n meta: {\n title: 'Create Support Ticket',\n description: 'Create new support ticket',\n breadcrumbs: [\n {\n label: 'Support',\n to: { name: customerSupportPaths.customer_list.name },\n },\n {\n label: 'Create',\n to: { name: customerSupportPaths.customer_create.name },\n },\n ],\n },\n },\n {\n path: customerSupportPaths.customer_create_success.path,\n name: customerSupportPaths.customer_create_success.name,\n component: () => import('./CustomerSupportTicketSuccess.vue'),\n meta: {\n title: 'Support Ticket Submitted',\n description: 'Support ticket submitted successfully',\n breadcrumbs: [\n {\n label: 'Support',\n to: { name: customerSupportPaths.customer_list.name },\n },\n {\n label: 'Create',\n to: { name: customerSupportPaths.customer_create.name },\n },\n {\n label: 'Success',\n to: { name: customerSupportPaths.customer_create_success.name },\n },\n ],\n },\n },\n {\n path: customerSupportPaths.customer_view.path,\n component: () => import('./CustomerSupportTicketParent.vue'),\n meta: {\n title: 'View Support Ticket',\n description: 'View support ticket details',\n },\n children: [\n {\n path: '',\n name: customerSupportPaths.customer_view.name,\n component: () => import('./CustomerSupportTicketDetailPage.vue'),\n meta: {\n title: 'View Support Ticket',\n description: 'View support ticket details',\n },\n },\n {\n path: customerSupportPaths.customer_edit.path,\n redirect: (to) => ({\n name: customerSupportPaths.customer_view.name,\n params: { id: to.params.id },\n query: { mode: 'edit' },\n }),\n },\n ],\n },\n ],\n },\n];\n"],"mappings":";;;;AAIA,MAAM,0BAA0B,0BAA0B,2BAA2B,4BAA4B;AAEjH,MAAa,uBAAuB;CAClC,eAAe;EACb,MAAM;EACN,WAAW;EACX,MAAM;EACP;CACD,iBAAiB;EACf,MAAM;EACN,WAAW;EACX,MAAM;EACP;CACD,yBAAyB;EACvB,MAAM;EACN,WAAW;EACX,MAAM;EACP;CACD,eAAe;EACb,MAAM;EACN,WAAW;EACX,MAAM;EACP;CACD,eAAe;EACb,MAAM;EACN,WAAW;EACX,MAAM;EACP;CACD,yBAAyB;EACvB,MAAM;EACN,WAAW;EACX,MAAM;EACP;CACD,kBAAkB;EAChB,MAAM;EACN,WAAW;EACX,MAAM;EACP;CACD,sBAAsB;EACpB,MAAM;EACN,WAAW;EACX,MAAM;EACP;CACF;AAED,MAAaA,8BAA6D,CACxE;CACE,MAAM;CACN,MAAM;CACN,UAAU,EAAE,MAAM,qBAAqB,cAAc,MAAM;CAC3D,aAAa,CAAC,kBAAkB;CAChC,MAAM,EAAE;CACR,UAAU;EACR;GACE,MAAM,qBAAqB,cAAc;GACzC,MAAM,qBAAqB,cAAc;GACzC,iBAAiB,OAAO;GACxB,cAAc,OAAO,wBAAwB,GAAG;GAChD,MAAM;IACJ,OAAO;IACP,aAAa;IACb,UAAU;KACR,SAAS;KACT,YAAY;MAAC;MAAY;MAAQ;MAAS;MAAc;KACzD;IACF;GACF;EACD;GACE,MAAM,qBAAqB,gBAAgB;GAC3C,MAAM,qBAAqB,gBAAgB;GAC3C,iBAAiB,OAAO;GACxB,MAAM;IACJ,OAAO;IACP,aAAa;IACb,aAAa,CACX;KACE,OAAO;KACP,IAAI,EAAE,MAAM,qBAAqB,cAAc,MAAM;KACtD,EACD;KACE,OAAO;KACP,IAAI,EAAE,MAAM,qBAAqB,gBAAgB,MAAM;KACxD,CACF;IACF;GACF;EACD;GACE,MAAM,qBAAqB,wBAAwB;GACnD,MAAM,qBAAqB,wBAAwB;GACnD,iBAAiB,OAAO;GACxB,MAAM;IACJ,OAAO;IACP,aAAa;IACb,aAAa;KACX;MACE,OAAO;MACP,IAAI,EAAE,MAAM,qBAAqB,cAAc,MAAM;MACtD;KACD;MACE,OAAO;MACP,IAAI,EAAE,MAAM,qBAAqB,gBAAgB,MAAM;MACxD;KACD;MACE,OAAO;MACP,IAAI,EAAE,MAAM,qBAAqB,wBAAwB,MAAM;MAChE;KACF;IACF;GACF;EACD;GACE,MAAM,qBAAqB,cAAc;GACzC,iBAAiB,OAAO;GACxB,MAAM;IACJ,OAAO;IACP,aAAa;IACd;GACD,UAAU,CACR;IACE,MAAM;IACN,MAAM,qBAAqB,cAAc;IACzC,iBAAiB,OAAO;IACxB,MAAM;KACJ,OAAO;KACP,aAAa;KACd;IACF,EACD;IACE,MAAM,qBAAqB,cAAc;IACzC,WAAW,QAAQ;KACjB,MAAM,qBAAqB,cAAc;KACzC,QAAQ,EAAE,IAAI,GAAG,OAAO,IAAI;KAC5B,OAAO,EAAE,MAAM,QAAQ;KACxB;IACF,CACF;GACF;EACF;CACF,CACF"}