@mesob/auth-react 0.5.8 → 0.5.10

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 (152) hide show
  1. package/dist/{chunk-YP5V56LW.js → chunk-22KICA5N.js} +3 -3
  2. package/dist/{chunk-XLPPZKU2.js → chunk-22WSB5V2.js} +15 -5
  3. package/dist/chunk-22WSB5V2.js.map +1 -0
  4. package/dist/{chunk-GQFTH5DQ.js → chunk-25DJGLNU.js} +12 -8
  5. package/dist/chunk-25DJGLNU.js.map +1 -0
  6. package/dist/{chunk-W2HMARW4.js → chunk-2BF2JIDK.js} +3 -3
  7. package/dist/{chunk-4LHFPVAY.js → chunk-4YPLJ2P6.js} +7 -13
  8. package/dist/chunk-4YPLJ2P6.js.map +1 -0
  9. package/dist/{chunk-SA6HTWCL.js → chunk-5FNUPWPO.js} +2 -2
  10. package/dist/{chunk-6AV6I5B4.js → chunk-75K2SCNC.js} +3 -3
  11. package/dist/{chunk-YCVDEX5U.js → chunk-7QJBDRTL.js} +6 -5
  12. package/dist/chunk-7QJBDRTL.js.map +1 -0
  13. package/dist/{chunk-FCPN2FD7.js → chunk-B7BS57X7.js} +10 -4
  14. package/dist/chunk-B7BS57X7.js.map +1 -0
  15. package/dist/{chunk-FLGP4ROM.js → chunk-CBR5NTFM.js} +14 -8
  16. package/dist/chunk-CBR5NTFM.js.map +1 -0
  17. package/dist/chunk-DBTKXQV7.js +13 -0
  18. package/dist/chunk-DBTKXQV7.js.map +1 -0
  19. package/dist/{chunk-PUOQX6DR.js → chunk-DQB4WY5T.js} +4 -4
  20. package/dist/{chunk-TPG4RW7H.js → chunk-DRAUYDZ5.js} +2 -2
  21. package/dist/{chunk-IBRB7ABJ.js → chunk-G2RWFKGF.js} +2 -2
  22. package/dist/{chunk-EIJFTUTM.js → chunk-GP4XI5KB.js} +3 -3
  23. package/dist/{chunk-22AQI2FA.js → chunk-GWRMQSME.js} +5 -5
  24. package/dist/{chunk-XO5LLEGV.js → chunk-HOROLWBY.js} +2 -2
  25. package/dist/{chunk-YVHMCTLM.js → chunk-I46PN4JU.js} +2 -2
  26. package/dist/{chunk-VS5FEGMX.js → chunk-IUCTHMVY.js} +2 -2
  27. package/dist/{chunk-IFFWIROT.js → chunk-J7NROVB4.js} +2 -2
  28. package/dist/{chunk-FU4K62DS.js → chunk-KL2XZKDU.js} +2 -2
  29. package/dist/{chunk-VMAGFUOK.js → chunk-LI7WPOVY.js} +3 -3
  30. package/dist/{chunk-I34SXFQJ.js → chunk-LYCBL2W3.js} +4 -4
  31. package/dist/{chunk-A5ON3RKH.js → chunk-M2K6O5CN.js} +2 -2
  32. package/dist/chunk-M2K6O5CN.js.map +1 -0
  33. package/dist/{chunk-G4VPR4UC.js → chunk-M677DPBR.js} +2 -2
  34. package/dist/{chunk-BX75EFF3.js → chunk-MPZAPUVR.js} +4 -4
  35. package/dist/{chunk-V7HCZDJ4.js → chunk-NJGVOQIU.js} +4 -4
  36. package/dist/{chunk-HBQK5PAH.js → chunk-NPA7L57G.js} +2 -2
  37. package/dist/{chunk-TAJQ7O3U.js → chunk-ORQZZUVL.js} +2 -2
  38. package/dist/{chunk-5B6GREDA.js → chunk-OT2H5EHA.js} +2 -2
  39. package/dist/{chunk-NTDVUVZO.js → chunk-QNPK2H5A.js} +3 -3
  40. package/dist/{chunk-MDM3QYPM.js → chunk-QRYUUXNJ.js} +7 -6
  41. package/dist/chunk-QRYUUXNJ.js.map +1 -0
  42. package/dist/{chunk-Z4FXOZEJ.js → chunk-R7VVXH5U.js} +3 -3
  43. package/dist/{chunk-3GFTD46V.js → chunk-SLIIENXJ.js} +2 -2
  44. package/dist/{chunk-VWYJI2FU.js → chunk-TT3V6PC7.js} +4 -4
  45. package/dist/{chunk-ZOKBN5H4.js → chunk-UIXR5GF3.js} +2 -2
  46. package/dist/{chunk-XZAYLXLS.js → chunk-UV7JR3YU.js} +2 -2
  47. package/dist/{chunk-SX6WAVQS.js → chunk-VTANFZKG.js} +5 -5
  48. package/dist/{chunk-5XCUGCW7.js → chunk-VWGOCWRF.js} +9 -6
  49. package/dist/chunk-VWGOCWRF.js.map +1 -0
  50. package/dist/{chunk-WOJ3HM5R.js → chunk-WAMZL5CS.js} +4 -4
  51. package/dist/{chunk-DCWKYK3D.js → chunk-WY2F7475.js} +18 -10
  52. package/dist/chunk-WY2F7475.js.map +1 -0
  53. package/dist/{chunk-OMTV6IOB.js → chunk-XTLFZ77E.js} +2 -2
  54. package/dist/chunk-XTLFZ77E.js.map +1 -0
  55. package/dist/{chunk-H2W42KYL.js → chunk-Y6KURGWG.js} +2 -2
  56. package/dist/chunk-YR6SS2CC.js +11 -0
  57. package/dist/chunk-YR6SS2CC.js.map +1 -0
  58. package/dist/{chunk-BM3YKYGC.js → chunk-ZIUAYN37.js} +2 -2
  59. package/dist/components/auth/countdown.js +3 -3
  60. package/dist/components/auth/forgot-password.js +5 -3
  61. package/dist/components/auth/reset-password-form.js +3 -3
  62. package/dist/components/auth/set-password.js +5 -4
  63. package/dist/components/auth/sign-in.js +5 -4
  64. package/dist/components/auth/sign-up.js +5 -3
  65. package/dist/components/auth/verification-form.js +4 -4
  66. package/dist/components/auth/verify-email.js +5 -5
  67. package/dist/components/auth/verify-phone.js +5 -5
  68. package/dist/components/authorization/deny.js +2 -2
  69. package/dist/components/authorization/grant.js +2 -2
  70. package/dist/components/iam/domains-page.js +6 -6
  71. package/dist/components/iam/iam-guard.js +3 -3
  72. package/dist/components/iam/permission-selector.js +2 -2
  73. package/dist/components/iam/permissions-page.js +4 -4
  74. package/dist/components/iam/permissions.js +2 -2
  75. package/dist/components/iam/role-detail-layout.js +2 -2
  76. package/dist/components/iam/role-detail-page.js +4 -4
  77. package/dist/components/iam/role-permissions-page.js +5 -5
  78. package/dist/components/iam/roles-page.js +6 -6
  79. package/dist/components/iam/roles.js +2 -2
  80. package/dist/components/iam/sessions-page.js +6 -6
  81. package/dist/components/iam/sessions.js +2 -2
  82. package/dist/components/iam/tenants-page.js +6 -6
  83. package/dist/components/iam/tenants.js +2 -2
  84. package/dist/components/iam/users-page.js +7 -7
  85. package/dist/components/iam/users.js +2 -2
  86. package/dist/components/profile/account.js +2 -2
  87. package/dist/components/profile/change-email-form.js +8 -8
  88. package/dist/components/profile/change-password-form.js +2 -2
  89. package/dist/components/profile/change-phone-form.js +9 -9
  90. package/dist/components/profile/otp-verification-modal.js +5 -5
  91. package/dist/components/profile/profile-layout.js +3 -3
  92. package/dist/components/profile/request-change-email-form.js +2 -2
  93. package/dist/components/profile/request-change-phone-form.js +3 -3
  94. package/dist/components/profile/security.js +14 -14
  95. package/dist/components/profile/verify-change-email-form.js +6 -6
  96. package/dist/components/profile/verify-change-phone-form.js +6 -6
  97. package/dist/index.d.ts +1 -0
  98. package/dist/index.js +48 -44
  99. package/dist/index.js.map +1 -1
  100. package/dist/pages/auth/layout.js +1 -1
  101. package/dist/pages/iam/tenants/tenant-selector.js +3 -3
  102. package/dist/pages/iam/users/user-selector.js +4 -4
  103. package/dist/pages/profile/account.js +1 -1
  104. package/dist/pages/profile/security.js +1 -1
  105. package/dist/utils/normalize-email.d.ts +2 -0
  106. package/dist/utils/normalize-phone.d.ts +1 -0
  107. package/package.json +4 -4
  108. package/dist/chunk-4LHFPVAY.js.map +0 -1
  109. package/dist/chunk-5XCUGCW7.js.map +0 -1
  110. package/dist/chunk-A5ON3RKH.js.map +0 -1
  111. package/dist/chunk-DCWKYK3D.js.map +0 -1
  112. package/dist/chunk-FCPN2FD7.js.map +0 -1
  113. package/dist/chunk-FLGP4ROM.js.map +0 -1
  114. package/dist/chunk-GQFTH5DQ.js.map +0 -1
  115. package/dist/chunk-MDM3QYPM.js.map +0 -1
  116. package/dist/chunk-OMTV6IOB.js.map +0 -1
  117. package/dist/chunk-V2W3WPCZ.js +0 -22
  118. package/dist/chunk-V2W3WPCZ.js.map +0 -1
  119. package/dist/chunk-XLPPZKU2.js.map +0 -1
  120. package/dist/chunk-YCVDEX5U.js.map +0 -1
  121. /package/dist/{chunk-YP5V56LW.js.map → chunk-22KICA5N.js.map} +0 -0
  122. /package/dist/{chunk-W2HMARW4.js.map → chunk-2BF2JIDK.js.map} +0 -0
  123. /package/dist/{chunk-SA6HTWCL.js.map → chunk-5FNUPWPO.js.map} +0 -0
  124. /package/dist/{chunk-6AV6I5B4.js.map → chunk-75K2SCNC.js.map} +0 -0
  125. /package/dist/{chunk-PUOQX6DR.js.map → chunk-DQB4WY5T.js.map} +0 -0
  126. /package/dist/{chunk-TPG4RW7H.js.map → chunk-DRAUYDZ5.js.map} +0 -0
  127. /package/dist/{chunk-IBRB7ABJ.js.map → chunk-G2RWFKGF.js.map} +0 -0
  128. /package/dist/{chunk-EIJFTUTM.js.map → chunk-GP4XI5KB.js.map} +0 -0
  129. /package/dist/{chunk-22AQI2FA.js.map → chunk-GWRMQSME.js.map} +0 -0
  130. /package/dist/{chunk-XO5LLEGV.js.map → chunk-HOROLWBY.js.map} +0 -0
  131. /package/dist/{chunk-YVHMCTLM.js.map → chunk-I46PN4JU.js.map} +0 -0
  132. /package/dist/{chunk-VS5FEGMX.js.map → chunk-IUCTHMVY.js.map} +0 -0
  133. /package/dist/{chunk-IFFWIROT.js.map → chunk-J7NROVB4.js.map} +0 -0
  134. /package/dist/{chunk-FU4K62DS.js.map → chunk-KL2XZKDU.js.map} +0 -0
  135. /package/dist/{chunk-VMAGFUOK.js.map → chunk-LI7WPOVY.js.map} +0 -0
  136. /package/dist/{chunk-I34SXFQJ.js.map → chunk-LYCBL2W3.js.map} +0 -0
  137. /package/dist/{chunk-G4VPR4UC.js.map → chunk-M677DPBR.js.map} +0 -0
  138. /package/dist/{chunk-BX75EFF3.js.map → chunk-MPZAPUVR.js.map} +0 -0
  139. /package/dist/{chunk-V7HCZDJ4.js.map → chunk-NJGVOQIU.js.map} +0 -0
  140. /package/dist/{chunk-HBQK5PAH.js.map → chunk-NPA7L57G.js.map} +0 -0
  141. /package/dist/{chunk-TAJQ7O3U.js.map → chunk-ORQZZUVL.js.map} +0 -0
  142. /package/dist/{chunk-5B6GREDA.js.map → chunk-OT2H5EHA.js.map} +0 -0
  143. /package/dist/{chunk-NTDVUVZO.js.map → chunk-QNPK2H5A.js.map} +0 -0
  144. /package/dist/{chunk-Z4FXOZEJ.js.map → chunk-R7VVXH5U.js.map} +0 -0
  145. /package/dist/{chunk-3GFTD46V.js.map → chunk-SLIIENXJ.js.map} +0 -0
  146. /package/dist/{chunk-VWYJI2FU.js.map → chunk-TT3V6PC7.js.map} +0 -0
  147. /package/dist/{chunk-ZOKBN5H4.js.map → chunk-UIXR5GF3.js.map} +0 -0
  148. /package/dist/{chunk-XZAYLXLS.js.map → chunk-UV7JR3YU.js.map} +0 -0
  149. /package/dist/{chunk-SX6WAVQS.js.map → chunk-VTANFZKG.js.map} +0 -0
  150. /package/dist/{chunk-WOJ3HM5R.js.map → chunk-WAMZL5CS.js.map} +0 -0
  151. /package/dist/{chunk-H2W42KYL.js.map → chunk-Y6KURGWG.js.map} +0 -0
  152. /package/dist/{chunk-BM3YKYGC.js.map → chunk-ZIUAYN37.js.map} +0 -0
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/hooks/use-session-cookie-name.ts","../src/pages/iam/roles/users/_components/role-users-page.tsx","../src/pages/iam/tenants/tenant-detail-page-content.tsx","../src/pages/iam/users/_components/user-detail-layout-content.tsx","../src/pages/iam/users/_components/user-detail-page-content.tsx","../src/pages/iam/users/activity/user-activity-page-content.tsx","../src/pages/iam/users/activity/_components/role-section.tsx","../src/pages/iam/roles/_components/role-selector.tsx","../src/providers/nuqs-adapter.tsx"],"sourcesContent":["import { useConfig } from '../provider';\nimport { getSessionCookieName } from '../utils/cookie';\n\nexport function useSessionCookieName(): string {\n const { config } = useConfig();\n return getSessionCookieName(config);\n}\n","'use client';\n\nimport { IAMGuard } from '@mesob/auth-react/components/iam/iam-guard';\nimport { UserSelector } from '@mesob/auth-react/pages/iam/users/user-selector';\nimport type { User } from '@mesob/auth-react/pages/iam/users/users-data';\nimport {\n Avatar,\n AvatarFallback,\n AvatarImage,\n Badge,\n Button,\n DataTablePagination,\n DeleteConfirmButton,\n DisplayTable,\n EntityEmptyState,\n EntityFilter,\n EntityHeader,\n EntityLoadingState,\n EntitySearch,\n EntitySort,\n EntityViewToggle,\n PageBody,\n Tbody,\n Td,\n Th,\n Thead,\n Tr,\n useEntityPagination,\n useEntityParams,\n} from '@mesob/ui/components';\nimport { IconPlus, IconUser, IconUsers } from '@tabler/icons-react';\nimport { useQueryClient } from '@tanstack/react-query';\nimport type { ReactNode } from 'react';\nimport { useMemo } from 'react';\nimport { toast } from 'sonner';\nimport type { paths } from '../../../../../data/openapi';\nimport { authApi$ } from '../../../shared/page-helpers';\n\ntype RoleUsersPageProps = {\n roleId: string;\n};\n\nconst TABLE_COLUMN_COUNT = 4;\n\nfunction initials(user: User) {\n return user.fullName\n .split(' ')\n .filter(Boolean)\n .slice(0, 2)\n .map((part: string) => part[0]?.toUpperCase() ?? '')\n .join('');\n}\n\nfunction UserIdentity({ user }: { user: User }) {\n return (\n <div className=\"flex items-center gap-3\">\n <Avatar className=\"h-9 w-9\">\n <AvatarImage src={user.image ?? undefined} />\n <AvatarFallback>{initials(user)}</AvatarFallback>\n </Avatar>\n <div>\n <p className=\"font-medium\">{user.fullName}</p>\n </div>\n </div>\n );\n}\n\nfunction UserContact({ user }: { user: User }) {\n return (\n <div className=\"space-y-1\">\n {user.email ? (\n <div className=\"flex items-center gap-2\">\n <span>{user.email}</span>\n {user.emailVerified ? (\n <Badge variant=\"outline\">Verified</Badge>\n ) : null}\n </div>\n ) : null}\n {user.phone ? (\n <div className=\"flex items-center gap-2\">\n <span>{user.phone}</span>\n {user.phoneVerified ? (\n <Badge variant=\"outline\">Verified</Badge>\n ) : null}\n </div>\n ) : null}\n {user.email || user.phone ? null : (\n <span className=\"text-muted-foreground\">—</span>\n )}\n </div>\n );\n}\n\nfunction UserRemoveButton({\n roleId,\n userId,\n onRemove,\n}: {\n roleId: string;\n userId: string;\n onRemove: (roleId: string, userId: string) => void;\n}) {\n return (\n <DeleteConfirmButton\n entityName=\"user\"\n onConfirm={() => onRemove(roleId, userId)}\n triggerClassName=\"size-8 text-destructive hover:text-destructive\"\n />\n );\n}\n\nfunction RoleUsersTable({\n roleId,\n users,\n onRemove,\n}: {\n roleId: string;\n users: User[];\n onRemove: (roleId: string, userId: string) => void;\n}) {\n return (\n <DisplayTable withTableBorder>\n <Thead>\n <Tr>\n <Th>User</Th>\n <Th>Contact</Th>\n <Th>Last sign in</Th>\n <Th className=\"w-[60px]\" />\n </Tr>\n </Thead>\n <Tbody>\n {users.map((user) => (\n <Tr key={user.id}>\n <Td>\n <UserIdentity user={user} />\n </Td>\n <Td>\n <UserContact user={user} />\n </Td>\n <Td>\n {user.lastSignInAt\n ? new Date(user.lastSignInAt).toLocaleDateString()\n : 'Never'}\n </Td>\n <Td>\n <UserRemoveButton\n roleId={roleId}\n userId={user.id}\n onRemove={onRemove}\n />\n </Td>\n </Tr>\n ))}\n </Tbody>\n </DisplayTable>\n );\n}\n\nfunction RoleUsersCards({\n roleId,\n users,\n onRemove,\n}: {\n roleId: string;\n users: User[];\n onRemove: (roleId: string, userId: string) => void;\n}) {\n return (\n <div className=\"grid grid-cols-1 gap-4 md:grid-cols-2 xl:grid-cols-3\">\n {users.map((user) => (\n <div\n key={user.id}\n className=\"rounded-xl border border-border/60 bg-card p-4 shadow-sm\"\n >\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"space-y-3\">\n <div className=\"flex items-center gap-3\">\n <Avatar className=\"h-10 w-10\">\n <AvatarImage src={user.image ?? undefined} />\n <AvatarFallback>{initials(user)}</AvatarFallback>\n </Avatar>\n <div>\n <p className=\"font-semibold\">{user.fullName}</p>\n </div>\n </div>\n <div className=\"space-y-1 text-sm text-muted-foreground\">\n <p>{user.email ?? user.phone ?? 'No contact info'}</p>\n <p>\n Last sign in{' '}\n {user.lastSignInAt\n ? new Date(user.lastSignInAt).toLocaleDateString()\n : 'never'}\n </p>\n </div>\n </div>\n <UserRemoveButton\n roleId={roleId}\n userId={user.id}\n onRemove={onRemove}\n />\n </div>\n </div>\n ))}\n </div>\n );\n}\n\nexport function RoleUsersPage({ roleId }: RoleUsersPageProps) {\n return (\n <IAMGuard>\n <RoleUsersPageContent roleId={roleId} />\n </IAMGuard>\n );\n}\n\nfunction RoleUsersPageContent({ roleId }: RoleUsersPageProps) {\n const qc = useQueryClient();\n const { queryConfig, params, setParams } = useEntityParams({\n searchKey: 'search',\n defaultSort: 'fullName',\n defaultOrder: 'asc',\n });\n const usersQuery = useMemo(\n () =>\n ({\n params: {\n path: { id: roleId },\n query: queryConfig.params.query,\n },\n }) as {\n params: {\n path: { id: string };\n query: NonNullable<\n paths['/roles/{id}/users']['get']['parameters']['query']\n >;\n };\n },\n [queryConfig, roleId],\n );\n\n const { data, isPending, isFetching } = authApi$.useQuery(\n 'get',\n '/roles/{id}/users',\n usersQuery,\n { enabled: !!roleId },\n );\n const assignUsers = authApi$.useMutation('post', '/roles/{id}/users', {\n onSuccess: (result: { created?: number } | undefined) => {\n qc.invalidateQueries({ queryKey: ['get', '/roles'] });\n qc.invalidateQueries({ queryKey: ['get', '/roles/{id}'] });\n qc.invalidateQueries({ queryKey: ['get', '/roles/{id}/users'] });\n toast.success(\n result?.created ? `${result.created} user(s) added` : 'No changes',\n );\n },\n onError: () => {\n toast.error('Failed to assign users');\n },\n });\n const revokeUser = authApi$.useMutation(\n 'delete',\n '/roles/{id}/users/{userId}',\n {\n onSuccess: () => {\n qc.invalidateQueries({ queryKey: ['get', '/roles'] });\n qc.invalidateQueries({ queryKey: ['get', '/roles/{id}'] });\n qc.invalidateQueries({ queryKey: ['get', '/roles/{id}/users'] });\n toast.success('User removed');\n },\n onError: () => {\n toast.error('Failed to remove user');\n },\n },\n );\n\n const users = (data?.users ?? []) as User[];\n const { total, pageCount } = useEntityPagination({\n items: users,\n total: data?.total,\n pageSize: params.pageSize,\n });\n const isLoading = isPending || isFetching;\n const currentView = (params.view || 'table') as 'table' | 'card';\n const handleRemoveUser = (targetRoleId: string, userId: string) => {\n revokeUser.mutate({\n params: {\n path: { id: targetRoleId, userId },\n },\n });\n };\n\n if (!roleId) {\n return null;\n }\n\n let content: ReactNode;\n if (isLoading) {\n content = (\n <EntityLoadingState\n view={currentView}\n rowCount={params.pageSize}\n columnCount={TABLE_COLUMN_COUNT}\n cardCount={params.pageSize}\n />\n );\n } else if (total === 0) {\n content = (\n <EntityEmptyState\n icon={IconUsers}\n entityName=\"user\"\n title=\"No users assigned\"\n description=\"Assign users from the selector to add them to this role.\"\n />\n );\n } else if (currentView === 'table') {\n content = (\n <div className=\"space-y-4\">\n <RoleUsersTable\n roleId={roleId}\n users={users}\n onRemove={handleRemoveUser}\n />\n <DataTablePagination\n pageIndex={params.page - 1}\n pageSize={params.pageSize}\n pageCount={pageCount}\n totalRows={total}\n onPageChange={(page) => setParams({ page: page + 1 })}\n onPageSizeChange={(pageSize) => setParams({ pageSize, page: 1 })}\n />\n </div>\n );\n } else {\n content = (\n <div className=\"space-y-4\">\n <RoleUsersCards\n roleId={roleId}\n users={users}\n onRemove={handleRemoveUser}\n />\n <DataTablePagination\n pageIndex={params.page - 1}\n pageSize={params.pageSize}\n pageCount={pageCount}\n totalRows={total}\n onPageChange={(page) => setParams({ page: page + 1 })}\n onPageSizeChange={(pageSize) => setParams({ pageSize, page: 1 })}\n />\n </div>\n );\n }\n\n return (\n <PageBody className=\"px-0 pb-6\">\n <EntityHeader\n icon={<IconUser className=\"h-5 w-5\" />}\n title=\"Role users\"\n actions={\n <UserSelector\n trigger={\n <Button size=\"sm\" loading={assignUsers.isPending}>\n <IconPlus className=\"h-4 w-4\" />\n Add users\n </Button>\n }\n multiple\n excludeIds={users.map((user) => user.id)}\n onSelect={(selectedUsers: User[]) => {\n if (!selectedUsers.length) {\n return;\n }\n\n assignUsers.mutate({\n params: { path: { id: roleId } },\n body: {\n userIds: selectedUsers.map((user: User) => user.id),\n },\n });\n }}\n />\n }\n search={\n <EntitySearch\n paramKey=\"search\"\n placeholder=\"Search assigned users...\"\n />\n }\n filter={\n <EntityFilter\n options={[\n { label: 'All', value: '' },\n { label: 'Name', value: 'fullName' },\n { label: 'Email', value: 'email' },\n { label: 'Phone', value: 'phone' },\n ]}\n placeholder=\"Search field\"\n />\n }\n sort={\n <EntitySort\n defaultSort=\"fullName\"\n defaultOrder=\"asc\"\n options={[\n { label: 'Created', value: 'createdAt' },\n { label: 'Updated', value: 'updatedAt' },\n { label: 'Name', value: 'fullName' },\n { label: 'Last Sign In', value: 'lastSignInAt' },\n ]}\n />\n }\n view={<EntityViewToggle views={['table', 'card']} />}\n />\n {content}\n </PageBody>\n );\n}\n","'use client';\n\nimport { IAMGuard } from '@mesob/auth-react/components/iam/iam-guard';\nimport {\n Button,\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n EntityDetailHeader,\n PageContainer,\n type TabItem,\n useBreadcrumbs,\n} from '@mesob/ui/components';\nimport { IconBuilding } from '@tabler/icons-react';\nimport { useQueryClient } from '@tanstack/react-query';\nimport { useMemo } from 'react';\nimport { useApi, useConfig } from '../../../provider';\nimport { str } from './_components/tenants-data';\n\ntype TenantDetailPageContentProps = {\n tenantId: string;\n};\n\nexport function TenantDetailPageContent({\n tenantId,\n}: TenantDetailPageContentProps) {\n return (\n <IAMGuard>\n <TenantDetailPageContentInner tenantId={tenantId} />\n </IAMGuard>\n );\n}\n\nfunction TenantDetailPageContentInner({\n tenantId,\n}: TenantDetailPageContentProps) {\n const { hooks } = useApi();\n const { config } = useConfig();\n const homeHref = config.navigation?.defaultRedirectUrl || '/';\n const qc = useQueryClient();\n\n const { data, isLoading } = hooks.useQuery(\n 'get',\n '/tenants/{id}',\n { params: { path: { id: tenantId } } },\n { enabled: !!tenantId },\n );\n const tenant = data?.tenant;\n\n const toggleActive = hooks.useMutation('put', '/tenants/{id}', {\n onSuccess: () => {\n qc.invalidateQueries({ queryKey: ['get', '/tenants/{id}'] });\n qc.invalidateQueries({ queryKey: ['get', '/tenants'] });\n },\n });\n\n const title = tenant ? str(tenant.name) || tenant.id : (tenantId ?? 'Tenant');\n useBreadcrumbs({\n items: [\n { label: 'Home', href: homeHref },\n { label: 'IAM', href: '/iam' },\n { label: 'Tenants', href: '/iam/tenants' },\n { label: title },\n ],\n });\n\n const tabs: TabItem[] = useMemo(\n () => [\n {\n value: 'detail',\n name: 'Detail',\n content: (\n <Card className=\"mt-4\">\n <CardHeader>\n <CardTitle>Tenant details</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-2 text-sm\">\n {tenant && (\n <>\n <p>\n <span className=\"text-muted-foreground\">Name:</span>{' '}\n {str(tenant.name) || '—'}\n </p>\n <p>\n <span className=\"text-muted-foreground\">Description:</span>{' '}\n {str(tenant.description) || '—'}\n </p>\n <p>\n <span className=\"text-muted-foreground\">Language:</span>{' '}\n {tenant.defaultLanguage ?? '—'}\n </p>\n <p>\n <span className=\"text-muted-foreground\">Currency:</span>{' '}\n {tenant.defaultCurrency ?? '—'}\n </p>\n <p>\n <span className=\"text-muted-foreground\">Timezone:</span>{' '}\n {tenant.timezone ?? '—'}\n </p>\n </>\n )}\n </CardContent>\n </Card>\n ),\n },\n {\n value: 'theme',\n name: 'Theme',\n content: (\n <Card className=\"mt-4\">\n <CardHeader>\n <CardTitle>Theme</CardTitle>\n </CardHeader>\n <CardContent className=\"text-muted-foreground text-sm\">\n Theme settings (placeholder)\n </CardContent>\n </Card>\n ),\n },\n {\n value: 'settings',\n name: 'Settings',\n content: (\n <Card className=\"mt-4\">\n <CardHeader>\n <CardTitle>Settings</CardTitle>\n </CardHeader>\n <CardContent className=\"text-muted-foreground text-sm\">\n Tenant settings (placeholder)\n </CardContent>\n </Card>\n ),\n },\n ],\n [tenant],\n );\n\n const actions = tenant && (\n <Button\n variant={tenant.isActive ? 'secondary' : 'default'}\n size=\"sm\"\n onClick={() =>\n toggleActive.mutate({\n params: { path: { id: tenantId } },\n body: { isActive: !tenant.isActive },\n })\n }\n disabled={toggleActive.isPending}\n >\n {tenant.isActive ? 'Deactivate' : 'Activate'}\n </Button>\n );\n\n if (!tenantId) {\n return null;\n }\n if (isLoading || !tenant) {\n return (\n <div className=\"flex flex-1 flex-col gap-4 p-4 pt-0\">\n <div className=\"h-24 animate-pulse rounded-xl bg-muted\" />\n </div>\n );\n }\n\n return (\n <PageContainer className=\"flex flex-1 flex-col gap-4 p-4 pt-0\">\n <EntityDetailHeader\n title={title}\n icon={<IconBuilding className=\"h-5 w-5 text-muted-foreground\" />}\n actions={actions}\n tabs={tabs}\n />\n </PageContainer>\n );\n}\n","'use client';\n\nimport { IAMGuard } from '@mesob/auth-react/components/iam/iam-guard';\nimport { toTitleCase } from '@mesob/common';\nimport {\n Button,\n EntityDetailHeader,\n PageContainer,\n type TabItem,\n useBreadcrumbs,\n} from '@mesob/ui/components';\nimport { IconUser } from '@tabler/icons-react';\nimport { useMemo } from 'react';\nimport { useApi, useConfig } from '../../../../provider';\n\ntype UserDetailLayoutContentProps = {\n userId: string;\n children: React.ReactNode;\n};\n\nexport function UserDetailLayoutContent({\n userId,\n children,\n}: UserDetailLayoutContentProps) {\n return (\n <IAMGuard>\n <UserDetailLayoutContentInner userId={userId}>\n {children}\n </UserDetailLayoutContentInner>\n </IAMGuard>\n );\n}\n\nfunction UserDetailLayoutContentInner({\n userId,\n children,\n}: UserDetailLayoutContentProps) {\n const { hooks } = useApi();\n const { config } = useConfig();\n const homeHref = config.navigation?.defaultRedirectUrl || '/';\n const { data, isLoading } = hooks.useQuery(\n 'get',\n '/users/{id}',\n { params: { path: { id: userId } } },\n { enabled: !!userId },\n );\n const user = data?.user;\n\n const title = toTitleCase(user?.fullName || userId || 'User');\n\n useBreadcrumbs({\n items: [\n { label: 'Home', href: homeHref },\n { label: 'IAM', href: '/iam' },\n { label: 'Users', href: '/iam/users' },\n { label: title },\n ],\n });\n\n const tabs: TabItem[] = useMemo(\n () => [\n { value: 'detail', name: 'Detail', href: `/iam/users/${userId}` },\n {\n value: 'activity',\n name: 'Activity',\n href: `/iam/users/${userId}/activity`,\n },\n ],\n [userId],\n );\n\n if (!userId) {\n return null;\n }\n\n return (\n <PageContainer>\n <EntityDetailHeader\n title={title}\n icon={<IconUser />}\n tabs={tabs}\n loading={isLoading}\n actions={<Button>Test Button</Button>}\n />\n {children}\n </PageContainer>\n );\n}\n","'use client';\n\nimport { IAMGuard } from '@mesob/auth-react/components/iam/iam-guard';\nimport {\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from '@mesob/ui/components';\nimport { IconCircleCheck } from '@tabler/icons-react';\nimport { useApi } from '../../../../provider';\n\ntype UserDetailPageContentProps = {\n userId: string;\n};\n\nexport function UserDetailPageContent({ userId }: UserDetailPageContentProps) {\n return (\n <IAMGuard>\n <UserDetailPageContentInner userId={userId} />\n </IAMGuard>\n );\n}\n\nfunction UserDetailPageContentInner({ userId }: UserDetailPageContentProps) {\n const { hooks } = useApi();\n const { data, isLoading } = hooks.useQuery(\n 'get',\n '/users/{id}',\n { params: { path: { id: userId } } },\n { enabled: !!userId },\n );\n const user = data?.user;\n\n if (!userId) {\n return null;\n }\n if (isLoading || !user) {\n return <div className=\"h-32 animate-pulse rounded-xl bg-muted mt-4\" />;\n }\n\n return (\n <Card>\n <CardHeader>\n <CardTitle>User details</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-2 text-sm\">\n <p>\n <span className=\"text-muted-foreground\">Name:</span>{' '}\n {user.fullName || '—'}\n </p>\n <p>\n <span className=\"text-muted-foreground\">Email:</span>{' '}\n {user.email ?? '—'}{' '}\n {user.emailVerified && (\n <Tooltip>\n <TooltipTrigger>\n <IconCircleCheck className=\"inline size-4 text-muted-foreground\" />\n </TooltipTrigger>\n <TooltipContent>Email verified</TooltipContent>\n </Tooltip>\n )}\n </p>\n <p>\n <span className=\"text-muted-foreground\">Phone:</span>{' '}\n {user.phone ?? '—'}{' '}\n {user.phoneVerified && (\n <Tooltip>\n <TooltipTrigger>\n <IconCircleCheck className=\"inline size-4 text-muted-foreground\" />\n </TooltipTrigger>\n <TooltipContent>Phone verified</TooltipContent>\n </Tooltip>\n )}\n </p>\n <p>\n <span className=\"text-muted-foreground\">Last sign in:</span>{' '}\n {user.lastSignInAt\n ? new Date(user.lastSignInAt).toLocaleString()\n : 'Never'}\n </p>\n {user.roleCodes?.length ? (\n <p>\n <span className=\"text-muted-foreground\">Roles:</span>{' '}\n {user.roleCodes.join(', ')}\n </p>\n ) : null}\n </CardContent>\n </Card>\n );\n}\n","'use client';\n\nimport { IAMGuard } from '@mesob/auth-react/components/iam/iam-guard';\nimport {\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n Section,\n} from '@mesob/ui/components';\nimport { IconCalendar } from '@tabler/icons-react';\nimport { RoleSection } from './_components/role-section';\n\ntype UserActivityPageContentProps = {\n userId: string;\n};\n\nexport function UserActivityPageContent({\n userId,\n}: UserActivityPageContentProps) {\n return (\n <IAMGuard>\n <UserActivityPageContentInner userId={userId} />\n </IAMGuard>\n );\n}\n\nfunction UserActivityPageContentInner({\n userId,\n}: UserActivityPageContentProps) {\n if (!userId) {\n return null;\n }\n\n return (\n <div className=\"space-y-4\">\n <Card>\n <CardHeader>\n <CardTitle>Activity</CardTitle>\n </CardHeader>\n <CardContent className=\"flex items-center gap-2 text-muted-foreground text-sm\">\n <IconCalendar className=\"h-4 w-4\" />\n Activity (placeholder)\n </CardContent>\n </Card>\n <RoleSection userId={userId} />\n <Section title=\"Permissions\">test</Section>\n <Section title=\"Groups\">test</Section>\n </div>\n );\n}\n","'use client';\n\nimport {\n Button,\n EntityEmptyState,\n EntityLoadingState,\n EntitySection,\n useEntitySectionState,\n} from '@mesob/ui/components';\nimport { IconPlus, IconShield } from '@tabler/icons-react';\nimport { useMemo, useState } from 'react';\nimport { RoleSelector } from '../../../roles/_components/role-selector';\nimport type { Role } from '../../../roles/_components/roles-data';\nimport { str } from '../../../roles/_components/roles-data';\nimport { RolesList } from '../../../roles/_components/roles-list';\nimport {\n authApi$,\n defaultEntityQueryOptions,\n} from '../../../shared/page-helpers';\n\nconst LIMIT = 100;\nconst TABLE_COLUMN_COUNT = 4;\n\nfunction filterAndSort(\n roles: Role[],\n search: string,\n sort: string,\n order: 'asc' | 'desc',\n) {\n let out = roles;\n if (search.trim()) {\n const q = search.trim().toLowerCase();\n out = out.filter(\n (r) =>\n str(r.name).toLowerCase().includes(q) ||\n r.code.toLowerCase().includes(q),\n );\n }\n const mult = order === 'asc' ? 1 : -1;\n const by = sort === 'code' ? 'code' : 'createdAt';\n out = [...out].sort((a, b) =>\n by === 'code'\n ? mult * a.code.localeCompare(b.code)\n : mult *\n (new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime()),\n );\n return out;\n}\n\nexport function RoleSection({ userId }: { userId: string }) {\n const [open, setOpen] = useState(false);\n const sectionState = useEntitySectionState({\n defaultSort: 'createdAt',\n defaultOrder: 'desc',\n defaultPageSize: 10,\n filterOptions: [\n { label: 'All', value: '' },\n { label: 'By Code', value: 'code' },\n ],\n sortOptions: [\n { label: 'Created', value: 'createdAt' },\n { label: 'Updated', value: 'updatedAt' },\n { label: 'Code', value: 'code' },\n ],\n views: ['table', 'card'],\n });\n\n const { data, isPending, isFetching } = authApi$.useQuery(\n 'get',\n '/roles',\n { params: { query: { limit: LIMIT } } },\n { ...defaultEntityQueryOptions, enabled: open },\n );\n const isLoading = isPending || isFetching;\n const roles = data?.roles ?? [];\n\n const filtered = useMemo(\n () =>\n filterAndSort(\n roles,\n sectionState.search,\n sectionState.sort,\n sectionState.order,\n ),\n [roles, sectionState.search, sectionState.sort, sectionState.order],\n );\n const pageCount = Math.ceil(filtered.length / sectionState.pageSize) || 1;\n const pageIndex = Math.min(sectionState.page - 1, Math.max(0, pageCount - 1));\n const paginated = useMemo(\n () =>\n filtered.slice(\n pageIndex * sectionState.pageSize,\n pageIndex * sectionState.pageSize + sectionState.pageSize,\n ),\n [filtered, pageIndex, sectionState.pageSize],\n );\n\n return (\n <EntitySection\n title=\"Role\"\n state={sectionState}\n onOpenChange={setOpen}\n actions={\n <RoleSelector\n trigger={\n <Button variant=\"outline\" size=\"sm\">\n <IconPlus className=\"h-4 w-4\" />\n Add role\n </Button>\n }\n multiple\n onSelect={(roles) => {\n // TODO: assign roles to user; logging for now\n // biome-ignore lint/suspicious/noConsole: intentional for now\n console.log('Selected roles:', userId, roles);\n }}\n />\n }\n config={{\n searchPlaceholder: 'Search roles...',\n filterOptions: sectionState.filterOptions,\n sortOptions: sectionState.sortOptions,\n views: sectionState.views,\n }}\n >\n {(state) => (\n <>\n {isLoading && (\n <EntityLoadingState\n view={state.view as 'table' | 'card'}\n rowCount={state.pageSize}\n columnCount={TABLE_COLUMN_COUNT}\n cardCount={state.pageSize}\n />\n )}\n {!isLoading && filtered.length === 0 && (\n <EntityEmptyState\n icon={IconShield}\n entityName=\"role\"\n title=\"No roles\"\n description={\n roles.length === 0 ? 'No roles in tenant.' : 'No matches.'\n }\n />\n )}\n {!isLoading && filtered.length > 0 && (\n <RolesList\n data={paginated}\n view={state.view as 'table' | 'card'}\n pageIndex={pageIndex}\n pageSize={state.pageSize}\n pageCount={pageCount}\n totalRows={filtered.length}\n onPageChange={(p) => state.setPage(p + 1)}\n onPageSizeChange={(size) => {\n state.setPageSize(size);\n state.setPage(1);\n }}\n />\n )}\n </>\n )}\n </EntitySection>\n );\n}\n","'use client';\n\nimport {\n EntitySelector,\n type EntitySelectorColumn,\n type EntitySelectorConfig,\n useEntitySectionState,\n} from '@mesob/ui/components';\nimport { cn } from '@mesob/ui/lib/utils';\nimport { IconCalendar, IconShield } from '@tabler/icons-react';\nimport type { ReactNode } from 'react';\nimport type { paths } from '../../../../data/openapi';\nimport { authApi$, defaultEntityQueryOptions } from '../../shared/page-helpers';\nimport { RoleCard } from './role-card';\nimport type { Role } from './roles-data';\nimport { str } from './roles-data';\n\nfunction SelectableRoleCard({\n role,\n selected,\n onToggle,\n}: {\n role: Role;\n selected: boolean;\n onToggle: () => void;\n}) {\n return (\n // biome-ignore lint/a11y/useSemanticElements: div to avoid nested buttons from RoleCard\n <div\n role=\"button\"\n tabIndex={0}\n onClick={onToggle}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n onToggle();\n }\n }}\n className={cn(\n 'cursor-pointer rounded-lg transition-shadow focus:outline-none focus-visible:ring-2 focus-visible:ring-ring',\n selected && 'ring-primary ring-2',\n )}\n >\n <RoleCard role={role} mode=\"static\" />\n </div>\n );\n}\n\nconst roleColumns: EntitySelectorColumn<Role>[] = [\n {\n key: 'role',\n header: 'Role',\n cell: (role) => (\n <>\n <p className=\"font-medium\">{str(role.name) || role.code}</p>\n <p className=\"text-sm text-muted-foreground\">{role.code}</p>\n </>\n ),\n },\n {\n key: 'description',\n header: 'Description',\n cell: (role) => (\n <span className=\"text-muted-foreground line-clamp-1 max-w-[200px]\">\n {str(role.description) || '—'}\n </span>\n ),\n },\n {\n key: 'created',\n header: 'Created',\n cell: (role) => (\n <div className=\"flex items-center gap-1 text-muted-foreground\">\n <IconCalendar className=\"h-4 w-4\" />\n {new Date(role.createdAt).toLocaleDateString()}\n </div>\n ),\n },\n];\n\ntype RoleSelectorProps = {\n trigger: ReactNode;\n multiple?: boolean;\n onSelect: (roles: Role[]) => void;\n modalSize?: 'sm' | 'md' | 'lg' | 'xl' | 'full';\n contentClassName?: string;\n};\n\nexport function RoleSelector({\n trigger,\n multiple = true,\n onSelect,\n modalSize = 'xl',\n contentClassName,\n}: RoleSelectorProps) {\n const state = useEntitySectionState({\n defaultSort: 'createdAt',\n defaultOrder: 'desc',\n defaultPageSize: 10,\n searchParamName: 'search',\n });\n const rolesQuery = state.queryConfig as {\n params: {\n query: NonNullable<paths['/roles']['get']['parameters']['query']>;\n };\n };\n\n const { data, isPending, isFetching } = authApi$.useQuery(\n 'get',\n '/roles',\n rolesQuery,\n defaultEntityQueryOptions,\n );\n\n const roles = data?.roles ?? [];\n\n const config: EntitySelectorConfig<Role> = {\n title: 'Select role(s)',\n modalSize,\n contentClassName,\n multiple,\n entityName: 'role',\n entityIcon: IconShield,\n columns: roleColumns,\n columnCount: 3,\n getItemLabel: (role) => str(role.name) || role.code,\n searchPlaceholder: 'Search roles...',\n wrapHeaderInCard: false,\n filterOptions: [\n { label: 'All', value: '' },\n { label: 'By Code', value: 'code' },\n ],\n sortOptions: [\n { label: 'Created', value: 'createdAt' },\n { label: 'Updated', value: 'updatedAt' },\n { label: 'Code', value: 'code' },\n ],\n showViewToggle: false,\n renderCard: (role, selected, onToggle) => (\n <SelectableRoleCard role={role} selected={selected} onToggle={onToggle} />\n ),\n };\n\n return (\n <EntitySelector<Role>\n trigger={trigger}\n config={config}\n onSelect={onSelect}\n items={roles}\n total={data?.total}\n isLoading={isPending || isFetching}\n state={state}\n />\n );\n}\n","'use client';\n\nimport { NuqsAdapter } from 'nuqs/adapters/next/app';\nimport type { ReactNode } from 'react';\n\ntype NuqsAdapterWrapperProps = {\n children: ReactNode;\n};\n\nexport function NuqsAdapterWrapper({ children }: NuqsAdapterWrapperProps) {\n return <NuqsAdapter>{children}</NuqsAdapter>;\n}\n"],"mappings":"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","names":["IAMGuard","IAMGuard","IAMGuard","Button","useQueryClient","useMemo","jsx","jsxs","IAMGuard","useQueryClient","str","useMemo","Button","IAMGuard","Button","EntityDetailHeader","PageContainer","useBreadcrumbs","IconUser","useMemo","jsx","jsxs","IAMGuard","useBreadcrumbs","useMemo","PageContainer","EntityDetailHeader","IconUser","Button","IAMGuard","Card","CardContent","CardHeader","CardTitle","jsx","jsxs","IAMGuard","Card","CardHeader","CardTitle","CardContent","IAMGuard","Card","CardContent","CardHeader","CardTitle","IconCalendar","Button","EntityEmptyState","EntityLoadingState","useEntitySectionState","IconPlus","IconShield","useMemo","Fragment","jsx","jsxs","Fragment","jsx","jsxs","TABLE_COLUMN_COUNT","useEntitySectionState","useMemo","Button","IconPlus","roles","EntityLoadingState","EntityEmptyState","IconShield","jsx","jsxs","IAMGuard","Card","CardHeader","CardTitle","CardContent","IconCalendar","jsx"]}
1
+ {"version":3,"sources":["../src/hooks/use-session-cookie-name.ts","../src/pages/iam/roles/users/_components/role-users-page.tsx","../src/pages/iam/tenants/tenant-detail-page-content.tsx","../src/pages/iam/users/_components/user-detail-layout-content.tsx","../src/pages/iam/users/_components/user-detail-page-content.tsx","../src/pages/iam/users/activity/user-activity-page-content.tsx","../src/pages/iam/users/activity/_components/role-section.tsx","../src/pages/iam/roles/_components/role-selector.tsx","../src/providers/nuqs-adapter.tsx"],"sourcesContent":["import { useConfig } from '../provider';\nimport { getSessionCookieName } from '../utils/cookie';\n\nexport function useSessionCookieName(): string {\n const { config } = useConfig();\n return getSessionCookieName(config);\n}\n","'use client';\n\nimport { IAMGuard } from '@mesob/auth-react/components/iam/iam-guard';\nimport { UserSelector } from '@mesob/auth-react/pages/iam/users/user-selector';\nimport type { User } from '@mesob/auth-react/pages/iam/users/users-data';\nimport {\n Avatar,\n AvatarFallback,\n AvatarImage,\n Badge,\n Button,\n DataTablePagination,\n DeleteConfirmButton,\n DisplayTable,\n EntityEmptyState,\n EntityFilter,\n EntityHeader,\n EntityLoadingState,\n EntitySearch,\n EntitySort,\n EntityViewToggle,\n PageBody,\n Tbody,\n Td,\n Th,\n Thead,\n Tr,\n useEntityPagination,\n useEntityParams,\n} from '@mesob/ui/components';\nimport { IconPlus, IconUser, IconUsers } from '@tabler/icons-react';\nimport { useQueryClient } from '@tanstack/react-query';\nimport type { ReactNode } from 'react';\nimport { useMemo } from 'react';\nimport { toast } from 'sonner';\nimport type { paths } from '../../../../../data/openapi';\nimport { authApi$ } from '../../../shared/page-helpers';\n\ntype RoleUsersPageProps = {\n roleId: string;\n};\n\nconst TABLE_COLUMN_COUNT = 4;\n\nfunction initials(user: User) {\n return user.fullName\n .split(' ')\n .filter(Boolean)\n .slice(0, 2)\n .map((part: string) => part[0]?.toUpperCase() ?? '')\n .join('');\n}\n\nfunction UserIdentity({ user }: { user: User }) {\n return (\n <div className=\"flex items-center gap-3\">\n <Avatar className=\"h-9 w-9\">\n <AvatarImage src={user.image ?? undefined} />\n <AvatarFallback>{initials(user)}</AvatarFallback>\n </Avatar>\n <div>\n <p className=\"font-medium\">{user.fullName}</p>\n </div>\n </div>\n );\n}\n\nfunction UserContact({ user }: { user: User }) {\n return (\n <div className=\"space-y-1\">\n {user.email ? (\n <div className=\"flex items-center gap-2\">\n <span>{user.email}</span>\n {user.emailVerified ? (\n <Badge variant=\"outline\">Verified</Badge>\n ) : null}\n </div>\n ) : null}\n {user.phone ? (\n <div className=\"flex items-center gap-2\">\n <span>{user.phone}</span>\n {user.phoneVerified ? (\n <Badge variant=\"outline\">Verified</Badge>\n ) : null}\n </div>\n ) : null}\n {user.email || user.phone ? null : (\n <span className=\"text-muted-foreground\">—</span>\n )}\n </div>\n );\n}\n\nfunction UserRemoveButton({\n roleId,\n userId,\n onRemove,\n}: {\n roleId: string;\n userId: string;\n onRemove: (roleId: string, userId: string) => void;\n}) {\n return (\n <DeleteConfirmButton\n entityName=\"user\"\n onConfirm={() => onRemove(roleId, userId)}\n triggerClassName=\"size-8 text-destructive hover:text-destructive\"\n />\n );\n}\n\nfunction RoleUsersTable({\n roleId,\n users,\n onRemove,\n}: {\n roleId: string;\n users: User[];\n onRemove: (roleId: string, userId: string) => void;\n}) {\n return (\n <DisplayTable withTableBorder>\n <Thead>\n <Tr>\n <Th>User</Th>\n <Th>Contact</Th>\n <Th>Last sign in</Th>\n <Th className=\"w-[60px]\" />\n </Tr>\n </Thead>\n <Tbody>\n {users.map((user) => (\n <Tr key={user.id}>\n <Td>\n <UserIdentity user={user} />\n </Td>\n <Td>\n <UserContact user={user} />\n </Td>\n <Td>\n {user.lastSignInAt\n ? new Date(user.lastSignInAt).toLocaleDateString()\n : 'Never'}\n </Td>\n <Td>\n <UserRemoveButton\n roleId={roleId}\n userId={user.id}\n onRemove={onRemove}\n />\n </Td>\n </Tr>\n ))}\n </Tbody>\n </DisplayTable>\n );\n}\n\nfunction RoleUsersCards({\n roleId,\n users,\n onRemove,\n}: {\n roleId: string;\n users: User[];\n onRemove: (roleId: string, userId: string) => void;\n}) {\n return (\n <div className=\"grid grid-cols-1 gap-4 md:grid-cols-2 xl:grid-cols-3\">\n {users.map((user) => (\n <div\n key={user.id}\n className=\"rounded-xl border border-border/60 bg-card p-4 shadow-sm\"\n >\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"space-y-3\">\n <div className=\"flex items-center gap-3\">\n <Avatar className=\"h-10 w-10\">\n <AvatarImage src={user.image ?? undefined} />\n <AvatarFallback>{initials(user)}</AvatarFallback>\n </Avatar>\n <div>\n <p className=\"font-semibold\">{user.fullName}</p>\n </div>\n </div>\n <div className=\"space-y-1 text-sm text-muted-foreground\">\n <p>{user.email ?? user.phone ?? 'No contact info'}</p>\n <p>\n Last sign in{' '}\n {user.lastSignInAt\n ? new Date(user.lastSignInAt).toLocaleDateString()\n : 'never'}\n </p>\n </div>\n </div>\n <UserRemoveButton\n roleId={roleId}\n userId={user.id}\n onRemove={onRemove}\n />\n </div>\n </div>\n ))}\n </div>\n );\n}\n\nexport function RoleUsersPage({ roleId }: RoleUsersPageProps) {\n return (\n <IAMGuard>\n <RoleUsersPageContent roleId={roleId} />\n </IAMGuard>\n );\n}\n\nfunction RoleUsersPageContent({ roleId }: RoleUsersPageProps) {\n const qc = useQueryClient();\n const { queryConfig, params, setParams } = useEntityParams({\n searchKey: 'search',\n defaultSort: 'fullName',\n defaultOrder: 'asc',\n });\n const usersQuery = useMemo(\n () =>\n ({\n params: {\n path: { id: roleId },\n query: queryConfig.params.query,\n },\n }) as {\n params: {\n path: { id: string };\n query: NonNullable<\n paths['/roles/{id}/users']['get']['parameters']['query']\n >;\n };\n },\n [queryConfig, roleId],\n );\n\n const { data, isPending, isFetching } = authApi$.useQuery(\n 'get',\n '/roles/{id}/users',\n usersQuery,\n { enabled: !!roleId },\n );\n const assignUsers = authApi$.useMutation('post', '/roles/{id}/users', {\n onSuccess: (result: { created?: number } | undefined) => {\n qc.invalidateQueries({ queryKey: ['get', '/roles'] });\n qc.invalidateQueries({ queryKey: ['get', '/roles/{id}'] });\n qc.invalidateQueries({ queryKey: ['get', '/roles/{id}/users'] });\n toast.success(\n result?.created ? `${result.created} user(s) added` : 'No changes',\n );\n },\n onError: () => {\n toast.error('Failed to assign users');\n },\n });\n const revokeUser = authApi$.useMutation(\n 'delete',\n '/roles/{id}/users/{userId}',\n {\n onSuccess: () => {\n qc.invalidateQueries({ queryKey: ['get', '/roles'] });\n qc.invalidateQueries({ queryKey: ['get', '/roles/{id}'] });\n qc.invalidateQueries({ queryKey: ['get', '/roles/{id}/users'] });\n toast.success('User removed');\n },\n onError: () => {\n toast.error('Failed to remove user');\n },\n },\n );\n\n const users = (data?.users ?? []) as User[];\n const { total, pageCount } = useEntityPagination({\n items: users,\n total: data?.total,\n pageSize: params.pageSize,\n });\n const isLoading = isPending || isFetching;\n const currentView = (params.view || 'table') as 'table' | 'card';\n const handleRemoveUser = (targetRoleId: string, userId: string) => {\n revokeUser.mutate({\n params: {\n path: { id: targetRoleId, userId },\n },\n });\n };\n\n if (!roleId) {\n return null;\n }\n\n let content: ReactNode;\n if (isLoading) {\n content = (\n <EntityLoadingState\n view={currentView}\n rowCount={params.pageSize}\n columnCount={TABLE_COLUMN_COUNT}\n cardCount={params.pageSize}\n />\n );\n } else if (total === 0) {\n content = (\n <EntityEmptyState\n icon={IconUsers}\n entityName=\"user\"\n title=\"No users assigned\"\n description=\"Assign users from the selector to add them to this role.\"\n />\n );\n } else if (currentView === 'table') {\n content = (\n <div className=\"space-y-4\">\n <RoleUsersTable\n roleId={roleId}\n users={users}\n onRemove={handleRemoveUser}\n />\n <DataTablePagination\n pageIndex={params.page - 1}\n pageSize={params.pageSize}\n pageCount={pageCount}\n totalRows={total}\n onPageChange={(page) => setParams({ page: page + 1 })}\n onPageSizeChange={(pageSize) => setParams({ pageSize, page: 1 })}\n />\n </div>\n );\n } else {\n content = (\n <div className=\"space-y-4\">\n <RoleUsersCards\n roleId={roleId}\n users={users}\n onRemove={handleRemoveUser}\n />\n <DataTablePagination\n pageIndex={params.page - 1}\n pageSize={params.pageSize}\n pageCount={pageCount}\n totalRows={total}\n onPageChange={(page) => setParams({ page: page + 1 })}\n onPageSizeChange={(pageSize) => setParams({ pageSize, page: 1 })}\n />\n </div>\n );\n }\n\n return (\n <PageBody className=\"px-0 pb-6\">\n <EntityHeader\n icon={<IconUser className=\"h-5 w-5\" />}\n title=\"Role users\"\n actions={\n <UserSelector\n trigger={\n <Button size=\"sm\" loading={assignUsers.isPending}>\n <IconPlus className=\"h-4 w-4\" />\n Add users\n </Button>\n }\n multiple\n excludeIds={users.map((user) => user.id)}\n onSelect={(selectedUsers: User[]) => {\n if (!selectedUsers.length) {\n return;\n }\n\n assignUsers.mutate({\n params: { path: { id: roleId } },\n body: {\n userIds: selectedUsers.map((user: User) => user.id),\n },\n });\n }}\n />\n }\n search={\n <EntitySearch\n paramKey=\"search\"\n placeholder=\"Search assigned users...\"\n />\n }\n filter={\n <EntityFilter\n options={[\n { label: 'All', value: '' },\n { label: 'Name', value: 'fullName' },\n { label: 'Email', value: 'email' },\n { label: 'Phone', value: 'phone' },\n ]}\n placeholder=\"Search field\"\n />\n }\n sort={\n <EntitySort\n defaultSort=\"fullName\"\n defaultOrder=\"asc\"\n options={[\n { label: 'Created', value: 'createdAt' },\n { label: 'Updated', value: 'updatedAt' },\n { label: 'Name', value: 'fullName' },\n { label: 'Last Sign In', value: 'lastSignInAt' },\n ]}\n />\n }\n view={<EntityViewToggle views={['table', 'card']} />}\n />\n {content}\n </PageBody>\n );\n}\n","'use client';\n\nimport { IAMGuard } from '@mesob/auth-react/components/iam/iam-guard';\nimport {\n Button,\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n EntityDetailHeader,\n PageContainer,\n type TabItem,\n useBreadcrumbs,\n} from '@mesob/ui/components';\nimport { IconBuilding } from '@tabler/icons-react';\nimport { useQueryClient } from '@tanstack/react-query';\nimport { useMemo } from 'react';\nimport { useApi, useConfig } from '../../../provider';\nimport { str } from './_components/tenants-data';\n\ntype TenantDetailPageContentProps = {\n tenantId: string;\n};\n\nexport function TenantDetailPageContent({\n tenantId,\n}: TenantDetailPageContentProps) {\n return (\n <IAMGuard>\n <TenantDetailPageContentInner tenantId={tenantId} />\n </IAMGuard>\n );\n}\n\nfunction TenantDetailPageContentInner({\n tenantId,\n}: TenantDetailPageContentProps) {\n const { hooks } = useApi();\n const { config } = useConfig();\n const homeHref = config.navigation?.defaultRedirectUrl || '/';\n const qc = useQueryClient();\n\n const { data, isLoading } = hooks.useQuery(\n 'get',\n '/tenants/{id}',\n { params: { path: { id: tenantId } } },\n { enabled: !!tenantId },\n );\n const tenant = data?.tenant;\n\n const toggleActive = hooks.useMutation('put', '/tenants/{id}', {\n onSuccess: () => {\n qc.invalidateQueries({ queryKey: ['get', '/tenants/{id}'] });\n qc.invalidateQueries({ queryKey: ['get', '/tenants'] });\n },\n });\n\n const title = tenant ? str(tenant.name) || tenant.id : (tenantId ?? 'Tenant');\n useBreadcrumbs({\n items: [\n { label: 'Home', href: homeHref },\n { label: 'IAM', href: '/iam' },\n { label: 'Tenants', href: '/iam/tenants' },\n { label: title },\n ],\n });\n\n const tabs: TabItem[] = useMemo(\n () => [\n {\n value: 'detail',\n name: 'Detail',\n content: (\n <Card className=\"mt-4\">\n <CardHeader>\n <CardTitle>Tenant details</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-2 text-sm\">\n {tenant && (\n <>\n <p>\n <span className=\"text-muted-foreground\">Name:</span>{' '}\n {str(tenant.name) || '—'}\n </p>\n <p>\n <span className=\"text-muted-foreground\">Description:</span>{' '}\n {str(tenant.description) || '—'}\n </p>\n <p>\n <span className=\"text-muted-foreground\">Language:</span>{' '}\n {tenant.defaultLanguage ?? '—'}\n </p>\n <p>\n <span className=\"text-muted-foreground\">Currency:</span>{' '}\n {tenant.defaultCurrency ?? '—'}\n </p>\n <p>\n <span className=\"text-muted-foreground\">Timezone:</span>{' '}\n {tenant.timezone ?? '—'}\n </p>\n </>\n )}\n </CardContent>\n </Card>\n ),\n },\n {\n value: 'theme',\n name: 'Theme',\n content: (\n <Card className=\"mt-4\">\n <CardHeader>\n <CardTitle>Theme</CardTitle>\n </CardHeader>\n <CardContent className=\"text-muted-foreground text-sm\">\n Theme settings (placeholder)\n </CardContent>\n </Card>\n ),\n },\n {\n value: 'settings',\n name: 'Settings',\n content: (\n <Card className=\"mt-4\">\n <CardHeader>\n <CardTitle>Settings</CardTitle>\n </CardHeader>\n <CardContent className=\"text-muted-foreground text-sm\">\n Tenant settings (placeholder)\n </CardContent>\n </Card>\n ),\n },\n ],\n [tenant],\n );\n\n const actions = tenant && (\n <Button\n variant={tenant.isActive ? 'secondary' : 'default'}\n size=\"sm\"\n onClick={() =>\n toggleActive.mutate({\n params: { path: { id: tenantId } },\n body: { isActive: !tenant.isActive },\n })\n }\n disabled={toggleActive.isPending}\n >\n {tenant.isActive ? 'Deactivate' : 'Activate'}\n </Button>\n );\n\n if (!tenantId) {\n return null;\n }\n if (isLoading || !tenant) {\n return (\n <div className=\"flex flex-1 flex-col gap-4 p-4 pt-0\">\n <div className=\"h-24 animate-pulse rounded-xl bg-muted\" />\n </div>\n );\n }\n\n return (\n <PageContainer className=\"flex flex-1 flex-col gap-4 p-4 pt-0\">\n <EntityDetailHeader\n title={title}\n icon={<IconBuilding className=\"h-5 w-5 text-muted-foreground\" />}\n actions={actions}\n tabs={tabs}\n />\n </PageContainer>\n );\n}\n","'use client';\n\nimport { IAMGuard } from '@mesob/auth-react/components/iam/iam-guard';\nimport { toTitleCase } from '@mesob/common';\nimport {\n Button,\n EntityDetailHeader,\n PageContainer,\n type TabItem,\n useBreadcrumbs,\n} from '@mesob/ui/components';\nimport { IconUser } from '@tabler/icons-react';\nimport { useMemo } from 'react';\nimport { useApi, useConfig } from '../../../../provider';\n\ntype UserDetailLayoutContentProps = {\n userId: string;\n children: React.ReactNode;\n};\n\nexport function UserDetailLayoutContent({\n userId,\n children,\n}: UserDetailLayoutContentProps) {\n return (\n <IAMGuard>\n <UserDetailLayoutContentInner userId={userId}>\n {children}\n </UserDetailLayoutContentInner>\n </IAMGuard>\n );\n}\n\nfunction UserDetailLayoutContentInner({\n userId,\n children,\n}: UserDetailLayoutContentProps) {\n const { hooks } = useApi();\n const { config } = useConfig();\n const homeHref = config.navigation?.defaultRedirectUrl || '/';\n const { data, isLoading } = hooks.useQuery(\n 'get',\n '/users/{id}',\n { params: { path: { id: userId } } },\n { enabled: !!userId },\n );\n const user = data?.user;\n\n const title = toTitleCase(user?.fullName || userId || 'User');\n\n useBreadcrumbs({\n items: [\n { label: 'Home', href: homeHref },\n { label: 'IAM', href: '/iam' },\n { label: 'Users', href: '/iam/users' },\n { label: title },\n ],\n });\n\n const tabs: TabItem[] = useMemo(\n () => [\n { value: 'detail', name: 'Detail', href: `/iam/users/${userId}` },\n {\n value: 'activity',\n name: 'Activity',\n href: `/iam/users/${userId}/activity`,\n },\n ],\n [userId],\n );\n\n if (!userId) {\n return null;\n }\n\n return (\n <PageContainer>\n <EntityDetailHeader\n title={title}\n icon={<IconUser />}\n tabs={tabs}\n loading={isLoading}\n actions={<Button>Test Button</Button>}\n />\n {children}\n </PageContainer>\n );\n}\n","'use client';\n\nimport { IAMGuard } from '@mesob/auth-react/components/iam/iam-guard';\nimport {\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from '@mesob/ui/components';\nimport { IconCircleCheck } from '@tabler/icons-react';\nimport { useApi } from '../../../../provider';\n\ntype UserDetailPageContentProps = {\n userId: string;\n};\n\nexport function UserDetailPageContent({ userId }: UserDetailPageContentProps) {\n return (\n <IAMGuard>\n <UserDetailPageContentInner userId={userId} />\n </IAMGuard>\n );\n}\n\nfunction UserDetailPageContentInner({ userId }: UserDetailPageContentProps) {\n const { hooks } = useApi();\n const { data, isLoading } = hooks.useQuery(\n 'get',\n '/users/{id}',\n { params: { path: { id: userId } } },\n { enabled: !!userId },\n );\n const user = data?.user;\n\n if (!userId) {\n return null;\n }\n if (isLoading || !user) {\n return <div className=\"h-32 animate-pulse rounded-xl bg-muted mt-4\" />;\n }\n\n return (\n <Card>\n <CardHeader>\n <CardTitle>User details</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-2 text-sm\">\n <p>\n <span className=\"text-muted-foreground\">Name:</span>{' '}\n {user.fullName || '—'}\n </p>\n <p>\n <span className=\"text-muted-foreground\">Email:</span>{' '}\n {user.email ?? '—'}{' '}\n {user.emailVerified && (\n <Tooltip>\n <TooltipTrigger>\n <IconCircleCheck className=\"inline size-4 text-muted-foreground\" />\n </TooltipTrigger>\n <TooltipContent>Email verified</TooltipContent>\n </Tooltip>\n )}\n </p>\n <p>\n <span className=\"text-muted-foreground\">Phone:</span>{' '}\n {user.phone ?? '—'}{' '}\n {user.phoneVerified && (\n <Tooltip>\n <TooltipTrigger>\n <IconCircleCheck className=\"inline size-4 text-muted-foreground\" />\n </TooltipTrigger>\n <TooltipContent>Phone verified</TooltipContent>\n </Tooltip>\n )}\n </p>\n <p>\n <span className=\"text-muted-foreground\">Last sign in:</span>{' '}\n {user.lastSignInAt\n ? new Date(user.lastSignInAt).toLocaleString()\n : 'Never'}\n </p>\n {user.roleCodes?.length ? (\n <p>\n <span className=\"text-muted-foreground\">Roles:</span>{' '}\n {user.roleCodes.join(', ')}\n </p>\n ) : null}\n </CardContent>\n </Card>\n );\n}\n","'use client';\n\nimport { IAMGuard } from '@mesob/auth-react/components/iam/iam-guard';\nimport {\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n Section,\n} from '@mesob/ui/components';\nimport { IconCalendar } from '@tabler/icons-react';\nimport { RoleSection } from './_components/role-section';\n\ntype UserActivityPageContentProps = {\n userId: string;\n};\n\nexport function UserActivityPageContent({\n userId,\n}: UserActivityPageContentProps) {\n return (\n <IAMGuard>\n <UserActivityPageContentInner userId={userId} />\n </IAMGuard>\n );\n}\n\nfunction UserActivityPageContentInner({\n userId,\n}: UserActivityPageContentProps) {\n if (!userId) {\n return null;\n }\n\n return (\n <div className=\"space-y-4\">\n <Card>\n <CardHeader>\n <CardTitle>Activity</CardTitle>\n </CardHeader>\n <CardContent className=\"flex items-center gap-2 text-muted-foreground text-sm\">\n <IconCalendar className=\"h-4 w-4\" />\n Activity (placeholder)\n </CardContent>\n </Card>\n <RoleSection userId={userId} />\n <Section title=\"Permissions\">test</Section>\n <Section title=\"Groups\">test</Section>\n </div>\n );\n}\n","'use client';\n\nimport {\n Button,\n EntityEmptyState,\n EntityLoadingState,\n EntitySection,\n useEntitySectionState,\n} from '@mesob/ui/components';\nimport { IconPlus, IconShield } from '@tabler/icons-react';\nimport { useMemo, useState } from 'react';\nimport { RoleSelector } from '../../../roles/_components/role-selector';\nimport type { Role } from '../../../roles/_components/roles-data';\nimport { str } from '../../../roles/_components/roles-data';\nimport { RolesList } from '../../../roles/_components/roles-list';\nimport {\n authApi$,\n defaultEntityQueryOptions,\n} from '../../../shared/page-helpers';\n\nconst LIMIT = 100;\nconst TABLE_COLUMN_COUNT = 4;\n\nfunction filterAndSort(\n roles: Role[],\n search: string,\n sort: string,\n order: 'asc' | 'desc',\n) {\n let out = roles;\n if (search.trim()) {\n const q = search.trim().toLowerCase();\n out = out.filter(\n (r) =>\n str(r.name).toLowerCase().includes(q) ||\n r.code.toLowerCase().includes(q),\n );\n }\n const mult = order === 'asc' ? 1 : -1;\n const by = sort === 'code' ? 'code' : 'createdAt';\n out = [...out].sort((a, b) =>\n by === 'code'\n ? mult * a.code.localeCompare(b.code)\n : mult *\n (new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime()),\n );\n return out;\n}\n\nexport function RoleSection({ userId }: { userId: string }) {\n const [open, setOpen] = useState(false);\n const sectionState = useEntitySectionState({\n defaultSort: 'createdAt',\n defaultOrder: 'desc',\n defaultPageSize: 10,\n filterOptions: [\n { label: 'All', value: '' },\n { label: 'By Code', value: 'code' },\n ],\n sortOptions: [\n { label: 'Created', value: 'createdAt' },\n { label: 'Updated', value: 'updatedAt' },\n { label: 'Code', value: 'code' },\n ],\n views: ['table', 'card'],\n });\n\n const { data, isPending, isFetching } = authApi$.useQuery(\n 'get',\n '/roles',\n { params: { query: { limit: LIMIT } } },\n { ...defaultEntityQueryOptions, enabled: open },\n );\n const isLoading = isPending || isFetching;\n const roles = data?.roles ?? [];\n\n const filtered = useMemo(\n () =>\n filterAndSort(\n roles,\n sectionState.search,\n sectionState.sort,\n sectionState.order,\n ),\n [roles, sectionState.search, sectionState.sort, sectionState.order],\n );\n const pageCount = Math.ceil(filtered.length / sectionState.pageSize) || 1;\n const pageIndex = Math.min(sectionState.page - 1, Math.max(0, pageCount - 1));\n const paginated = useMemo(\n () =>\n filtered.slice(\n pageIndex * sectionState.pageSize,\n pageIndex * sectionState.pageSize + sectionState.pageSize,\n ),\n [filtered, pageIndex, sectionState.pageSize],\n );\n\n return (\n <EntitySection\n title=\"Role\"\n state={sectionState}\n onOpenChange={setOpen}\n actions={\n <RoleSelector\n trigger={\n <Button variant=\"outline\" size=\"sm\">\n <IconPlus className=\"h-4 w-4\" />\n Add role\n </Button>\n }\n multiple\n onSelect={(roles) => {\n // TODO: assign roles to user; logging for now\n // biome-ignore lint/suspicious/noConsole: intentional for now\n console.log('Selected roles:', userId, roles);\n }}\n />\n }\n config={{\n searchPlaceholder: 'Search roles...',\n filterOptions: sectionState.filterOptions,\n sortOptions: sectionState.sortOptions,\n views: sectionState.views,\n }}\n >\n {(state) => (\n <>\n {isLoading && (\n <EntityLoadingState\n view={state.view as 'table' | 'card'}\n rowCount={state.pageSize}\n columnCount={TABLE_COLUMN_COUNT}\n cardCount={state.pageSize}\n />\n )}\n {!isLoading && filtered.length === 0 && (\n <EntityEmptyState\n icon={IconShield}\n entityName=\"role\"\n title=\"No roles\"\n description={\n roles.length === 0 ? 'No roles in tenant.' : 'No matches.'\n }\n />\n )}\n {!isLoading && filtered.length > 0 && (\n <RolesList\n data={paginated}\n view={state.view as 'table' | 'card'}\n pageIndex={pageIndex}\n pageSize={state.pageSize}\n pageCount={pageCount}\n totalRows={filtered.length}\n onPageChange={(p) => state.setPage(p + 1)}\n onPageSizeChange={(size) => {\n state.setPageSize(size);\n state.setPage(1);\n }}\n />\n )}\n </>\n )}\n </EntitySection>\n );\n}\n","'use client';\n\nimport {\n EntitySelector,\n type EntitySelectorColumn,\n type EntitySelectorConfig,\n useEntitySectionState,\n} from '@mesob/ui/components';\nimport { cn } from '@mesob/ui/lib/utils';\nimport { IconCalendar, IconShield } from '@tabler/icons-react';\nimport type { ReactNode } from 'react';\nimport type { paths } from '../../../../data/openapi';\nimport { authApi$, defaultEntityQueryOptions } from '../../shared/page-helpers';\nimport { RoleCard } from './role-card';\nimport type { Role } from './roles-data';\nimport { str } from './roles-data';\n\nfunction SelectableRoleCard({\n role,\n selected,\n onToggle,\n}: {\n role: Role;\n selected: boolean;\n onToggle: () => void;\n}) {\n return (\n // biome-ignore lint/a11y/useSemanticElements: div to avoid nested buttons from RoleCard\n <div\n role=\"button\"\n tabIndex={0}\n onClick={onToggle}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n onToggle();\n }\n }}\n className={cn(\n 'cursor-pointer rounded-lg transition-shadow focus:outline-none focus-visible:ring-2 focus-visible:ring-ring',\n selected && 'ring-primary ring-2',\n )}\n >\n <RoleCard role={role} mode=\"static\" />\n </div>\n );\n}\n\nconst roleColumns: EntitySelectorColumn<Role>[] = [\n {\n key: 'role',\n header: 'Role',\n cell: (role) => (\n <>\n <p className=\"font-medium\">{str(role.name) || role.code}</p>\n <p className=\"text-sm text-muted-foreground\">{role.code}</p>\n </>\n ),\n },\n {\n key: 'description',\n header: 'Description',\n cell: (role) => (\n <span className=\"text-muted-foreground line-clamp-1 max-w-[200px]\">\n {str(role.description) || '—'}\n </span>\n ),\n },\n {\n key: 'created',\n header: 'Created',\n cell: (role) => (\n <div className=\"flex items-center gap-1 text-muted-foreground\">\n <IconCalendar className=\"h-4 w-4\" />\n {new Date(role.createdAt).toLocaleDateString()}\n </div>\n ),\n },\n];\n\ntype RoleSelectorProps = {\n trigger: ReactNode;\n multiple?: boolean;\n onSelect: (roles: Role[]) => void;\n modalSize?: 'sm' | 'md' | 'lg' | 'xl' | 'full';\n contentClassName?: string;\n};\n\nexport function RoleSelector({\n trigger,\n multiple = true,\n onSelect,\n modalSize = 'xl',\n contentClassName,\n}: RoleSelectorProps) {\n const state = useEntitySectionState({\n defaultSort: 'createdAt',\n defaultOrder: 'desc',\n defaultPageSize: 10,\n searchParamName: 'search',\n });\n const rolesQuery = state.queryConfig as {\n params: {\n query: NonNullable<paths['/roles']['get']['parameters']['query']>;\n };\n };\n\n const { data, isPending, isFetching } = authApi$.useQuery(\n 'get',\n '/roles',\n rolesQuery,\n defaultEntityQueryOptions,\n );\n\n const roles = data?.roles ?? [];\n\n const config: EntitySelectorConfig<Role> = {\n title: 'Select role(s)',\n modalSize,\n contentClassName,\n multiple,\n entityName: 'role',\n entityIcon: IconShield,\n columns: roleColumns,\n columnCount: 3,\n getItemLabel: (role) => str(role.name) || role.code,\n searchPlaceholder: 'Search roles...',\n wrapHeaderInCard: false,\n filterOptions: [\n { label: 'All', value: '' },\n { label: 'By Code', value: 'code' },\n ],\n sortOptions: [\n { label: 'Created', value: 'createdAt' },\n { label: 'Updated', value: 'updatedAt' },\n { label: 'Code', value: 'code' },\n ],\n showViewToggle: false,\n renderCard: (role, selected, onToggle) => (\n <SelectableRoleCard role={role} selected={selected} onToggle={onToggle} />\n ),\n };\n\n return (\n <EntitySelector<Role>\n trigger={trigger}\n config={config}\n onSelect={onSelect}\n items={roles}\n total={data?.total}\n isLoading={isPending || isFetching}\n state={state}\n />\n );\n}\n","'use client';\n\nimport { NuqsAdapter } from 'nuqs/adapters/next/app';\nimport type { ReactNode } from 'react';\n\ntype NuqsAdapterWrapperProps = {\n children: ReactNode;\n};\n\nexport function NuqsAdapterWrapper({ children }: NuqsAdapterWrapperProps) {\n return <NuqsAdapter>{children}</NuqsAdapter>;\n}\n"],"mappings":"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","names":["IAMGuard","IAMGuard","IAMGuard","Button","useQueryClient","useMemo","jsx","jsxs","IAMGuard","useQueryClient","str","useMemo","Button","IAMGuard","Button","EntityDetailHeader","PageContainer","useBreadcrumbs","IconUser","useMemo","jsx","jsxs","IAMGuard","useBreadcrumbs","useMemo","PageContainer","EntityDetailHeader","IconUser","Button","IAMGuard","Card","CardContent","CardHeader","CardTitle","jsx","jsxs","IAMGuard","Card","CardHeader","CardTitle","CardContent","IAMGuard","Card","CardContent","CardHeader","CardTitle","IconCalendar","Button","EntityEmptyState","EntityLoadingState","useEntitySectionState","IconPlus","IconShield","useMemo","Fragment","jsx","jsxs","Fragment","jsx","jsxs","TABLE_COLUMN_COUNT","useEntitySectionState","useMemo","Button","IconPlus","roles","EntityLoadingState","EntityEmptyState","IconShield","jsx","jsxs","IAMGuard","Card","CardHeader","CardTitle","CardContent","IconCalendar","jsx"]}
@@ -5,7 +5,7 @@ import {
5
5
  import {
6
6
  useConfig,
7
7
  useSession
8
- } from "../../chunk-A5ON3RKH.js";
8
+ } from "../../chunk-M2K6O5CN.js";
9
9
 
10
10
  // src/pages/auth/layout.tsx
11
11
  import { AuthCard } from "@mesob/auth-react/components/auth/auth-card";
@@ -4,12 +4,12 @@ import {
4
4
  } from "../../../chunk-EWXK56WQ.js";
5
5
  import {
6
6
  authApi$
7
- } from "../../../chunk-NTDVUVZO.js";
8
- import "../../../chunk-3GFTD46V.js";
7
+ } from "../../../chunk-QNPK2H5A.js";
8
+ import "../../../chunk-SLIIENXJ.js";
9
9
  import {
10
10
  defaultEntityQueryOptions
11
11
  } from "../../../chunk-NPW7D2HZ.js";
12
- import "../../../chunk-A5ON3RKH.js";
12
+ import "../../../chunk-M2K6O5CN.js";
13
13
 
14
14
  // src/pages/iam/tenants/_components/tenant-selector.tsx
15
15
  import {
@@ -1,16 +1,16 @@
1
1
  "use client";
2
2
  import {
3
3
  UserCard
4
- } from "../../../chunk-OMTV6IOB.js";
4
+ } from "../../../chunk-XTLFZ77E.js";
5
5
  import "../../../chunk-OW75JENQ.js";
6
6
  import {
7
7
  authApi$
8
- } from "../../../chunk-NTDVUVZO.js";
9
- import "../../../chunk-3GFTD46V.js";
8
+ } from "../../../chunk-QNPK2H5A.js";
9
+ import "../../../chunk-SLIIENXJ.js";
10
10
  import {
11
11
  defaultEntityQueryOptions
12
12
  } from "../../../chunk-NPW7D2HZ.js";
13
- import "../../../chunk-A5ON3RKH.js";
13
+ import "../../../chunk-M2K6O5CN.js";
14
14
 
15
15
  // src/pages/iam/users/_components/user-selector.tsx
16
16
  import {
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import {
3
3
  useConfig
4
- } from "../../chunk-A5ON3RKH.js";
4
+ } from "../../chunk-M2K6O5CN.js";
5
5
 
6
6
  // src/pages/profile/account.tsx
7
7
  import { Account } from "@mesob/auth-react/components/profile/account";
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import {
3
3
  useConfig
4
- } from "../../chunk-A5ON3RKH.js";
4
+ } from "../../chunk-M2K6O5CN.js";
5
5
 
6
6
  // src/pages/profile/security.tsx
7
7
  import { Security } from "@mesob/auth-react/components/profile/security";
@@ -0,0 +1,2 @@
1
+ /** Matches @mesob/auth-hono `normalizeEmail`. */
2
+ export declare function normalizeEmail(input: string): string;
@@ -1 +1,2 @@
1
+ /** Last 9 digits → `+251…` (matches @mesob/auth-hono `normalizeEthiopiaPhone`). */
1
2
  export declare function normalizePhone(phone: string): string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mesob/auth-react",
3
- "version": "0.5.8",
3
+ "version": "0.5.10",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",
@@ -132,8 +132,8 @@
132
132
  ],
133
133
  "dependencies": {
134
134
  "@hookform/resolvers": "^5.2.2",
135
- "@mesob/common": "^0.5.8",
136
- "@mesob/ui": "^0.5.8",
135
+ "@mesob/common": "^0.5.10",
136
+ "@mesob/ui": "^0.5.10",
137
137
  "@tabler/icons-react": "^3.35.0",
138
138
  "deepmerge-ts": "^7.1.5",
139
139
  "nuqs": "^2.8.1",
@@ -162,7 +162,7 @@
162
162
  "access": "public"
163
163
  },
164
164
  "scripts": {
165
- "build": "tsup && pnpm exec tsc --noEmit false --emitDeclarationOnly --declaration --declarationMap false --outDir dist-types && cp -R dist-types/auth-react/src/. dist/ && rm -rf dist-types",
165
+ "build": "tsup && pnpm exec tsc --noEmit false --emitDeclarationOnly --declaration --declarationMap false --outDir dist-types && node scripts/merge-dist-types.mjs",
166
166
  "dev": "tsup --watch",
167
167
  "generate:client": "node scripts/generate-client.mjs",
168
168
  "lint": "biome check --write .",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/profile/request-change-phone-form.tsx"],"sourcesContent":["'use client';\n\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport { Button, Input, Label, Spinner } from '@mesob/ui/components';\nimport { IconEye, IconEyeOff } from '@tabler/icons-react';\nimport { useEffect, useState } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { toast } from 'sonner';\nimport { z } from 'zod';\nimport { useApi, useConfig, useSession } from '../../provider';\nimport { normalizePhone } from '../../utils/normalize-phone';\n\nconst phonePasswordSchema = (phoneRegex: RegExp) =>\n z.object({\n phone: z\n .string()\n .trim()\n .min(1, { message: 'Phone number is required' })\n .refine(\n (val) => {\n const isPhone = phoneRegex.test(val);\n return isPhone;\n },\n {\n message: 'Invalid phone number',\n },\n ),\n password: z\n .string()\n .min(8, 'Password must be at least 8 characters')\n .max(128, 'Password too long'),\n });\n\ntype PhonePasswordFormData = z.infer<ReturnType<typeof phonePasswordSchema>>;\n\ntype AuthErrorLike = {\n code?: string;\n message?: string;\n name?: string;\n};\n\nfunction isAuthError(error: unknown): error is AuthErrorLike {\n return (\n typeof error === 'object' &&\n error !== null &&\n ('code' in error || 'message' in error || 'name' in error)\n );\n}\n\nfunction getErrorCode(error: AuthErrorLike): string | undefined {\n if (error.code) {\n return error.code;\n }\n if (error.message) {\n const upperMessage = error.message.toUpperCase().trim();\n const validCodes = [\n 'USER_NOT_FOUND',\n 'USER_EXISTS',\n 'INVALID_PASSWORD',\n 'VERIFICATION_EXPIRED',\n 'VERIFICATION_MISMATCH',\n 'VERIFICATION_NOT_FOUND',\n 'TOO_MANY_ATTEMPTS',\n 'UNAUTHORIZED',\n ];\n if (validCodes.includes(upperMessage)) {\n return upperMessage;\n }\n }\n return undefined;\n}\n\nfunction getErrorMessage(error: unknown): string {\n if (isAuthError(error)) {\n const errorCode = getErrorCode(error);\n switch (errorCode) {\n case 'USER_EXISTS':\n return 'This phone number is already taken. Please use a different number.';\n case 'VERIFICATION_EXPIRED':\n return 'Verification code has expired. Please request a new one.';\n case 'VERIFICATION_MISMATCH':\n return 'Invalid verification code. Please try again.';\n case 'VERIFICATION_NOT_FOUND':\n return 'Verification not found. Please request a new code.';\n default:\n return error.message || 'An error occurred. Please try again.';\n }\n }\n if (error instanceof Error) {\n return error.message;\n }\n return 'An error occurred. Please try again.';\n}\n\ninterface RequestChangePhoneFormProps {\n onSuccess: (verificationId: string, phone: string) => void;\n onCancel: () => void;\n buttonText: string;\n}\n\nexport function RequestChangePhoneForm({\n onSuccess,\n onCancel,\n buttonText,\n}: RequestChangePhoneFormProps) {\n const { user } = useSession();\n const { hooks } = useApi();\n const { config } = useConfig();\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [isChecking, setIsChecking] = useState(true);\n const [showPassword, setShowPassword] = useState(false);\n\n const phoneRegex =\n typeof config.phoneRegex === 'string'\n ? new RegExp(config.phoneRegex)\n : config.phoneRegex || /^(\\+2519|\\+2517|2519|2517|09|07)\\d{8}$/;\n\n const getPendingAccountChangeQuery = hooks.useQuery(\n 'get',\n '/account-change/pending',\n {},\n { enabled: false },\n );\n const verifyPasswordMutation = hooks.useMutation('post', '/password/verify');\n const checkUserMutation = hooks.useMutation('post', '/check-account');\n const requestPhoneOtpMutation = hooks.useMutation(\n 'post',\n '/phone/verification/request',\n );\n\n const phonePasswordForm = useForm<PhonePasswordFormData>({\n resolver: zodResolver(phonePasswordSchema(phoneRegex)),\n defaultValues: {\n phone: '',\n password: '',\n },\n });\n\n const {\n register,\n handleSubmit,\n getValues,\n setValue,\n formState: { errors },\n } = phonePasswordForm;\n\n useEffect(() => {\n let active = true;\n const run = async () => {\n try {\n const data = await getPendingAccountChangeQuery.refetch();\n if (!active) {\n return;\n }\n const accountChange = data.data?.accountChange;\n const verificationId = data.data?.verificationId;\n if (accountChange?.changeType !== 'phone') {\n setIsChecking(false);\n return;\n }\n if (!accountChange.newPhone) {\n setIsChecking(false);\n return;\n }\n if (getValues('phone')) {\n setIsChecking(false);\n return;\n }\n setValue('phone', accountChange.newPhone, { shouldValidate: true });\n\n if (verificationId) {\n toast.message('Resuming verification…');\n onSuccess(verificationId, accountChange.newPhone);\n return;\n }\n\n setIsChecking(false);\n } catch {\n setIsChecking(false);\n }\n };\n run().catch(() => undefined);\n return () => {\n active = false;\n };\n }, [getPendingAccountChangeQuery.refetch, getValues, onSuccess, setValue]);\n\n const onPhonePasswordSubmit = async (data: PhonePasswordFormData) => {\n if (!user) {\n toast.error('User not found');\n return;\n }\n\n try {\n setIsSubmitting(true);\n\n const normalizedPhone = normalizePhone(data.phone);\n\n // Verify password first\n await verifyPasswordMutation.mutateAsync({\n body: { password: data.password },\n });\n\n // Check if phone exists\n const checkResult = await checkUserMutation.mutateAsync({\n body: { identifier: normalizedPhone },\n });\n if (checkResult.data?.exists) {\n // Check if it belongs to current user\n if (\n user?.phone?.replace(/\\s/g, '') === normalizedPhone.replace(/\\s/g, '')\n ) {\n toast.error('This is already your current phone number.');\n return;\n }\n toast.error(\n 'This phone number is already taken. Please use a different number.',\n );\n return;\n }\n\n // Request OTP\n const verification = await requestPhoneOtpMutation.mutateAsync({\n body: {\n phone: normalizedPhone,\n context: 'change-phone',\n },\n });\n\n toast.success('Verification code sent to your phone');\n onSuccess(verification.data?.verificationId ?? '', normalizedPhone);\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n if (isAuthError(error)) {\n const errorCode = getErrorCode(error);\n if (\n errorCode === 'INVALID_PASSWORD' ||\n errorCode === 'USER_NOT_FOUND'\n ) {\n toast.error('Incorrect password. Please try again.');\n return;\n }\n }\n toast.error(errorMessage);\n } finally {\n setIsSubmitting(false);\n }\n };\n\n const isLoading = isSubmitting || isChecking;\n\n return (\n <form\n onSubmit={handleSubmit(onPhonePasswordSubmit)}\n className=\"p-4 space-y-4 border-t\"\n >\n <div className=\"space-y-4 w-full md:w-1/2\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"phone\">Phone Number</Label>\n <Input\n id=\"phone\"\n type=\"tel\"\n placeholder=\"Enter your new phone number\"\n {...register('phone')}\n disabled={isLoading}\n />\n {errors.phone && (\n <p className=\"text-sm text-destructive\">{errors.phone.message}</p>\n )}\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"password\">Password</Label>\n <div className=\"relative\">\n <Input\n id=\"password\"\n type={showPassword ? 'text' : 'password'}\n autoComplete=\"current-password\"\n placeholder=\"Enter your password\"\n {...register('password')}\n disabled={isLoading}\n />\n <button\n type=\"button\"\n onClick={() => setShowPassword(!showPassword)}\n className=\"absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground\"\n >\n {showPassword ? (\n <IconEyeOff className=\"h-4 w-4\" />\n ) : (\n <IconEye className=\"h-4 w-4\" />\n )}\n </button>\n </div>\n {errors.password && (\n <p className=\"text-sm text-destructive\">\n {errors.password.message}\n </p>\n )}\n </div>\n </div>\n\n <div className=\"flex justify-end gap-2\">\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={onCancel}\n disabled={isLoading}\n >\n Cancel\n </Button>\n <Button type=\"submit\" disabled={isLoading}>\n {isLoading && <Spinner className=\"mr-2 h-4 w-4\" />}\n {isChecking ? 'Checking…' : buttonText}\n </Button>\n </div>\n </form>\n );\n}\n"],"mappings":";;;;;;;;;;AAEA,SAAS,mBAAmB;AAC5B,SAAS,QAAQ,OAAO,OAAO,eAAe;AAC9C,SAAS,SAAS,kBAAkB;AACpC,SAAS,WAAW,gBAAgB;AACpC,SAAS,eAAe;AACxB,SAAS,aAAa;AACtB,SAAS,SAAS;AAyPV,SACE,KADF;AArPR,IAAM,sBAAsB,CAAC,eAC3B,EAAE,OAAO;AAAA,EACP,OAAO,EACJ,OAAO,EACP,KAAK,EACL,IAAI,GAAG,EAAE,SAAS,2BAA2B,CAAC,EAC9C;AAAA,IACC,CAAC,QAAQ;AACP,YAAM,UAAU,WAAW,KAAK,GAAG;AACnC,aAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,SAAS;AAAA,IACX;AAAA,EACF;AAAA,EACF,UAAU,EACP,OAAO,EACP,IAAI,GAAG,wCAAwC,EAC/C,IAAI,KAAK,mBAAmB;AACjC,CAAC;AAUH,SAAS,YAAY,OAAwC;AAC3D,SACE,OAAO,UAAU,YACjB,UAAU,SACT,UAAU,SAAS,aAAa,SAAS,UAAU;AAExD;AAEA,SAAS,aAAa,OAA0C;AAC9D,MAAI,MAAM,MAAM;AACd,WAAO,MAAM;AAAA,EACf;AACA,MAAI,MAAM,SAAS;AACjB,UAAM,eAAe,MAAM,QAAQ,YAAY,EAAE,KAAK;AACtD,UAAM,aAAa;AAAA,MACjB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,QAAI,WAAW,SAAS,YAAY,GAAG;AACrC,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,gBAAgB,OAAwB;AAC/C,MAAI,YAAY,KAAK,GAAG;AACtB,UAAM,YAAY,aAAa,KAAK;AACpC,YAAQ,WAAW;AAAA,MACjB,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AACH,eAAO;AAAA,MACT;AACE,eAAO,MAAM,WAAW;AAAA,IAC5B;AAAA,EACF;AACA,MAAI,iBAAiB,OAAO;AAC1B,WAAO,MAAM;AAAA,EACf;AACA,SAAO;AACT;AAQO,SAAS,uBAAuB;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AACF,GAAgC;AAC9B,QAAM,EAAE,KAAK,IAAI,WAAW;AAC5B,QAAM,EAAE,MAAM,IAAI,OAAO;AACzB,QAAM,EAAE,OAAO,IAAI,UAAU;AAC7B,QAAM,CAAC,cAAc,eAAe,IAAI,SAAS,KAAK;AACtD,QAAM,CAAC,YAAY,aAAa,IAAI,SAAS,IAAI;AACjD,QAAM,CAAC,cAAc,eAAe,IAAI,SAAS,KAAK;AAEtD,QAAM,aACJ,OAAO,OAAO,eAAe,WACzB,IAAI,OAAO,OAAO,UAAU,IAC5B,OAAO,cAAc;AAE3B,QAAM,+BAA+B,MAAM;AAAA,IACzC;AAAA,IACA;AAAA,IACA,CAAC;AAAA,IACD,EAAE,SAAS,MAAM;AAAA,EACnB;AACA,QAAM,yBAAyB,MAAM,YAAY,QAAQ,kBAAkB;AAC3E,QAAM,oBAAoB,MAAM,YAAY,QAAQ,gBAAgB;AACpE,QAAM,0BAA0B,MAAM;AAAA,IACpC;AAAA,IACA;AAAA,EACF;AAEA,QAAM,oBAAoB,QAA+B;AAAA,IACvD,UAAU,YAAY,oBAAoB,UAAU,CAAC;AAAA,IACrD,eAAe;AAAA,MACb,OAAO;AAAA,MACP,UAAU;AAAA,IACZ;AAAA,EACF,CAAC;AAED,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW,EAAE,OAAO;AAAA,EACtB,IAAI;AAEJ,YAAU,MAAM;AACd,QAAI,SAAS;AACb,UAAM,MAAM,YAAY;AACtB,UAAI;AACF,cAAM,OAAO,MAAM,6BAA6B,QAAQ;AACxD,YAAI,CAAC,QAAQ;AACX;AAAA,QACF;AACA,cAAM,gBAAgB,KAAK,MAAM;AACjC,cAAM,iBAAiB,KAAK,MAAM;AAClC,YAAI,eAAe,eAAe,SAAS;AACzC,wBAAc,KAAK;AACnB;AAAA,QACF;AACA,YAAI,CAAC,cAAc,UAAU;AAC3B,wBAAc,KAAK;AACnB;AAAA,QACF;AACA,YAAI,UAAU,OAAO,GAAG;AACtB,wBAAc,KAAK;AACnB;AAAA,QACF;AACA,iBAAS,SAAS,cAAc,UAAU,EAAE,gBAAgB,KAAK,CAAC;AAElE,YAAI,gBAAgB;AAClB,gBAAM,QAAQ,6BAAwB;AACtC,oBAAU,gBAAgB,cAAc,QAAQ;AAChD;AAAA,QACF;AAEA,sBAAc,KAAK;AAAA,MACrB,QAAQ;AACN,sBAAc,KAAK;AAAA,MACrB;AAAA,IACF;AACA,QAAI,EAAE,MAAM,MAAM,MAAS;AAC3B,WAAO,MAAM;AACX,eAAS;AAAA,IACX;AAAA,EACF,GAAG,CAAC,6BAA6B,SAAS,WAAW,WAAW,QAAQ,CAAC;AAEzE,QAAM,wBAAwB,OAAO,SAAgC;AACnE,QAAI,CAAC,MAAM;AACT,YAAM,MAAM,gBAAgB;AAC5B;AAAA,IACF;AAEA,QAAI;AACF,sBAAgB,IAAI;AAEpB,YAAM,kBAAkB,eAAe,KAAK,KAAK;AAGjD,YAAM,uBAAuB,YAAY;AAAA,QACvC,MAAM,EAAE,UAAU,KAAK,SAAS;AAAA,MAClC,CAAC;AAGD,YAAM,cAAc,MAAM,kBAAkB,YAAY;AAAA,QACtD,MAAM,EAAE,YAAY,gBAAgB;AAAA,MACtC,CAAC;AACD,UAAI,YAAY,MAAM,QAAQ;AAE5B,YACE,MAAM,OAAO,QAAQ,OAAO,EAAE,MAAM,gBAAgB,QAAQ,OAAO,EAAE,GACrE;AACA,gBAAM,MAAM,4CAA4C;AACxD;AAAA,QACF;AACA,cAAM;AAAA,UACJ;AAAA,QACF;AACA;AAAA,MACF;AAGA,YAAM,eAAe,MAAM,wBAAwB,YAAY;AAAA,QAC7D,MAAM;AAAA,UACJ,OAAO;AAAA,UACP,SAAS;AAAA,QACX;AAAA,MACF,CAAC;AAED,YAAM,QAAQ,sCAAsC;AACpD,gBAAU,aAAa,MAAM,kBAAkB,IAAI,eAAe;AAAA,IACpE,SAAS,OAAO;AACd,YAAM,eAAe,gBAAgB,KAAK;AAC1C,UAAI,YAAY,KAAK,GAAG;AACtB,cAAM,YAAY,aAAa,KAAK;AACpC,YACE,cAAc,sBACd,cAAc,kBACd;AACA,gBAAM,MAAM,uCAAuC;AACnD;AAAA,QACF;AAAA,MACF;AACA,YAAM,MAAM,YAAY;AAAA,IAC1B,UAAE;AACA,sBAAgB,KAAK;AAAA,IACvB;AAAA,EACF;AAEA,QAAM,YAAY,gBAAgB;AAElC,SACE;AAAA,IAAC;AAAA;AAAA,MACC,UAAU,aAAa,qBAAqB;AAAA,MAC5C,WAAU;AAAA,MAEV;AAAA,6BAAC,SAAI,WAAU,6BACb;AAAA,+BAAC,SAAI,WAAU,aACb;AAAA,gCAAC,SAAM,SAAQ,SAAQ,0BAAY;AAAA,YACnC;AAAA,cAAC;AAAA;AAAA,gBACC,IAAG;AAAA,gBACH,MAAK;AAAA,gBACL,aAAY;AAAA,gBACX,GAAG,SAAS,OAAO;AAAA,gBACpB,UAAU;AAAA;AAAA,YACZ;AAAA,YACC,OAAO,SACN,oBAAC,OAAE,WAAU,4BAA4B,iBAAO,MAAM,SAAQ;AAAA,aAElE;AAAA,UACA,qBAAC,SAAI,WAAU,aACb;AAAA,gCAAC,SAAM,SAAQ,YAAW,sBAAQ;AAAA,YAClC,qBAAC,SAAI,WAAU,YACb;AAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,IAAG;AAAA,kBACH,MAAM,eAAe,SAAS;AAAA,kBAC9B,cAAa;AAAA,kBACb,aAAY;AAAA,kBACX,GAAG,SAAS,UAAU;AAAA,kBACvB,UAAU;AAAA;AAAA,cACZ;AAAA,cACA;AAAA,gBAAC;AAAA;AAAA,kBACC,MAAK;AAAA,kBACL,SAAS,MAAM,gBAAgB,CAAC,YAAY;AAAA,kBAC5C,WAAU;AAAA,kBAET,yBACC,oBAAC,cAAW,WAAU,WAAU,IAEhC,oBAAC,WAAQ,WAAU,WAAU;AAAA;AAAA,cAEjC;AAAA,eACF;AAAA,YACC,OAAO,YACN,oBAAC,OAAE,WAAU,4BACV,iBAAO,SAAS,SACnB;AAAA,aAEJ;AAAA,WACF;AAAA,QAEA,qBAAC,SAAI,WAAU,0BACb;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,SAAQ;AAAA,cACR,SAAS;AAAA,cACT,UAAU;AAAA,cACX;AAAA;AAAA,UAED;AAAA,UACA,qBAAC,UAAO,MAAK,UAAS,UAAU,WAC7B;AAAA,yBAAa,oBAAC,WAAQ,WAAU,gBAAe;AAAA,YAC/C,aAAa,mBAAc;AAAA,aAC9B;AAAA,WACF;AAAA;AAAA;AAAA,EACF;AAEJ;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/auth/set-password.tsx"],"sourcesContent":["'use client';\n\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport {\n Alert,\n AlertDescription,\n AlertTitle,\n Button,\n Form,\n FormControl,\n FormField,\n FormItem,\n FormLabel,\n FormMessage,\n Input,\n useFormField,\n} from '@mesob/ui/components';\nimport { useMesob } from '@mesob/ui/providers';\nimport { IconAlertCircle, IconEye, IconEyeOff } from '@tabler/icons-react';\nimport type { ChangeEvent, ComponentProps } from 'react';\nimport { useEffect, useEffectEvent, useState } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { toast } from 'sonner';\nimport { z } from 'zod';\nimport { useTranslator } from '../../hooks/use-translator';\nimport { useApi, useConfig } from '../../provider';\nimport type { AuthErrorContent } from '../../utils/handle-error';\nimport { handleError } from '../../utils/handle-error';\nimport { normalizePhone } from '../../utils/normalize-phone';\nimport { AuthLayout } from './auth-layout';\n\ntype PasswordInputProps = {\n field: ComponentProps<'input'> & {\n value: string;\n onChange: (e: ChangeEvent<HTMLInputElement>) => void;\n onBlur: () => void;\n };\n show: boolean;\n onToggle: () => void;\n};\n\nfunction PasswordInput({ field, show, onToggle }: PasswordInputProps) {\n const { formItemId, error } = useFormField();\n return (\n <div className=\"relative\">\n <Input\n {...field}\n id={formItemId}\n type={show ? 'text' : 'password'}\n aria-invalid={!!error}\n className=\"pr-10\"\n />\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n className=\"absolute right-0 top-0 h-full px-3 text-muted-foreground hover:text-foreground\"\n onClick={onToggle}\n aria-label={show ? 'Hide password' : 'Show password'}\n >\n {show ? (\n <IconEyeOff className=\"h-4 w-4\" />\n ) : (\n <IconEye className=\"h-4 w-4\" />\n )}\n </Button>\n </div>\n );\n}\n\nconst setPasswordSchema = (t: (key: string) => string) =>\n z\n .object({\n password: z\n .string()\n .min(8, t('errors.passwordLength'))\n .max(128, t('errors.longPasswordError')),\n confirmPassword: z.string(),\n })\n .refine((data) => data.password === data.confirmPassword, {\n message: t('errors.passwordsMismatch'),\n path: ['confirmPassword'],\n });\n\ntype SetPasswordFormValues = z.infer<ReturnType<typeof setPasswordSchema>>;\n\ntype SetPasswordProps = {\n identifier?: string;\n redirectUrl?: string;\n};\n\ntype AccountState = {\n fullName: string;\n email: string | null;\n phone: string | null;\n};\n\nconst getPhoneRegex = (phoneRegex: RegExp | string | undefined) => {\n if (typeof phoneRegex === 'string') {\n return new RegExp(phoneRegex);\n }\n\n return phoneRegex || /^(\\+2519|\\+2517|2519|2517|09|07)\\d{8}$/;\n};\n\nconst normalizeIdentifier = (\n identifier: string,\n phoneRegex: RegExp | string | undefined,\n) => {\n const resolvedPhoneRegex = getPhoneRegex(phoneRegex);\n return resolvedPhoneRegex.test(identifier)\n ? normalizePhone(identifier)\n : identifier;\n};\n\nexport const SetPassword = function SetPassword({\n identifier,\n redirectUrl,\n}: SetPasswordProps = {}) {\n const { hooks, setAuth } = useApi();\n const { config } = useConfig();\n const mesob = useMesob();\n const t = useTranslator('Auth.setPassword');\n const Link = mesob?.navigation?.Link;\n const [error, setError] = useState<AuthErrorContent | null>(null);\n const [isLoading, setIsLoading] = useState(false);\n const [isChecking, setIsChecking] = useState(true);\n const [showPassword, setShowPassword] = useState(false);\n const [showConfirmPassword, setShowConfirmPassword] = useState(false);\n const [account, setAccount] = useState<AccountState | null>(null);\n\n const checkAccountMutation = hooks.useMutation('post', '/check-account');\n const setPasswordMutation = hooks.useMutation('post', '/password/set');\n\n const onNavigate =\n config.navigation?.onNavigate ||\n ((path: string) => {\n if (typeof window !== 'undefined') {\n window.location.href = path;\n }\n });\n const signInLink = config.navigation?.links?.signIn || '/auth/sign-in';\n const logoImage = config.ui.logoImage;\n const defaultRedirect =\n redirectUrl || config.navigation?.defaultRedirectUrl || '/';\n const form = useForm<SetPasswordFormValues>({\n resolver: zodResolver(setPasswordSchema(t)),\n defaultValues: {\n password: '',\n confirmPassword: '',\n },\n });\n\n useEffect(() => {\n if (error) {\n toast.error(error.title || 'Error', {\n description: error.description,\n });\n }\n }, [error]);\n\n const loadAccount = useEffectEvent(async () => {\n if (!identifier) {\n setError({\n title: t('errors.fallback'),\n description: t('errors.missingIdentifier'),\n });\n setIsChecking(false);\n return;\n }\n\n try {\n const normalizedIdentifier = normalizeIdentifier(\n identifier,\n config.phoneRegex,\n );\n const res = await checkAccountMutation.mutateAsync({\n body: { username: normalizedIdentifier },\n });\n\n if (!(res.exists && res.account && res.requiresPasswordSetup)) {\n setError({\n title: t('errors.fallback'),\n description: t('errors.accountNotEligible'),\n });\n setIsChecking(false);\n return;\n }\n\n setAccount({\n fullName: res.account.fullName,\n email: res.account.email,\n phone: res.account.phone,\n });\n } catch {\n setError({\n title: t('errors.fallback'),\n description: t('errors.accountLookupFailed'),\n });\n } finally {\n setIsChecking(false);\n }\n });\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: rerun only when route identifier changes\n useEffect(() => {\n loadAccount().catch(() => {\n setIsChecking(false);\n });\n }, [identifier]);\n\n const handleSubmit = form.handleSubmit(async (values) => {\n if (!identifier) {\n return;\n }\n\n setIsLoading(true);\n setError(null);\n\n try {\n const normalizedIdentifier = normalizeIdentifier(\n identifier,\n config.phoneRegex,\n );\n const res = await setPasswordMutation.mutateAsync({\n body: {\n identifier: normalizedIdentifier,\n password: values.password,\n },\n });\n\n if ('user' in res && 'session' in res) {\n setAuth(res);\n }\n onNavigate(defaultRedirect);\n } catch (err) {\n handleError(err, setError, t);\n } finally {\n setIsLoading(false);\n }\n });\n\n const accountLabel = account?.email\n ? t('form.emailLabel')\n : t('form.phoneLabel');\n const accountValue = account?.email || account?.phone || identifier || '';\n\n let errorContent: AuthErrorContent | null = null;\n if (error) {\n errorContent =\n typeof error === 'string'\n ? { title: 'Error', description: error }\n : error;\n }\n const showError = !isChecking && !!errorContent;\n const errorAlert = showError && errorContent && (\n <Alert variant=\"destructive\" className=\"mt-4\">\n <IconAlertCircle className=\"h-4 w-4\" />\n <AlertTitle>{errorContent.title}</AlertTitle>\n <AlertDescription>{errorContent.description}</AlertDescription>\n </Alert>\n );\n\n return (\n <AuthLayout\n title={config.ui.name}\n description={t('description')}\n logoImage={logoImage}\n footer={\n <p>\n {t('footer.hasPassword')}{' '}\n {Link ? (\n <Link href={signInLink} className=\"text-primary hover:underline\">\n {t('footer.signInCta')}\n </Link>\n ) : (\n <a\n href={signInLink}\n onClick={(e) => {\n e.preventDefault();\n onNavigate(signInLink);\n }}\n className=\"text-primary hover:underline\"\n >\n {t('footer.signInCta')}\n </a>\n )}\n </p>\n }\n >\n <Form {...form}>\n <form\n id=\"set-password-form\"\n onSubmit={handleSubmit}\n className=\"space-y-4\"\n >\n <FormItem>\n <FormLabel>{t('form.fullNameLabel')}</FormLabel>\n <FormControl>\n <Input value={account?.fullName || ''} disabled />\n </FormControl>\n </FormItem>\n <FormItem>\n <FormLabel>{accountLabel}</FormLabel>\n <FormControl>\n <Input value={accountValue} disabled />\n </FormControl>\n </FormItem>\n <FormField\n control={form.control}\n name=\"password\"\n render={({ field }) => (\n <FormItem>\n <FormLabel>{t('form.passwordLabel')}</FormLabel>\n <PasswordInput\n field={field}\n show={showPassword}\n onToggle={() => setShowPassword(!showPassword)}\n />\n <FormMessage />\n </FormItem>\n )}\n />\n <FormField\n control={form.control}\n name=\"confirmPassword\"\n render={({ field }) => (\n <FormItem>\n <FormLabel>{t('form.confirmPasswordLabel')}</FormLabel>\n <PasswordInput\n field={field}\n show={showConfirmPassword}\n onToggle={() => setShowConfirmPassword(!showConfirmPassword)}\n />\n <FormMessage />\n </FormItem>\n )}\n />\n <Button\n type=\"submit\"\n form=\"set-password-form\"\n className=\"w-full\"\n disabled={\n isChecking ||\n !account ||\n isLoading ||\n setPasswordMutation.isPending\n }\n >\n {isLoading || setPasswordMutation.isPending\n ? t('form.submitting')\n : t('form.submit')}\n </Button>\n </form>\n </Form>\n {errorAlert}\n </AuthLayout>\n );\n};\n"],"mappings":"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","names":["SetPassword"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/utils/cookie.ts","../src/provider.tsx","../src/lib/translations.ts","../src/types.ts","../src/utils/custom-fetch.ts"],"sourcesContent":["import type { AuthClientConfig } from '../types';\n\nconst isProduction =\n typeof process !== 'undefined' && process.env.NODE_ENV === 'production';\n\nexport const getSessionCookieName = (config: AuthClientConfig): string => {\n const prefix = config.prefix?.trim() || config.cookiePrefix?.trim() || '';\n const baseName = 'session_token';\n if (prefix) {\n return `${prefix}_${baseName}`;\n }\n return isProduction ? '__Host-session_token' : baseName;\n};\n","'use client';\n\nimport { QueryClient, QueryClientProvider } from '@tanstack/react-query';\nimport { deepmerge } from 'deepmerge-ts';\nimport createFetchClient from 'openapi-fetch';\nimport createClient from 'openapi-react-query';\nimport type { ReactNode } from 'react';\nimport { createContext, useContext, useMemo, useState } from 'react';\nimport type { paths } from './data/openapi';\nimport { createTranslator } from './lib/translations';\nimport {\n type AuthClientConfig,\n type AuthResponse,\n defaultAuthClientConfig,\n type Session,\n type User,\n} from './types';\nimport { getSessionCookieName } from './utils/cookie';\nimport { createCustomFetch } from './utils/custom-fetch';\n\n// biome-ignore lint/suspicious/noExplicitAny: OpenAPI hooks type\ntype OpenApiHooks = any;\n\n// --- Utility: Check if running on server ---\nfunction isServer(): boolean {\n return typeof document === 'undefined';\n}\n\n/**\n * @deprecated Cookie is httpOnly and cannot be read client-side.\n * Use `useSession().isAuthenticated` instead.\n * This function always returns false on client.\n */\nexport function hasAuthCookie(_cookieName: string): boolean {\n // Cookie is httpOnly, can't check client-side\n // Always return false - use useSession() for auth status\n return false;\n}\n\n// --- Types ---\nexport type AuthStatus = 'loading' | 'authenticated' | 'unauthenticated';\n\ntype AuthState = {\n user: User | null;\n session: Session | null;\n status: AuthStatus;\n error: Error | null;\n};\n\ntype SessionContextValue = AuthState & {\n isLoading: boolean;\n isAuthenticated: boolean;\n refresh: () => Promise<void>;\n signOut: () => Promise<void>;\n};\n\ntype ApiContextValue = {\n hooks: OpenApiHooks;\n setAuth: (auth: AuthResponse) => void;\n clearAuth: () => void;\n refresh: () => Promise<void>;\n};\n\ntype ConfigContextValue = {\n config: AuthClientConfig;\n cookieName: string;\n t: (key: string, params?: Record<string, string | number>) => string;\n};\n\nconst SessionContext = createContext<SessionContextValue | null>(null);\nconst ApiContext = createContext<ApiContextValue | null>(null);\nconst ConfigContext = createContext<ConfigContextValue | null>(null);\n\nconst queryClient = new QueryClient({\n defaultOptions: {\n queries: {\n refetchOnWindowFocus: false,\n },\n },\n});\n\n// --- Hooks ---\n\n/**\n * Get session state including user, session, and auth status.\n * - `status`: 'loading' | 'authenticated' | 'unauthenticated'\n * - `isLoading`: true while fetching session\n * - `isAuthenticated`: true if user and session exist\n */\nexport function useSession(): SessionContextValue {\n const context = useContext(SessionContext);\n if (!context) {\n throw new Error('useSession must be used within MesobAuthProvider');\n }\n return context;\n}\n\nexport function useApi(): ApiContextValue {\n const context = useContext(ApiContext);\n if (!context) {\n throw new Error('useApi must be used within MesobAuthProvider');\n }\n return context;\n}\n\nexport function useConfig(): ConfigContextValue {\n const context = useContext(ConfigContext);\n if (!context) {\n throw new Error('useConfig must be used within MesobAuthProvider');\n }\n return context;\n}\n\n/**\n * @deprecated Cookie is httpOnly, can't be checked client-side.\n * Use `useSession().isAuthenticated` instead.\n */\nexport function useHasAuthCookie(): boolean {\n const { status } = useSession();\n return status === 'authenticated' || status === 'loading';\n}\n\n// --- Provider ---\n\ntype MesobAuthProviderProps = {\n config: AuthClientConfig;\n children: ReactNode;\n};\n\nexport function MesobAuthProvider({\n config,\n children,\n}: MesobAuthProviderProps) {\n const mergedConfig = useMemo(\n () =>\n deepmerge(\n { ...defaultAuthClientConfig } as Partial<AuthClientConfig>,\n config,\n ) as AuthClientConfig,\n [config],\n );\n\n const api = useMemo(\n () =>\n createFetchClient<paths>({\n baseUrl: mergedConfig.baseURL,\n fetch: createCustomFetch(mergedConfig),\n }),\n [mergedConfig],\n );\n\n const hooks = useMemo(() => createClient(api), [api]);\n const cookieName = useMemo(\n () => getSessionCookieName(mergedConfig),\n [mergedConfig],\n );\n\n return (\n <QueryClientProvider client={queryClient}>\n <AuthStateProvider\n config={mergedConfig}\n hooks={hooks}\n cookieName={cookieName}\n >\n {children}\n </AuthStateProvider>\n </QueryClientProvider>\n );\n}\n\ntype AuthStateProviderProps = {\n config: AuthClientConfig;\n hooks: OpenApiHooks;\n cookieName: string;\n children: ReactNode;\n};\n\nfunction AuthStateProvider({\n config,\n hooks,\n cookieName,\n children,\n}: AuthStateProviderProps) {\n // Manual override for sign-out / sign-in\n const [override, setOverride] = useState<AuthState | null>(null);\n\n // Always fetch session - cookie is httpOnly, can't check client-side\n // Server will read the cookie and return user/session if valid\n const {\n data: sessionData,\n isLoading,\n isFetched,\n error: sessionError,\n refetch,\n } = hooks.useQuery(\n 'get',\n '/session',\n {},\n {\n enabled: !(override || isServer()),\n refetchOnMount: false,\n refetchOnWindowFocus: false,\n refetchOnReconnect: false,\n retry: false,\n gcTime: 0,\n staleTime: 0,\n },\n );\n\n // Derive state directly - no useEffect\n const user = override?.user ?? sessionData?.user ?? null;\n const session = override?.session ?? sessionData?.session ?? null;\n const error = override?.error ?? (sessionError as Error | null);\n\n // Check error status code\n const errorStatus = (() => {\n if (!sessionError) {\n return null;\n }\n const err = sessionError as { status?: number };\n return err.status ?? null;\n })();\n\n // Check if error is a network/connection error\n const isNetworkError = (() => {\n if (!sessionError) {\n return false;\n }\n const error = sessionError as Error & { cause?: unknown; data?: unknown };\n const errorMessage =\n error.message || String(error) || JSON.stringify(error);\n // Network errors: TypeError, DOMException, or fetch failures\n if (\n error instanceof TypeError ||\n error instanceof DOMException ||\n error.name === 'TypeError' ||\n errorMessage.includes('Failed to fetch') ||\n errorMessage.includes('ERR_CONNECTION_REFUSED') ||\n errorMessage.includes('NetworkError') ||\n errorMessage.includes('Network request failed') ||\n errorMessage.includes('fetch failed')\n ) {\n return true;\n }\n // Check error cause\n if (error.cause) {\n const causeStr = String(error.cause);\n if (\n causeStr.includes('Failed to fetch') ||\n causeStr.includes('ERR_CONNECTION_REFUSED') ||\n causeStr.includes('NetworkError')\n ) {\n return true;\n }\n }\n return false;\n })();\n\n // Compute status\n // biome-ignore lint: Status determination requires multiple checks\n const status: AuthStatus = (() => {\n if (override) {\n return override.status;\n }\n if (isServer()) {\n return 'loading';\n }\n if (user && session) {\n return 'authenticated';\n }\n // Check for network errors or auth errors first - allow auth page to show\n if (isNetworkError || errorStatus === 401) {\n return 'unauthenticated';\n }\n // If we have an error but it's not a network error, still check loading state\n if (sessionError && !isNetworkError && errorStatus !== 401) {\n if (errorStatus && errorStatus >= 500) {\n return 'authenticated';\n }\n // Other errors mean unauthenticated\n if (isFetched) {\n return 'unauthenticated';\n }\n }\n if (isLoading || !isFetched) {\n return 'loading';\n }\n if (isFetched && !user && !session) {\n return 'unauthenticated';\n }\n return 'unauthenticated';\n })();\n\n const signOutMutation = hooks.useMutation('post', '/sign-out');\n const t = createTranslator(config.messages || {});\n\n const setAuth = (auth: AuthResponse) => {\n setOverride({\n user: auth.user,\n session: auth.session,\n status: 'authenticated',\n error: null,\n });\n };\n\n const clearAuth = () => {\n setOverride({\n user: null,\n session: null,\n status: 'unauthenticated',\n error: null,\n });\n };\n\n const refresh = async () => {\n setOverride(null);\n await refetch();\n };\n\n const signOut = async () => {\n await signOutMutation.mutateAsync({});\n clearAuth();\n\n const redirectUrl = config.navigation?.defaultRedirectUrl || '/';\n\n if (config.navigation?.onNavigate) {\n config.navigation.onNavigate(redirectUrl);\n } else if (typeof window !== 'undefined') {\n window.location.href = redirectUrl;\n }\n };\n\n return (\n <ConfigContext.Provider value={{ config, cookieName, t }}>\n <ApiContext.Provider value={{ hooks, setAuth, clearAuth, refresh }}>\n <SessionContext.Provider\n value={{\n user,\n session,\n status,\n error,\n isLoading: status === 'loading',\n isAuthenticated: status === 'authenticated',\n refresh,\n signOut,\n }}\n >\n {children}\n </SessionContext.Provider>\n </ApiContext.Provider>\n </ConfigContext.Provider>\n );\n}\n","type Messages = Record<string, unknown>;\n\nexport function createTranslator(messages: Messages, namespace?: string) {\n return (key: string, params?: Record<string, string | number>): string => {\n const fullKey = namespace ? `${namespace}.${key}` : key;\n const keys = fullKey.split('.');\n\n let value: unknown = messages;\n for (const k of keys) {\n if (value && typeof value === 'object' && value !== null) {\n value = (value as Record<string, unknown>)[k];\n } else {\n return fullKey;\n }\n }\n\n if (typeof value !== 'string') {\n return fullKey;\n }\n\n // Simple parameter replacement\n if (params) {\n return value.replace(/\\{(\\w+)\\}/g, (_, param) =>\n String(params[param] ?? `{${param}}`),\n );\n }\n\n return value;\n };\n}\n","import type { PermissionTree } from '@mesob/common';\n\nexport type UIConfig = {\n logo: React.ReactNode;\n name: React.ReactNode;\n logoImage?: string;\n};\n\nexport type FeaturesConfig = {\n enableSignup?: boolean;\n enablePasswordReset?: boolean;\n enableEmailSignup?: boolean;\n enablePhoneSignup?: boolean;\n enableEmailSignIn?: boolean;\n enablePhoneSignIn?: boolean;\n allowedSignupEmailDomains?: string[];\n enableSocialSignup?: boolean;\n socialProviders?: string[];\n};\n\nexport type TenantConfig = {\n enabled: boolean;\n tenantId: string;\n};\n\nexport type NavigationConfig = {\n locale?: string;\n defaultRedirectUrl?: string;\n onNavigate?: (path: string) => void;\n linkComponent?: React.ComponentType<\n React.ComponentProps<'a'> & { href: string }\n >;\n links?: {\n signIn?: string;\n signUp?: string;\n forgotPassword?: string;\n setPassword?: string;\n };\n};\n\nexport type AuthClientConfig = {\n baseURL: string;\n ui: UIConfig;\n features?: FeaturesConfig;\n tenant?: TenantConfig;\n permissions?: PermissionTree;\n navigation?: NavigationConfig;\n messages?: Record<string, unknown>;\n /** @deprecated use `prefix` */\n cookiePrefix?: string;\n /** Must match API `prefix` (session cookie + KV namespace). */\n prefix?: string;\n phoneRegex?: RegExp | string;\n /** Default userType filter for users list (e.g. 'employee'). Omit or 'all' to show all. */\n defaultUserType?: string;\n};\n\ntype DefaultAuthClientConfig = {\n readonly features: {\n readonly enableSignup: true;\n readonly enablePasswordReset: true;\n readonly enableEmailSignup: true;\n readonly enablePhoneSignup: true;\n readonly enableEmailSignIn: true;\n readonly enablePhoneSignIn: true;\n readonly allowedSignupEmailDomains: [];\n readonly enableSocialSignup: false;\n readonly socialProviders: [];\n };\n readonly navigation: {\n readonly locale: 'en';\n };\n readonly prefix: 'msb';\n readonly phoneRegex: RegExp;\n};\n\nexport const defaultAuthClientConfig: DefaultAuthClientConfig = {\n features: {\n enableSignup: true,\n enablePasswordReset: true,\n enableEmailSignup: true,\n enablePhoneSignup: true,\n enableEmailSignIn: true,\n enablePhoneSignIn: true,\n allowedSignupEmailDomains: [],\n enableSocialSignup: false,\n socialProviders: [],\n },\n navigation: {\n locale: 'en',\n },\n prefix: 'msb',\n phoneRegex: /^(\\+2519|\\+2517|2519|2517|09|07)\\d{8}$/,\n} as const;\n\nexport type User = {\n id: string;\n tenantId: string;\n fullName: string;\n email: string | null;\n phone: string | null;\n handle?: string;\n image: string | null;\n emailVerified: boolean;\n phoneVerified: boolean;\n lastSignInAt?: string | null;\n /** Role IDs */\n roles?: string[] | null;\n roleCodes?: string[] | null;\n permissions?: string[] | null;\n};\n\nexport type Session = {\n id?: string;\n expiresAt: string;\n createdAt?: string;\n userAgent?: string | null;\n ip?: string | null;\n};\n\nexport type AuthResponse = {\n user: User;\n session: Session;\n sessionToken?: string;\n sessionExpiresAt?: string;\n};\n\nexport type AuthErrorCode =\n | 'USER_NOT_FOUND'\n | 'INVALID_PASSWORD'\n | 'USER_EXISTS'\n | 'VERIFICATION_EXPIRED'\n | 'VERIFICATION_MISMATCH'\n | 'VERIFICATION_NOT_FOUND'\n | 'TOO_MANY_ATTEMPTS'\n | 'REQUIRES_VERIFICATION'\n | 'UNAUTHORIZED'\n | 'ACCESS_DENIED'\n | 'HAS_NO_PASSWORD'\n | 'PASSWORD_ALREADY_SET'\n | 'RATE_LIMITED';\n\nexport type AuthError = {\n message: string;\n code?: AuthErrorCode;\n status?: number;\n details?: Record<string, unknown>;\n};\n","import type { AuthClientConfig } from '../types';\n\nexport const createCustomFetch = (_config: AuthClientConfig) => {\n return (input: RequestInfo | URL, init?: RequestInit): Promise<Response> => {\n if (input instanceof Request) {\n return fetch(input, { ...init, credentials: 'include' });\n }\n return fetch(input, { ...init, credentials: 'include' });\n };\n};\n"],"mappings":"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","names":["error"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/auth/sign-up.tsx"],"sourcesContent":["'use client';\n\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport {\n Alert,\n AlertDescription,\n AlertTitle,\n Button,\n Form,\n FormControl,\n FormField,\n FormItem,\n FormLabel,\n FormMessage,\n Input,\n useFormField,\n} from '@mesob/ui/components';\nimport { useMesob } from '@mesob/ui/providers';\nimport { IconAlertCircle, IconEye, IconEyeOff } from '@tabler/icons-react';\nimport type { ChangeEvent, ComponentProps } from 'react';\nimport { useEffect, useState } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { toast } from 'sonner';\nimport { z } from 'zod';\nimport { useTranslator } from '../../hooks/use-translator';\nimport { useApi, useConfig } from '../../provider';\nimport type { AuthErrorContent } from '../../utils/handle-error';\nimport { handleError } from '../../utils/handle-error';\nimport { AuthLayout } from './auth-layout';\n\nconst isPhone = (s: string) => /^\\+?[0-9()[\\]\\s-]{6,}$/.test(s);\nconst isEmail = (s: string) => z.email().safeParse(s).success;\nconst normalizeDomain = (value: string) =>\n value.trim().toLowerCase().replace(/^@/, '');\n\ntype SignUpValidationOptions = {\n allowEmailSignup: boolean;\n allowPhoneSignup: boolean;\n allowedSignupEmailDomains: string[];\n};\n\ntype PasswordInputProps = {\n field: ComponentProps<'input'> & {\n value: string;\n onChange: (e: ChangeEvent<HTMLInputElement>) => void;\n onBlur: () => void;\n };\n show: boolean;\n onToggle: () => void;\n autoComplete?: 'current-password' | 'new-password';\n};\n\nfunction PasswordInput({\n field,\n show,\n onToggle,\n autoComplete = 'current-password',\n}: PasswordInputProps) {\n const { formItemId, error } = useFormField();\n return (\n <div className=\"relative\">\n <Input\n {...field}\n id={formItemId}\n type={show ? 'text' : 'password'}\n autoComplete={autoComplete}\n aria-invalid={!!error}\n className=\"pr-10\"\n />\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n className=\"absolute right-0 top-0 h-full px-3 text-muted-foreground hover:text-foreground\"\n onClick={onToggle}\n aria-label={show ? 'Hide password' : 'Show password'}\n >\n {show ? (\n <IconEyeOff className=\"h-4 w-4\" />\n ) : (\n <IconEye className=\"h-4 w-4\" />\n )}\n </Button>\n </div>\n );\n}\n\ntype SignUpFormValues = {\n fullName: string;\n identifier: string;\n password: string;\n confirmPassword: string;\n};\n\ntype SignUpProps = {\n redirectUrl?: string;\n initialIdentifier?: string;\n};\n\nconst signUpSchema = (\n t: (key: string) => string,\n options: SignUpValidationOptions,\n) =>\n z\n .object({\n fullName: z.string().min(1, t('errors.fullNameRequired')),\n identifier: z\n .string()\n .trim()\n .min(1, t('errors.contactRequired'))\n .superRefine((value, ctx) => {\n const emailInput = isEmail(value);\n const phoneInput = isPhone(value);\n if (!(emailInput || phoneInput)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: t('errors.invalidEmailOrPhone'),\n });\n return;\n }\n if (emailInput && !options.allowEmailSignup) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: 'Email sign up is disabled',\n });\n return;\n }\n if (phoneInput && !options.allowPhoneSignup) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: 'Phone sign up is disabled',\n });\n return;\n }\n if (\n emailInput &&\n options.allowedSignupEmailDomains.length > 0 &&\n !options.allowedSignupEmailDomains.includes(\n normalizeDomain(value.split('@')[1] || ''),\n )\n ) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: 'Email domain is not allowed for sign up',\n });\n }\n }),\n password: z\n .string()\n .min(8, t('errors.passwordLength'))\n .max(128, t('errors.longPasswordError')),\n confirmPassword: z.string(),\n })\n .refine((data) => data.password === data.confirmPassword, {\n message: t('errors.passwordsMismatch'),\n path: ['confirmPassword'],\n });\n\nexport const SignUp = ({\n redirectUrl,\n initialIdentifier,\n}: SignUpProps = {}) => {\n const { hooks, setAuth } = useApi();\n const { config } = useConfig();\n const mesob = useMesob();\n const t = useTranslator('Auth.signUp');\n const Link = mesob?.navigation?.Link;\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<AuthErrorContent | null>(null);\n const [showPassword, setShowPassword] = useState(false);\n const [showConfirmPassword, setShowConfirmPassword] = useState(false);\n const signupEnabled = config.features?.enableSignup !== false;\n const allowEmailSignup = config.features?.enableEmailSignup !== false;\n const allowPhoneSignup = config.features?.enablePhoneSignup !== false;\n const allowedSignupEmailDomains = (\n config.features?.allowedSignupEmailDomains || []\n )\n .map(normalizeDomain)\n .filter(Boolean);\n const hasSignupIdentifierChannel = allowEmailSignup || allowPhoneSignup;\n const isSignupAvailable = signupEnabled && hasSignupIdentifierChannel;\n\n const signUpMutation = hooks.useMutation('post', '/sign-up');\n\n const signInLink = config.navigation?.links?.signIn || '/auth/sign-in';\n const onNavigate =\n config.navigation?.onNavigate ||\n ((path: string) => {\n if (typeof window !== 'undefined') {\n window.location.href = path;\n }\n });\n const logoImage = config.ui.logoImage;\n const defaultRedirect =\n redirectUrl || config.navigation?.defaultRedirectUrl || '/';\n\n const hasInitialIdentifier = !!initialIdentifier;\n\n const form = useForm<SignUpFormValues>({\n resolver: zodResolver(\n signUpSchema(t, {\n allowEmailSignup,\n allowPhoneSignup,\n allowedSignupEmailDomains,\n }),\n ),\n defaultValues: {\n fullName: '',\n identifier: initialIdentifier || '',\n password: '',\n confirmPassword: '',\n },\n mode: 'onSubmit',\n reValidateMode: 'onSubmit',\n });\n\n useEffect(() => {\n if (initialIdentifier) {\n form.setValue('identifier', initialIdentifier);\n }\n }, [initialIdentifier, form]);\n\n useEffect(() => {\n if (error) {\n toast.error(error.title || 'Error', {\n description: error.description,\n });\n }\n }, [error]);\n\n const handleSubmit = form.handleSubmit(async (values) => {\n if (!signupEnabled) {\n form.setError('identifier', { message: 'Sign up is disabled' });\n return;\n }\n if (!hasSignupIdentifierChannel) {\n form.setError('identifier', {\n message: 'Sign up is unavailable for email and phone',\n });\n return;\n }\n setIsLoading(true);\n setError(null);\n\n try {\n const identifier = values.identifier.trim();\n const usingPhone =\n allowPhoneSignup && (isPhone(identifier) || !allowEmailSignup);\n\n const res = await signUpMutation.mutateAsync({\n body: usingPhone\n ? {\n phone: identifier,\n password: values.password,\n fullName: values.fullName,\n }\n : {\n email: identifier,\n password: values.password,\n fullName: values.fullName,\n },\n });\n\n if ('verificationId' in res && res.verificationId) {\n const redirectParam = defaultRedirect\n ? `&redirect=${encodeURIComponent(defaultRedirect)}`\n : '';\n if (usingPhone) {\n onNavigate(\n `/auth/verify-phone?context=sign-up&verificationId=${res.verificationId}&phone=${encodeURIComponent(identifier)}${redirectParam}`,\n );\n } else {\n onNavigate(\n `/auth/verify-email?verificationId=${res.verificationId}&email=${encodeURIComponent(identifier)}${redirectParam}`,\n );\n }\n return;\n }\n\n if ('user' in res && 'session' in res) {\n setAuth(res);\n }\n onNavigate(defaultRedirect);\n } catch (err) {\n handleError(err, setError, t);\n } finally {\n setIsLoading(false);\n }\n });\n\n const getIdentifierLabel = () => {\n if (allowEmailSignup && !allowPhoneSignup) {\n return t('form.emailLabel');\n }\n if (!allowEmailSignup && allowPhoneSignup) {\n return t('form.phoneLabel');\n }\n if (!hasInitialIdentifier) {\n return t('form.accountLabel') || 'Email/Phone';\n }\n if (initialIdentifier?.includes('@')) {\n return t('form.emailLabel');\n }\n return t('form.phoneLabel');\n };\n const identifierLabel = getIdentifierLabel();\n let signupUnavailableDescription = 'No sign up channel is enabled.';\n if (!signupEnabled) {\n signupUnavailableDescription = 'Sign up is disabled.';\n }\n\n let identifierInputType: 'email' | 'tel' = 'email';\n if (!allowEmailSignup && allowPhoneSignup) {\n identifierInputType = 'tel';\n } else if (allowEmailSignup && allowPhoneSignup) {\n identifierInputType = isPhone(form.watch('identifier')) ? 'tel' : 'email';\n }\n\n let errorContent: AuthErrorContent | null = null;\n if (error) {\n if (typeof error === 'string') {\n errorContent = { title: 'Error', description: error };\n } else {\n errorContent = error;\n }\n }\n\n return (\n <AuthLayout\n title={config.ui.name}\n description={t('description')}\n logoImage={logoImage}\n footer={\n <p>\n {t('footer.hasAccount')}{' '}\n {Link ? (\n <Link href={signInLink} className=\"text-primary hover:underline\">\n {t('footer.signInCta')}\n </Link>\n ) : (\n <a\n href={signInLink}\n onClick={(e) => {\n e.preventDefault();\n onNavigate(signInLink);\n }}\n className=\"text-primary hover:underline\"\n >\n {t('footer.signInCta')}\n </a>\n )}\n </p>\n }\n >\n {isSignupAvailable ? null : (\n <Alert variant=\"destructive\">\n <IconAlertCircle className=\"h-4 w-4\" />\n <AlertTitle>Sign up unavailable</AlertTitle>\n <AlertDescription>{signupUnavailableDescription}</AlertDescription>\n </Alert>\n )}\n <Form {...form}>\n <form\n id=\"sign-up-form\"\n autoComplete=\"on\"\n onSubmit={handleSubmit}\n className=\"space-y-4\"\n >\n <FormField\n control={form.control}\n name=\"fullName\"\n render={({ field }) => (\n <FormItem>\n <FormLabel>{t('form.fullNameLabel')}</FormLabel>\n <FormControl>\n <Input {...field} autoComplete=\"name\" />\n </FormControl>\n <FormMessage />\n </FormItem>\n )}\n />\n <FormField\n control={form.control}\n name=\"identifier\"\n render={({ field }) => (\n <FormItem>\n <FormLabel\n className={hasInitialIdentifier ? 'block' : undefined}\n >\n {identifierLabel}\n </FormLabel>\n <FormControl>\n <Input\n {...field}\n type={identifierInputType}\n autoComplete={identifierInputType}\n disabled={hasInitialIdentifier}\n />\n </FormControl>\n <FormMessage />\n </FormItem>\n )}\n />\n <FormField\n control={form.control}\n name=\"password\"\n render={({ field }) => (\n <FormItem>\n <FormLabel>{t('form.passwordLabel')}</FormLabel>\n <PasswordInput\n field={field}\n show={showPassword}\n onToggle={() => setShowPassword(!showPassword)}\n autoComplete=\"new-password\"\n />\n <FormMessage />\n </FormItem>\n )}\n />\n <FormField\n control={form.control}\n name=\"confirmPassword\"\n render={({ field }) => (\n <FormItem>\n <FormLabel>{t('form.confirmPasswordLabel')}</FormLabel>\n <PasswordInput\n field={field}\n show={showConfirmPassword}\n onToggle={() => setShowConfirmPassword(!showConfirmPassword)}\n autoComplete=\"new-password\"\n />\n <FormMessage />\n </FormItem>\n )}\n />\n <Button\n type=\"submit\"\n form=\"sign-up-form\"\n className=\"w-full\"\n disabled={\n isLoading ||\n signUpMutation.isPending ||\n !signupEnabled ||\n !hasSignupIdentifierChannel\n }\n >\n {isLoading || signUpMutation.isPending\n ? t('form.submitting')\n : t('form.submit')}\n </Button>\n </form>\n </Form>\n {errorContent && (\n <Alert variant=\"destructive\" className=\"mt-4\">\n <IconAlertCircle className=\"h-4 w-4\" />\n <AlertTitle>{errorContent.title}</AlertTitle>\n <AlertDescription>{errorContent.description}</AlertDescription>\n </Alert>\n )}\n </AuthLayout>\n );\n};\n"],"mappings":"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","names":[]}