create-mithaq 0.1.1 → 0.2.1
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.
- package/LICENSES/openstatus-time-picker.txt +21 -0
- package/index.js +457 -63
- package/package.json +1 -1
- package/template/apps/{asas-platform → asas-backoffice}/package.json +5 -3
- package/template/apps/{asas-platform → asas-backoffice}/src/api.ts +1 -1
- package/template/apps/{asas-platform → asas-backoffice}/src/auth-frame.tsx +12 -12
- package/template/apps/asas-backoffice/src/components.ts +35 -0
- package/template/apps/asas-backoffice/src/first-user.ts +14 -0
- package/template/apps/{asas-platform → asas-backoffice}/src/links.ts +1 -1
- package/template/apps/{asas-platform → asas-backoffice}/src/locale-switch.tsx +7 -5
- package/template/apps/asas-backoffice/src/no-organization.tsx +5 -0
- package/template/apps/asas-backoffice/src/redirect.ts +1 -0
- package/template/apps/{asas-platform → asas-backoffice}/src/request-headers.ts +1 -1
- package/template/apps/asas-backoffice/src/routeTree.gen.ts +206 -0
- package/template/apps/asas-backoffice/src/router.tsx +18 -0
- package/template/apps/asas-backoffice/src/routes/(screens)/backoffice/files.ts +10 -0
- package/template/apps/{asas-platform/src/routes/(screens)/platform → asas-backoffice/src/routes/(screens)/backoffice}/screen.json +426 -64
- package/template/apps/{asas-platform/src/routes/(screens)/platform → asas-backoffice/src/routes/(screens)/backoffice}/types.ts +18 -0
- package/template/apps/{asas-platform/src/routes/(screens)/platform.$.tsx → asas-backoffice/src/routes/(screens)/backoffice.$.tsx} +4 -4
- package/template/apps/{asas-platform/src/routes/(screens)/platform.index.tsx → asas-backoffice/src/routes/(screens)/backoffice.index.tsx} +3 -3
- package/template/apps/{asas-platform/src/routes/(screens)/platform.tsx → asas-backoffice/src/routes/(screens)/backoffice.tsx} +3 -3
- package/template/apps/{asas-platform → asas-backoffice}/src/routes/__root.tsx +2 -2
- package/template/apps/asas-backoffice/src/routes/api/$.ts +34 -0
- package/template/apps/asas-backoffice/src/routes/auth.create-first-user.tsx +113 -0
- package/template/apps/{asas-platform → asas-backoffice}/src/routes/auth.sign-in.tsx +9 -4
- package/template/apps/{asas-platform → asas-backoffice}/src/routes/unauthorized.tsx +24 -12
- package/template/apps/{asas-platform → asas-backoffice}/src/screen-form.tsx +5 -3
- package/template/apps/{asas-platform → asas-backoffice}/src/screen-list.tsx +6 -5
- package/template/apps/{asas-platform → asas-backoffice}/src/screen-names.ts +1 -1
- package/template/apps/{asas-platform → asas-backoffice}/src/screens.tsx +46 -26
- package/template/apps/asas-backoffice/src/server.ts +30 -0
- package/template/apps/{asas-platform → asas-backoffice}/src/slide.ts +1 -1
- package/template/apps/{asas-platform → asas-backoffice}/src/start.ts +1 -1
- package/template/apps/{asas-platform → asas-backoffice}/src/styles.css +9 -7
- package/template/apps/{asas-platform → asas-backoffice}/tsconfig.json +2 -2
- package/template/apps/{asas-platform → asas-backoffice}/vite.config.ts +7 -1
- package/template/apps/asas-tanstack/package.json +4 -2
- package/template/apps/asas-tanstack/src/api.ts +1 -1
- package/template/apps/asas-tanstack/src/auth-frame.tsx +12 -12
- package/template/apps/asas-tanstack/src/choose-password.tsx +150 -0
- package/template/apps/asas-tanstack/src/components.ts +35 -0
- package/template/apps/asas-tanstack/src/copy.ts +416 -79
- package/template/apps/asas-tanstack/src/first-run.ts +16 -0
- package/template/apps/asas-tanstack/src/links.ts +1 -1
- package/template/apps/asas-tanstack/src/locale-switch.tsx +7 -5
- package/template/apps/asas-tanstack/src/no-organization.tsx +108 -0
- package/template/apps/asas-tanstack/src/redirect.ts +20 -1
- package/template/apps/asas-tanstack/src/request-headers.ts +1 -1
- package/template/apps/asas-tanstack/src/routeTree.gen.ts +42 -0
- package/template/apps/asas-tanstack/src/router.tsx +12 -1
- package/template/apps/asas-tanstack/src/routes/(screens)/dashboard/files.ts +9 -2
- package/template/apps/asas-tanstack/src/routes/(screens)/dashboard/screen.json +475 -116
- package/template/apps/asas-tanstack/src/routes/(screens)/dashboard/types.ts +4 -2
- package/template/apps/asas-tanstack/src/routes/(screens)/portal/files.ts +7 -2
- package/template/apps/asas-tanstack/src/routes/(screens)/portal/screen.json +83 -319
- package/template/apps/asas-tanstack/src/routes/(screens)/portal/types.ts +3 -1
- package/template/apps/asas-tanstack/src/routes/__root.tsx +1 -1
- package/template/apps/asas-tanstack/src/routes/auth.accept-invitation.tsx +14 -7
- package/template/apps/asas-tanstack/src/routes/auth.first-run.tsx +114 -0
- package/template/apps/asas-tanstack/src/routes/auth.forgot-password.tsx +2 -2
- package/template/apps/asas-tanstack/src/routes/auth.handoff.ts +5 -5
- package/template/apps/asas-tanstack/src/routes/auth.reset-password.tsx +7 -100
- package/template/apps/asas-tanstack/src/routes/auth.set-password.tsx +16 -0
- package/template/apps/asas-tanstack/src/routes/auth.sign-in.tsx +27 -15
- package/template/apps/asas-tanstack/src/routes/auth.sign-up.tsx +59 -38
- package/template/apps/asas-tanstack/src/routes/index.tsx +18 -14
- package/template/apps/asas-tanstack/src/routes/unauthorized.tsx +24 -12
- package/template/apps/asas-tanstack/src/screen-form.tsx +5 -3
- package/template/apps/asas-tanstack/src/screen-list.tsx +6 -5
- package/template/apps/asas-tanstack/src/screen-names.ts +1 -1
- package/template/apps/asas-tanstack/src/screens.tsx +46 -26
- package/template/apps/asas-tanstack/src/server.ts +10 -0
- package/template/apps/asas-tanstack/src/slide.ts +1 -1
- package/template/apps/asas-tanstack/src/styles.css +7 -3
- package/template/apps/asas-tanstack/tsconfig.json +2 -2
- package/template/apps/asas-tanstack/vite.config.ts +7 -1
- package/template/package.json +3 -3
- package/template/templates/asas/.claude/skills/add-field/SKILL.md +27 -0
- package/template/templates/asas/.claude/skills/add-kayan/SKILL.md +26 -0
- package/template/templates/asas/.claude/skills/eject-admin-piece/SKILL.md +28 -0
- package/template/templates/asas/.claude/skills/upgrade-mithaq/SKILL.md +35 -0
- package/template/templates/asas/.env.example +22 -5
- package/template/templates/asas/AGENTS.md +101 -0
- package/template/templates/asas/CLAUDE.md +1 -0
- package/template/templates/asas/README.md +1094 -0
- package/template/templates/asas/package.json +19 -4
- package/template/templates/asas/src/asas.ts +81 -56
- package/template/templates/asas/src/{platform-http.ts → backoffice-http.ts} +48 -27
- package/template/templates/asas/src/dev-setup.ts +112 -0
- package/template/templates/asas/src/local-database.ts +22 -0
- package/template/templates/asas/src/messages/account.json +129 -103
- package/template/templates/asas/src/messages/auditLog.json +223 -105
- package/template/templates/asas/src/messages/backofficeLog.json +132 -0
- package/template/templates/asas/src/messages/courses.json +256 -214
- package/template/templates/asas/src/messages/enrollments.json +45 -27
- package/template/templates/asas/src/messages/invitation.json +72 -56
- package/template/templates/asas/src/messages/localUsers.json +34 -28
- package/template/templates/asas/src/messages/media.json +31 -21
- package/template/templates/asas/src/messages/member.json +59 -39
- package/template/templates/asas/src/messages/memberRoles.json +37 -31
- package/template/templates/asas/src/messages/mithaq.json +206 -162
- package/template/templates/asas/src/messages/organization.json +63 -41
- package/template/templates/asas/src/messages/organizationRole.json +59 -47
- package/template/templates/asas/src/messages/roles.json +59 -45
- package/template/templates/asas/src/messages/session.json +99 -79
- package/template/templates/asas/src/messages/sessions.json +110 -80
- package/template/templates/asas/src/messages/settings.json +51 -53
- package/template/templates/asas/src/messages/tags.json +31 -21
- package/template/templates/asas/src/messages/user.json +109 -87
- package/template/templates/asas/src/messages/verification.json +59 -47
- package/template/templates/asas/src/migrations/20261014221355_tags_restrict/migration.sql +1 -0
- package/template/templates/asas/src/migrations/20261014221355_tags_restrict/snapshot.json +3881 -0
- package/template/templates/asas/src/migrations/20261014222218_one_seat_per_session/migration.sql +1 -0
- package/template/templates/asas/src/migrations/20261014222218_one_seat_per_session/snapshot.json +3894 -0
- package/template/templates/asas/src/migrations/20261014223522_session_archive_reason/migration.sql +1 -0
- package/template/templates/asas/src/migrations/20261014223522_session_archive_reason/snapshot.json +3907 -0
- package/template/templates/asas/src/migrations/20261014225728_course_archive_by_operation/migration.sql +1 -0
- package/template/templates/asas/src/migrations/20261014225728_course_archive_by_operation/snapshot.json +3907 -0
- package/template/templates/asas/src/migrations/20261015042444_organization_names/migration.sql +1 -0
- package/template/templates/asas/src/migrations/20261015042444_organization_names/snapshot.json +3920 -0
- package/template/templates/asas/src/migrations/20261015053212_member_last_seen/migration.sql +1 -0
- package/template/templates/asas/src/migrations/20261015053212_member_last_seen/snapshot.json +3933 -0
- package/template/templates/asas/src/migrations/20261015093203_activity_and_staff_history/migration.sql +15 -0
- package/template/templates/asas/src/migrations/20261015093203_activity_and_staff_history/snapshot.json +4113 -0
- package/template/templates/asas/src/migrations/20261015095752_portal/migration.sql +2 -0
- package/template/templates/asas/src/migrations/20261015095752_portal/snapshot.json +4113 -0
- package/template/templates/asas/src/migrations/20261015135529_better_auth_indexes/migration.sql +9 -0
- package/template/templates/asas/src/migrations/20261015135529_better_auth_indexes/snapshot.json +4302 -0
- package/template/templates/asas/src/migrations/20261015162438_audit_changes_json/migration.sql +27 -0
- package/template/templates/asas/src/migrations/20261015162438_audit_changes_json/snapshot.json +4289 -0
- package/template/templates/asas/src/migrations/schema.ts +1 -0
- package/template/templates/asas/src/mithaq.ts +4 -406
- package/template/templates/asas/src/organizations.ts +3 -0
- package/template/templates/asas/src/seed.ts +147 -45
- package/template/templates/asas/src/{ui-platform → ui-backoffice}/home.tsx +9 -9
- package/template/templates/asas/src/ui-backoffice/organization-actions.tsx +121 -0
- package/template/templates/asas/src/{ui-platform → ui-backoffice}/record-page.tsx +4 -4
- package/template/templates/asas/src/{ui-platform → ui-backoffice}/role-cells.tsx +13 -6
- package/template/templates/asas/src/{ui-platform → ui-backoffice}/user-actions.tsx +46 -48
- package/template/templates/asas/src/ui-dashboard/dashboard.tsx +10 -4
- package/template/templates/asas/src/ui-dashboard/home.tsx +73 -0
- package/template/templates/asas/src/ui-dashboard/members-card.tsx +147 -0
- package/template/templates/asas/src/ui-dashboard/members.tsx +637 -438
- package/template/templates/asas/src/ui-dashboard/versions.tsx +22 -8
- package/template/templates/asas/src/ui-portal/courses-home.tsx +96 -0
- package/template/templates/asas/src/ui-portal/home.tsx +9 -13
- package/template/templates/features/audit-log/audit-log/audit-log.ts +284 -0
- package/template/templates/features/audit-log/backoffice-log/backoffice-log.ts +67 -0
- package/template/templates/features/audit-log/index.ts +4 -0
- package/template/templates/features/audit-log/package.json +13 -0
- package/template/templates/features/auth/index.ts +11 -0
- package/template/templates/{asas/src → features/auth}/local-users/local-users.ts +7 -7
- package/template/templates/{auth → features/auth}/package.json +2 -3
- package/template/templates/{asas/src/kayan → features}/auth/user/account.access.ts +2 -2
- package/template/templates/{asas/src/kayan → features}/auth/user/account.ts +2 -2
- package/template/templates/{asas/src/kayan → features}/auth/user/invitation.access.ts +1 -1
- package/template/templates/{asas/src/kayan → features}/auth/user/invitation.ts +3 -3
- package/template/templates/{asas/src/kayan → features}/auth/user/member.access.ts +4 -4
- package/template/templates/{asas/src/kayan → features}/auth/user/member.screens.ts +5 -5
- package/template/templates/{asas/src/kayan → features}/auth/user/member.ts +4 -3
- package/template/templates/{asas/src/kayan → features}/auth/user/organization.access.ts +6 -6
- package/template/templates/{asas/src/kayan → features}/auth/user/organization.screens.ts +6 -6
- package/template/templates/{asas/src/kayan → features}/auth/user/organization.ts +2 -1
- package/template/templates/{asas/src/kayan → features}/auth/user/organizationRole.access.ts +2 -2
- package/template/templates/{asas/src/kayan → features}/auth/user/organizationRole.ts +3 -3
- package/template/templates/{asas/src/kayan → features}/auth/user/session.access.ts +2 -2
- package/template/templates/{asas/src/kayan → features}/auth/user/session.ts +2 -2
- package/template/templates/{asas/src/kayan → features}/auth/user/user.access.ts +8 -7
- package/template/templates/{asas/src/kayan → features}/auth/user/user.screens.ts +9 -9
- package/template/templates/{asas/src/kayan → features}/auth/user/user.ts +2 -2
- package/template/templates/{asas/src/kayan → features}/auth/user/verification.access.ts +2 -2
- package/template/templates/{asas/src/kayan → features}/auth/user/verification.ts +2 -2
- package/template/templates/{asas/src → features/courses}/courses/courses.ts +122 -133
- package/template/templates/features/courses/courses/cover-reads.ts +33 -0
- package/template/templates/features/courses/courses/ui/archived-badge.tsx +9 -0
- package/template/templates/{asas/src → features/courses}/courses/ui/fee-cell.tsx +1 -1
- package/template/templates/{asas/src → features/courses}/courses/ui/status-cell.tsx +5 -3
- package/template/templates/features/courses/courses/ui/unpublish-button.tsx +15 -0
- package/template/templates/features/courses/domain/archive.ts +39 -0
- package/template/templates/features/courses/domain/on-offer.ts +6 -0
- package/template/templates/features/courses/enrollments/enrollments.ts +309 -0
- package/template/templates/{asas/src → features/courses}/enrollments/ui/session-cell.tsx +17 -7
- package/template/templates/{asas/src → features/courses/enrollments}/ui/session-labels.tsx +3 -3
- package/template/templates/features/courses/index.ts +8 -0
- package/template/templates/features/courses/package.json +24 -0
- package/template/templates/features/courses/portal/ui/catalogue.tsx +86 -0
- package/template/templates/features/courses/portal/ui/course.tsx +176 -0
- package/template/templates/features/courses/portal/ui/enrollments.tsx +170 -0
- package/template/templates/features/courses/portal/ui/parts.tsx +95 -0
- package/template/templates/features/courses/portal/ui/reads.ts +76 -0
- package/template/templates/features/courses/portal/ui/rules.ts +87 -0
- package/template/templates/features/courses/portal/ui/shell.tsx +194 -0
- package/template/templates/features/courses/sessions/seats.ts +42 -0
- package/template/templates/{asas/src → features/courses}/sessions/sessions.ts +45 -14
- package/template/templates/features/media/index.ts +10 -0
- package/template/templates/{asas/src → features/media}/media/media.ts +34 -40
- package/template/templates/{asas/src → features/media}/media/ui/preview.tsx +2 -2
- package/template/templates/features/media/package.json +19 -0
- package/template/templates/features/roles/index.ts +4 -0
- package/template/templates/{asas/src → features/roles}/member-roles/member-roles.ts +15 -15
- package/template/templates/features/roles/package.json +21 -0
- package/template/templates/{asas/src → features/roles}/roles/roles.ts +23 -23
- package/template/templates/{asas/src → features/roles}/roles/ui/role-form.tsx +65 -24
- package/template/templates/{asas/src → features/roles}/roles/ui/roles.tsx +49 -25
- package/template/templates/features/settings/index.ts +3 -0
- package/template/templates/features/settings/package.json +13 -0
- package/template/templates/{asas/src → features/settings}/settings/settings.ts +12 -17
- package/template/templates/features/tags/index.ts +3 -0
- package/template/templates/features/tags/package.json +14 -0
- package/template/templates/{asas/src → features/tags}/tags/tags.ts +15 -15
- package/template/templates/mithaq/package.json +33 -0
- package/template/templates/mithaq/src/mail/index.ts +32 -0
- package/template/templates/mithaq/src/mail/mailers.ts +36 -0
- package/template/templates/{asas/src/audit-log/sink.ts → mithaq/src/mithaq/audit-sink.ts} +31 -9
- package/template/templates/{auth/src/platform-roles.ts → mithaq/src/mithaq/auth/backoffice-roles.ts} +44 -23
- package/template/templates/mithaq/src/mithaq/auth/index.ts +1859 -0
- package/template/templates/mithaq/src/mithaq/auth/organizations.ts +80 -0
- package/template/templates/{asas/src → mithaq/src/mithaq}/pages.ts +16 -7
- package/template/templates/mithaq/src/mithaq/rich-text-nodes.ts +19 -0
- package/template/templates/mithaq/src/mithaq.ts +593 -0
- package/template/templates/mithaq/src/roles/default-member-roles.ts +29 -0
- package/template/templates/{asas → mithaq}/src/roles/grants.ts +1 -1
- package/template/templates/mithaq/src/roles/member-access.ts +11 -0
- package/template/templates/{asas/src → mithaq/src/roles}/statements.ts +6 -4
- package/template/templates/mithaq/src/roles/system-roles.ts +16 -0
- package/template/templates/{asas/src → mithaq/src/roles}/tenant-access.ts +96 -57
- package/template/templates/{asas/src → mithaq/src/roles}/tenant-roles.ts +84 -25
- package/template/templates/{asas → mithaq}/src/steps/expected-updated-at.ts +2 -2
- package/template/templates/{asas → mithaq}/src/storage/index.ts +3 -1
- package/template/templates/mithaq/src/ui/activity-page.tsx +33 -0
- package/template/templates/mithaq/src/ui/activity.tsx +527 -0
- package/template/templates/{asas → mithaq}/src/ui/app-shell.tsx +27 -19
- package/template/templates/mithaq/src/ui/rich-text-nodes.tsx +33 -0
- package/template/templates/{asas → mithaq}/src/ui/screen-nav.tsx +1 -1
- package/template/templates/{asas → mithaq}/src/ui/top-shell.tsx +8 -8
- package/template/apps/asas-platform/src/components/mithaq/cells.tsx +0 -112
- package/template/apps/asas-platform/src/components/mithaq/controls.tsx +0 -650
- package/template/apps/asas-platform/src/components/mithaq/field-shell.tsx +0 -53
- package/template/apps/asas-platform/src/components/mithaq/filter-operators.ts +0 -108
- package/template/apps/asas-platform/src/components/mithaq/form.tsx +0 -1467
- package/template/apps/asas-platform/src/components/mithaq/list-columns.tsx +0 -108
- package/template/apps/asas-platform/src/components/mithaq/list-filters.tsx +0 -368
- package/template/apps/asas-platform/src/components/mithaq/list-pagination.tsx +0 -153
- package/template/apps/asas-platform/src/components/mithaq/list-query.ts +0 -432
- package/template/apps/asas-platform/src/components/mithaq/list-selection.tsx +0 -74
- package/template/apps/asas-platform/src/components/mithaq/list.tsx +0 -865
- package/template/apps/asas-platform/src/components/mithaq/nav.tsx +0 -871
- package/template/apps/asas-platform/src/components/mithaq/nodes.tsx +0 -1024
- package/template/apps/asas-platform/src/components/mithaq/relationship-cell.tsx +0 -127
- package/template/apps/asas-platform/src/components/mithaq/relationship-control.tsx +0 -400
- package/template/apps/asas-platform/src/components/mithaq/rich-text-nodes.ts +0 -6
- package/template/apps/asas-platform/src/components/mithaq/rich-text.tsx +0 -1083
- package/template/apps/asas-platform/src/components/mithaq/upload.tsx +0 -686
- package/template/apps/asas-platform/src/components/ui/drawer.tsx +0 -216
- package/template/apps/asas-platform/src/redirect.ts +0 -1
- package/template/apps/asas-platform/src/routeTree.gen.ts +0 -181
- package/template/apps/asas-platform/src/router.tsx +0 -7
- package/template/apps/asas-platform/src/routes/(screens)/platform/files.ts +0 -4
- package/template/apps/asas-platform/src/routes/api/$.ts +0 -30
- package/template/apps/asas-platform/src/server.ts +0 -20
- package/template/apps/asas-tanstack/src/components/mithaq/cells.tsx +0 -112
- package/template/apps/asas-tanstack/src/components/mithaq/controls.tsx +0 -650
- package/template/apps/asas-tanstack/src/components/mithaq/field-shell.tsx +0 -53
- package/template/apps/asas-tanstack/src/components/mithaq/filter-operators.ts +0 -108
- package/template/apps/asas-tanstack/src/components/mithaq/form.tsx +0 -1467
- package/template/apps/asas-tanstack/src/components/mithaq/list-columns.tsx +0 -108
- package/template/apps/asas-tanstack/src/components/mithaq/list-filters.tsx +0 -368
- package/template/apps/asas-tanstack/src/components/mithaq/list-pagination.tsx +0 -153
- package/template/apps/asas-tanstack/src/components/mithaq/list-query.ts +0 -432
- package/template/apps/asas-tanstack/src/components/mithaq/list-selection.tsx +0 -74
- package/template/apps/asas-tanstack/src/components/mithaq/list.tsx +0 -865
- package/template/apps/asas-tanstack/src/components/mithaq/nav.tsx +0 -871
- package/template/apps/asas-tanstack/src/components/mithaq/nodes.tsx +0 -1024
- package/template/apps/asas-tanstack/src/components/mithaq/relationship-cell.tsx +0 -127
- package/template/apps/asas-tanstack/src/components/mithaq/relationship-control.tsx +0 -400
- package/template/apps/asas-tanstack/src/components/mithaq/rich-text-nodes.ts +0 -6
- package/template/apps/asas-tanstack/src/components/mithaq/rich-text.tsx +0 -1083
- package/template/apps/asas-tanstack/src/components/mithaq/upload.tsx +0 -686
- package/template/apps/asas-tanstack/src/components/ui/drawer.tsx +0 -215
- package/template/templates/asas/src/audit-log/audit-log.ts +0 -187
- package/template/templates/asas/src/audit-log/ui/activity.tsx +0 -243
- package/template/templates/asas/src/courses/ui/archive-button.tsx +0 -25
- package/template/templates/asas/src/courses/ui/no-courses-on-offer.tsx +0 -11
- package/template/templates/asas/src/courses/ui/on-offer.ts +0 -6
- package/template/templates/asas/src/enrollments/enrollments.ts +0 -137
- package/template/templates/asas/src/rich-text-nodes.ts +0 -11
- package/template/templates/asas/src/roles.ts +0 -16
- package/template/templates/asas/src/ui/rich-text-nodes.tsx +0 -15
- package/template/templates/asas/src/ui-platform/organization-actions.tsx +0 -114
- package/template/templates/auth/src/index.ts +0 -690
- /package/template/apps/{asas-platform → asas-backoffice}/components.json +0 -0
- /package/template/apps/{asas-platform → asas-backoffice}/gitignore +0 -0
- /package/template/apps/{asas-platform → asas-backoffice}/public/favicon.svg +0 -0
- /package/template/apps/{asas-platform → asas-backoffice}/src/components/ui/accordion.tsx +0 -0
- /package/template/apps/{asas-platform → asas-backoffice}/src/components/ui/alert-dialog.tsx +0 -0
- /package/template/apps/{asas-platform → asas-backoffice}/src/components/ui/avatar.tsx +0 -0
- /package/template/apps/{asas-platform → asas-backoffice}/src/components/ui/badge.tsx +0 -0
- /package/template/apps/{asas-platform → asas-backoffice}/src/components/ui/breadcrumb.tsx +0 -0
- /package/template/apps/{asas-platform → asas-backoffice}/src/components/ui/button-group.tsx +0 -0
- /package/template/apps/{asas-platform → asas-backoffice}/src/components/ui/button.tsx +0 -0
- /package/template/apps/{asas-platform → asas-backoffice}/src/components/ui/calendar.tsx +0 -0
- /package/template/apps/{asas-platform → asas-backoffice}/src/components/ui/card.tsx +0 -0
- /package/template/apps/{asas-platform → asas-backoffice}/src/components/ui/chart.tsx +0 -0
- /package/template/apps/{asas-platform → asas-backoffice}/src/components/ui/checkbox.tsx +0 -0
- /package/template/apps/{asas-platform → asas-backoffice}/src/components/ui/collapsible.tsx +0 -0
- /package/template/apps/{asas-platform → asas-backoffice}/src/components/ui/combobox.tsx +0 -0
- /package/template/apps/{asas-platform → asas-backoffice}/src/components/ui/dialog.tsx +0 -0
- /package/template/apps/{asas-platform → asas-backoffice}/src/components/ui/direction.tsx +0 -0
- /package/template/apps/{asas-platform → asas-backoffice}/src/components/ui/directional-icon.tsx +0 -0
- /package/template/apps/{asas-platform → asas-backoffice}/src/components/ui/dropdown-menu.tsx +0 -0
- /package/template/apps/{asas-platform → asas-backoffice}/src/components/ui/field.tsx +0 -0
- /package/template/apps/{asas-platform → asas-backoffice}/src/components/ui/input-group.tsx +0 -0
- /package/template/apps/{asas-platform → asas-backoffice}/src/components/ui/input-otp.tsx +0 -0
- /package/template/apps/{asas-platform → asas-backoffice}/src/components/ui/input.tsx +0 -0
- /package/template/apps/{asas-platform → asas-backoffice}/src/components/ui/label.tsx +0 -0
- /package/template/apps/{asas-platform → asas-backoffice}/src/components/ui/popover.tsx +0 -0
- /package/template/apps/{asas-platform → asas-backoffice}/src/components/ui/radio-group.tsx +0 -0
- /package/template/apps/{asas-platform → asas-backoffice}/src/components/ui/resizable.tsx +0 -0
- /package/template/apps/{asas-platform → asas-backoffice}/src/components/ui/scroll-area.tsx +0 -0
- /package/template/apps/{asas-platform → asas-backoffice}/src/components/ui/select.tsx +0 -0
- /package/template/apps/{asas-platform → asas-backoffice}/src/components/ui/separator.tsx +0 -0
- /package/template/apps/{asas-platform → asas-backoffice}/src/components/ui/sheet.tsx +0 -0
- /package/template/apps/{asas-platform → asas-backoffice}/src/components/ui/sidebar.tsx +0 -0
- /package/template/apps/{asas-platform → asas-backoffice}/src/components/ui/skeleton.tsx +0 -0
- /package/template/apps/{asas-platform → asas-backoffice}/src/components/ui/slider.tsx +0 -0
- /package/template/apps/{asas-platform → asas-backoffice}/src/components/ui/spinner.tsx +0 -0
- /package/template/apps/{asas-platform → asas-backoffice}/src/components/ui/switch.tsx +0 -0
- /package/template/apps/{asas-platform → asas-backoffice}/src/components/ui/table.tsx +0 -0
- /package/template/apps/{asas-platform → asas-backoffice}/src/components/ui/tabs.tsx +0 -0
- /package/template/apps/{asas-platform → asas-backoffice}/src/components/ui/textarea.tsx +0 -0
- /package/template/apps/{asas-platform → asas-backoffice}/src/components/ui/toggle-group.tsx +0 -0
- /package/template/apps/{asas-platform → asas-backoffice}/src/components/ui/toggle.tsx +0 -0
- /package/template/apps/{asas-platform → asas-backoffice}/src/components/ui/tooltip.tsx +0 -0
- /package/template/apps/{asas-platform → asas-backoffice}/src/copy.ts +0 -0
- /package/template/apps/{asas-platform → asas-backoffice}/src/hooks/use-mobile.ts +0 -0
- /package/template/apps/{asas-platform → asas-backoffice}/src/lib/utils.ts +0 -0
- /package/template/apps/{asas-platform → asas-backoffice}/src/theme.ts +0 -0
- /package/template/templates/{asas/src/kayan → features}/auth/user/index.ts +0 -0
- /package/template/templates/{asas/src → features/courses}/courses/ui/no-courses.tsx +0 -0
- /package/template/templates/{asas → mithaq}/components.json +0 -0
- /package/template/templates/{asas → mithaq}/src/storage/defaults.ts +0 -0
- /package/template/templates/{asas → mithaq}/src/storage/local.ts +0 -0
- /package/template/templates/{asas → mithaq}/src/storage/r2.ts +0 -0
- /package/template/templates/{asas → mithaq}/src/storage/s3.ts +0 -0
- /package/template/templates/{asas → mithaq}/src/storage/uploadthing.ts +0 -0
- /package/template/templates/{asas → mithaq}/src/ui/kpi-card.tsx +0 -0
- /package/template/templates/{asas → mithaq}/src/ui/record-page.tsx +0 -0
- /package/template/templates/{asas → mithaq}/src/ui/table-page.tsx +0 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { createServerFn } from '@tanstack/react-start'
|
|
2
|
+
|
|
3
|
+
type FirstRun = { open: false } | { open: true; code: 'none' | 'required' | 'unset' }
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Whether this app of one organization still waits for its first owner, and while it does,
|
|
7
|
+
* whether first-run asks the setup code: the provider's own state, read in process. With
|
|
8
|
+
* many organizations nobody waits: each sign-up founds one.
|
|
9
|
+
*/
|
|
10
|
+
export const firstRun = createServerFn({ method: 'GET' }).handler(async (): Promise<FirstRun> => {
|
|
11
|
+
// Imported inside the server half so no page ships the provider to the browser.
|
|
12
|
+
const [{ asas }, { organizations }] = await Promise.all([import('asas'), import('asas/organizations')])
|
|
13
|
+
if (organizations === 'many') return { open: false }
|
|
14
|
+
type Provider = { name: string; server: { api: { firstRunState(): Promise<FirstRun> } } }
|
|
15
|
+
return (asas.auth.strategies as unknown as Provider[]).find((one) => one.name === 'user')!.server.api.firstRunState()
|
|
16
|
+
})
|
|
@@ -35,4 +35,4 @@ export const clampedHref = ({ href, page, totalPages }: { href: string; page: nu
|
|
|
35
35
|
else url.searchParams.delete('page')
|
|
36
36
|
return `${url.pathname}${url.search}${url.hash}`
|
|
37
37
|
}
|
|
38
|
-
// mithaq-admin
|
|
38
|
+
// mithaq-admin 2d3ab739c92c6c2b397041b76bf4b23b2902b7a2 4754cbac64eeac528e7e037173ad56ffa8d07df3e526e1191bbe3be400db97a5
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
import { useRouter } from '@tanstack/react-router'
|
|
1
2
|
import { Button } from '@/components/ui/button'
|
|
2
|
-
import { localeEntries } from '
|
|
3
|
-
import { locales,
|
|
3
|
+
import { localeEntries } from 'mithaq-admin/locale-menu.ts'
|
|
4
|
+
import { locales, showLocale, type Locale } from './copy.ts'
|
|
4
5
|
|
|
5
|
-
/** The language switch
|
|
6
|
+
/** The language switch of the auth and landing pages, which redraws the page in place, so a form keeps what was typed. */
|
|
6
7
|
export function LocaleSwitch({ locale }: { locale: Locale }) {
|
|
8
|
+
const router = useRouter()
|
|
7
9
|
return (
|
|
8
10
|
<div className="flex items-center gap-1">
|
|
9
11
|
{localeEntries(locales, locale).map((entry) => (
|
|
@@ -14,7 +16,7 @@ export function LocaleSwitch({ locale }: { locale: Locale }) {
|
|
|
14
16
|
size="xs"
|
|
15
17
|
aria-current={entry.active}
|
|
16
18
|
aria-label={entry.label}
|
|
17
|
-
onClick={() =>
|
|
19
|
+
onClick={() => void showLocale({ to: entry.locale, router })}
|
|
18
20
|
>
|
|
19
21
|
<span className="hidden sm:inline">{entry.label}</span>
|
|
20
22
|
<span className="sm:hidden">{entry.locale.toUpperCase()}</span>
|
|
@@ -23,4 +25,4 @@ export function LocaleSwitch({ locale }: { locale: Locale }) {
|
|
|
23
25
|
</div>
|
|
24
26
|
)
|
|
25
27
|
}
|
|
26
|
-
// mithaq-admin
|
|
28
|
+
// mithaq-admin 0.0.0 37e32a32766452cd88389e2e4cc6c246ccc3ccb40bf941f8c1e3835b4e377f98
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
// What `/unauthorized` draws below its sentence for a person who belongs to no organization: the invitations sent to
|
|
2
|
+
// their address, and with many organizations a way to found one. The screen host imports it from the app, which knows
|
|
3
|
+
// the organization mode the host does not.
|
|
4
|
+
import { useEffect, useState } from 'react'
|
|
5
|
+
import { defaultLocale, organizations } from 'asas/organizations'
|
|
6
|
+
import { endonym } from 'mithaq-admin/locale-menu.ts'
|
|
7
|
+
import { Button } from '@/components/ui/button'
|
|
8
|
+
import { Input } from '@/components/ui/input'
|
|
9
|
+
import { authArm } from './api.ts'
|
|
10
|
+
import { useRefusal } from './auth-frame.tsx'
|
|
11
|
+
import { locales } from './copy.ts'
|
|
12
|
+
import { useCopy } from './routes/__root.tsx'
|
|
13
|
+
|
|
14
|
+
/** An invitation as the auth setup answers it: the organization's name in each locale beside the provider's one. */
|
|
15
|
+
type Invitation = { id: string; organizationName: string; organizationNames?: Record<string, string>; expiresAt: string }
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Better Auth requires a unique slug, so a random tail keeps same-named organizations apart.
|
|
19
|
+
* Padded before the cut, so the tail is always six characters and the slug never ends in `-`.
|
|
20
|
+
*/
|
|
21
|
+
const slugOf = (name: string) =>
|
|
22
|
+
`${name.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '').slice(0, 40) || 'organization'}-${Math.random().toString(36).slice(2).padEnd(6, '0').slice(0, 6)}`
|
|
23
|
+
|
|
24
|
+
/** Signing in again lands a signed-in person on their first screen, in the organization the session now names. */
|
|
25
|
+
const goIn = () => window.location.assign('/auth/sign-in')
|
|
26
|
+
|
|
27
|
+
export function NoOrganization({ email, founds = organizations === 'many' }: { email: string | undefined; founds?: boolean }) {
|
|
28
|
+
const { t, locale } = useCopy()
|
|
29
|
+
const refusal = useRefusal()
|
|
30
|
+
const [invitations, setInvitations] = useState<Invitation[]>([])
|
|
31
|
+
const [name, setName] = useState('')
|
|
32
|
+
// The organization's name in each other locale, optional: one left empty falls back to `name`.
|
|
33
|
+
const [names, setNames] = useState<Record<string, string>>({})
|
|
34
|
+
const others = locales.filter((one) => one !== defaultLocale)
|
|
35
|
+
const [busy, setBusy] = useState(false)
|
|
36
|
+
const [failed, setFailed] = useState<string>()
|
|
37
|
+
useEffect(() => {
|
|
38
|
+
// A refusal, such as an address nobody proved, reads as no invitation.
|
|
39
|
+
void fetch('/api/auth/user/organization/list-user-invitations').then(async (answer) => {
|
|
40
|
+
if (answer.ok) setInvitations(((await answer.json()) as Invitation[]).filter((one) => new Date(one.expiresAt).getTime() > Date.now()))
|
|
41
|
+
})
|
|
42
|
+
if (founds) {
|
|
43
|
+
void fetch('/api/auth/user/get-session').then(async (answer) => {
|
|
44
|
+
const named = ((await answer.json().catch(() => null)) as { user?: { name?: string } } | null)?.user?.name
|
|
45
|
+
if (named) setName((typed) => typed || t('auth.workspaceOf', '{name}\'s workspace')!.replace('{name}', () => named))
|
|
46
|
+
})
|
|
47
|
+
}
|
|
48
|
+
}, [])
|
|
49
|
+
/** One request at a time, its refusal said in this app's words. */
|
|
50
|
+
const send = async ({ path, body, done }: { path: string; body: Record<string, unknown>; done: () => void }) => {
|
|
51
|
+
setBusy(true)
|
|
52
|
+
setFailed(undefined)
|
|
53
|
+
const answered = await authArm(path, body)
|
|
54
|
+
setBusy(false)
|
|
55
|
+
if (!answered.ok) return setFailed(refusal(answered, t('auth.requestFailed', 'That request did not work.')))
|
|
56
|
+
done()
|
|
57
|
+
}
|
|
58
|
+
return (
|
|
59
|
+
<div data-no-organization="" className="grid gap-4">
|
|
60
|
+
{invitations.length ? (
|
|
61
|
+
<section className="grid gap-2">
|
|
62
|
+
<h2 className="text-sm font-medium">{t('auth.yourInvitations', 'Your invitations')}</h2>
|
|
63
|
+
<ul className="grid gap-2">
|
|
64
|
+
{invitations.map((one) => (
|
|
65
|
+
<li key={one.id} data-invitation={one.id} className="flex flex-wrap items-center justify-between gap-2 rounded-md border px-3 py-2">
|
|
66
|
+
<bdi className="[overflow-wrap:anywhere]">{one.organizationNames?.[locale] || one.organizationName}</bdi>
|
|
67
|
+
<span className="flex gap-2">
|
|
68
|
+
<Button type="button" size="sm" data-accept={one.id} disabled={busy} onClick={() => void send({ path: 'organization/accept-invitation', body: { invitationId: one.id }, done: goIn })}>
|
|
69
|
+
{t('auth.invitationAccept', 'Accept the invitation')}
|
|
70
|
+
</Button>
|
|
71
|
+
<Button type="button" size="sm" variant="outline" data-decline={one.id} disabled={busy} onClick={() => void send({ path: 'organization/reject-invitation', body: { invitationId: one.id }, done: () => setInvitations((all) => all.filter((other) => other.id !== one.id)) })}>
|
|
72
|
+
{t('auth.invitationDecline', 'Decline')}
|
|
73
|
+
</Button>
|
|
74
|
+
</span>
|
|
75
|
+
</li>
|
|
76
|
+
))}
|
|
77
|
+
</ul>
|
|
78
|
+
</section>
|
|
79
|
+
) : null}
|
|
80
|
+
{founds ? (
|
|
81
|
+
<form
|
|
82
|
+
data-create-organization=""
|
|
83
|
+
className="grid gap-2"
|
|
84
|
+
noValidate
|
|
85
|
+
onSubmit={(event) => {
|
|
86
|
+
event.preventDefault()
|
|
87
|
+
const named = { [defaultLocale]: name.trim(), ...Object.fromEntries(others.map((one) => [one, names[one]?.trim() ?? '']).filter(([, one]) => one)) }
|
|
88
|
+
if (name.trim()) void send({ path: 'organization/create', body: { name: name.trim(), names: JSON.stringify(named), slug: slugOf(name.trim()) }, done: goIn })
|
|
89
|
+
}}
|
|
90
|
+
>
|
|
91
|
+
<label htmlFor="new-organization" className="text-sm font-medium">{t('auth.createOrganization', 'Create an organization')}</label>
|
|
92
|
+
<Input id="new-organization" value={name} maxLength={100} autoComplete="organization" dir="auto" onChange={(event) => setName(event.target.value)} />
|
|
93
|
+
{others.map((one) => (
|
|
94
|
+
<div key={one} className="grid gap-1">
|
|
95
|
+
<label htmlFor={`new-organization-${one}`} className="text-muted-foreground text-sm">{t('auth.organizationNameIn', 'Its name in {language}, if it has one')!.replace('{language}', () => endonym(one))}</label>
|
|
96
|
+
<Input id={`new-organization-${one}`} lang={one} dir="auto" value={names[one] ?? ''} maxLength={100} onChange={(event) => setNames((held) => ({ ...held, [one]: event.target.value }))} />
|
|
97
|
+
</div>
|
|
98
|
+
))}
|
|
99
|
+
<Button type="submit" disabled={busy || !name.trim()}>{t('auth.createOrganizationSubmit', 'Create')}</Button>
|
|
100
|
+
</form>
|
|
101
|
+
) : null}
|
|
102
|
+
<p className="text-muted-foreground text-sm">
|
|
103
|
+
{t('auth.askToBeInvited', 'Ask an administrator to invite {email}.')!.split(/(\{email\})/).map((part, at) => (part === '{email}' ? <bdi key={at} className="[overflow-wrap:anywhere]">{email}</bdi> : part))}
|
|
104
|
+
</p>
|
|
105
|
+
{failed ? <p role="alert" className="text-destructive text-sm">{failed}</p> : null}
|
|
106
|
+
</div>
|
|
107
|
+
)
|
|
108
|
+
}
|
|
@@ -6,15 +6,34 @@
|
|
|
6
6
|
* `//elsewhere` and `javascript:` are refused however they are spelled. A backslash, a C0 control
|
|
7
7
|
* and DEL are refused before the parse, since the parser rewrites or strips them before reading
|
|
8
8
|
* the host. They are written as escapes so git and grep keep reading this file as text.
|
|
9
|
+
*
|
|
10
|
+
* The answer is the parser's own path, its dot segments resolved, plain or percent-encoded, so what
|
|
11
|
+
* a caller reads is where the browser goes. A path that resolves to `//` is refused, since a browser
|
|
12
|
+
* reads it as another origin: `/..//elsewhere` resolves to `//elsewhere`.
|
|
9
13
|
*/
|
|
10
14
|
const base = 'https://mithaq.invalid'
|
|
11
15
|
|
|
12
16
|
export const wanted = ({ asked, home }: { asked: string | undefined; home: string }): string => {
|
|
13
17
|
if (asked === undefined || !asked.startsWith('/') || /[\\\x00-\x1f\x7f]/.test(asked)) return home
|
|
14
18
|
try {
|
|
15
|
-
|
|
19
|
+
const url = new URL(asked, base)
|
|
20
|
+
return url.origin === base && !url.pathname.startsWith('//') ? url.pathname + url.search + url.hash : home
|
|
16
21
|
} catch {
|
|
17
22
|
// `new URL('//', base)` throws rather than resolving.
|
|
18
23
|
return home
|
|
19
24
|
}
|
|
20
25
|
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Where a signed-in person goes: the path asked for where it lies inside a screen they open, else the
|
|
29
|
+
* one screen they open, else the dashboard, since whoever opens several is staff, else `/unauthorized`,
|
|
30
|
+
* which asks which of several or says why there is none. The dashboard is found by its screen's name,
|
|
31
|
+
* never its place in the list. A path in a screen they do not open is not followed, since there they
|
|
32
|
+
* would only be refused.
|
|
33
|
+
*/
|
|
34
|
+
export const landing = ({ asked, screens }: { asked: string | undefined; screens: readonly { name: string; path: string }[] }): string => {
|
|
35
|
+
const home = (screens.length === 1 ? screens[0] : screens.find((one) => one.name === 'dashboard'))?.path ?? '/unauthorized'
|
|
36
|
+
const path = wanted({ asked, home })
|
|
37
|
+
const { pathname } = new URL(path, base)
|
|
38
|
+
return screens.some(({ path: screen }) => pathname === screen || pathname.startsWith(`${screen}/`)) ? path : home
|
|
39
|
+
}
|
|
@@ -8,4 +8,4 @@ export const mergedHeaders = (session: Headers, own?: HeadersInit): Headers => {
|
|
|
8
8
|
if (own) for (const [key, value] of new Headers(own)) if (key !== 'cookie') headers.set(key, value)
|
|
9
9
|
return headers
|
|
10
10
|
}
|
|
11
|
-
// mithaq-admin
|
|
11
|
+
// mithaq-admin 2d3ab739c92c6c2b397041b76bf4b23b2902b7a2 2969a3dafbf201d6eb6074ecda0e8f17e341cbd1ca176100350844e74ec23623
|
|
@@ -15,9 +15,11 @@ import { Route as screensDashboardRouteImport } from './routes/(screens)/dashboa
|
|
|
15
15
|
import { Route as screensPortalRouteImport } from './routes/(screens)/portal'
|
|
16
16
|
import { Route as ApiSplatRouteImport } from './routes/api/$'
|
|
17
17
|
import { Route as AuthAcceptInvitationRouteImport } from './routes/auth.accept-invitation'
|
|
18
|
+
import { Route as AuthFirstRunRouteImport } from './routes/auth.first-run'
|
|
18
19
|
import { Route as AuthForgotPasswordRouteImport } from './routes/auth.forgot-password'
|
|
19
20
|
import { Route as AuthHandoffRouteImport } from './routes/auth.handoff'
|
|
20
21
|
import { Route as AuthResetPasswordRouteImport } from './routes/auth.reset-password'
|
|
22
|
+
import { Route as AuthSetPasswordRouteImport } from './routes/auth.set-password'
|
|
21
23
|
import { Route as AuthSignInRouteImport } from './routes/auth.sign-in'
|
|
22
24
|
import { Route as AuthSignUpRouteImport } from './routes/auth.sign-up'
|
|
23
25
|
import { Route as screensDashboardIndexRouteImport } from './routes/(screens)/dashboard.index'
|
|
@@ -55,6 +57,11 @@ const AuthAcceptInvitationRoute = AuthAcceptInvitationRouteImport.update({
|
|
|
55
57
|
path: '/auth/accept-invitation',
|
|
56
58
|
getParentRoute: () => rootRouteImport,
|
|
57
59
|
} as any)
|
|
60
|
+
const AuthFirstRunRoute = AuthFirstRunRouteImport.update({
|
|
61
|
+
id: '/auth/first-run',
|
|
62
|
+
path: '/auth/first-run',
|
|
63
|
+
getParentRoute: () => rootRouteImport,
|
|
64
|
+
} as any)
|
|
58
65
|
const AuthForgotPasswordRoute = AuthForgotPasswordRouteImport.update({
|
|
59
66
|
id: '/auth/forgot-password',
|
|
60
67
|
path: '/auth/forgot-password',
|
|
@@ -70,6 +77,11 @@ const AuthResetPasswordRoute = AuthResetPasswordRouteImport.update({
|
|
|
70
77
|
path: '/auth/reset-password',
|
|
71
78
|
getParentRoute: () => rootRouteImport,
|
|
72
79
|
} as any)
|
|
80
|
+
const AuthSetPasswordRoute = AuthSetPasswordRouteImport.update({
|
|
81
|
+
id: '/auth/set-password',
|
|
82
|
+
path: '/auth/set-password',
|
|
83
|
+
getParentRoute: () => rootRouteImport,
|
|
84
|
+
} as any)
|
|
73
85
|
const AuthSignInRoute = AuthSignInRouteImport.update({
|
|
74
86
|
id: '/auth/sign-in',
|
|
75
87
|
path: '/auth/sign-in',
|
|
@@ -108,9 +120,11 @@ export interface FileRoutesByFullPath {
|
|
|
108
120
|
'/portal': typeof screensPortalRouteWithChildren
|
|
109
121
|
'/api/$': typeof ApiSplatRoute
|
|
110
122
|
'/auth/accept-invitation': typeof AuthAcceptInvitationRoute
|
|
123
|
+
'/auth/first-run': typeof AuthFirstRunRoute
|
|
111
124
|
'/auth/forgot-password': typeof AuthForgotPasswordRoute
|
|
112
125
|
'/auth/handoff': typeof AuthHandoffRoute
|
|
113
126
|
'/auth/reset-password': typeof AuthResetPasswordRoute
|
|
127
|
+
'/auth/set-password': typeof AuthSetPasswordRoute
|
|
114
128
|
'/auth/sign-in': typeof AuthSignInRoute
|
|
115
129
|
'/auth/sign-up': typeof AuthSignUpRoute
|
|
116
130
|
'/dashboard/$': typeof screensDashboardSplatRoute
|
|
@@ -123,9 +137,11 @@ export interface FileRoutesByTo {
|
|
|
123
137
|
'/unauthorized': typeof UnauthorizedRoute
|
|
124
138
|
'/api/$': typeof ApiSplatRoute
|
|
125
139
|
'/auth/accept-invitation': typeof AuthAcceptInvitationRoute
|
|
140
|
+
'/auth/first-run': typeof AuthFirstRunRoute
|
|
126
141
|
'/auth/forgot-password': typeof AuthForgotPasswordRoute
|
|
127
142
|
'/auth/handoff': typeof AuthHandoffRoute
|
|
128
143
|
'/auth/reset-password': typeof AuthResetPasswordRoute
|
|
144
|
+
'/auth/set-password': typeof AuthSetPasswordRoute
|
|
129
145
|
'/auth/sign-in': typeof AuthSignInRoute
|
|
130
146
|
'/auth/sign-up': typeof AuthSignUpRoute
|
|
131
147
|
'/dashboard/$': typeof screensDashboardSplatRoute
|
|
@@ -141,9 +157,11 @@ export interface FileRoutesById {
|
|
|
141
157
|
'/(screens)/portal': typeof screensPortalRouteWithChildren
|
|
142
158
|
'/api/$': typeof ApiSplatRoute
|
|
143
159
|
'/auth/accept-invitation': typeof AuthAcceptInvitationRoute
|
|
160
|
+
'/auth/first-run': typeof AuthFirstRunRoute
|
|
144
161
|
'/auth/forgot-password': typeof AuthForgotPasswordRoute
|
|
145
162
|
'/auth/handoff': typeof AuthHandoffRoute
|
|
146
163
|
'/auth/reset-password': typeof AuthResetPasswordRoute
|
|
164
|
+
'/auth/set-password': typeof AuthSetPasswordRoute
|
|
147
165
|
'/auth/sign-in': typeof AuthSignInRoute
|
|
148
166
|
'/auth/sign-up': typeof AuthSignUpRoute
|
|
149
167
|
'/(screens)/dashboard/$': typeof screensDashboardSplatRoute
|
|
@@ -160,9 +178,11 @@ export interface FileRouteTypes {
|
|
|
160
178
|
| '/portal'
|
|
161
179
|
| '/api/$'
|
|
162
180
|
| '/auth/accept-invitation'
|
|
181
|
+
| '/auth/first-run'
|
|
163
182
|
| '/auth/forgot-password'
|
|
164
183
|
| '/auth/handoff'
|
|
165
184
|
| '/auth/reset-password'
|
|
185
|
+
| '/auth/set-password'
|
|
166
186
|
| '/auth/sign-in'
|
|
167
187
|
| '/auth/sign-up'
|
|
168
188
|
| '/dashboard/$'
|
|
@@ -175,9 +195,11 @@ export interface FileRouteTypes {
|
|
|
175
195
|
| '/unauthorized'
|
|
176
196
|
| '/api/$'
|
|
177
197
|
| '/auth/accept-invitation'
|
|
198
|
+
| '/auth/first-run'
|
|
178
199
|
| '/auth/forgot-password'
|
|
179
200
|
| '/auth/handoff'
|
|
180
201
|
| '/auth/reset-password'
|
|
202
|
+
| '/auth/set-password'
|
|
181
203
|
| '/auth/sign-in'
|
|
182
204
|
| '/auth/sign-up'
|
|
183
205
|
| '/dashboard/$'
|
|
@@ -192,9 +214,11 @@ export interface FileRouteTypes {
|
|
|
192
214
|
| '/(screens)/portal'
|
|
193
215
|
| '/api/$'
|
|
194
216
|
| '/auth/accept-invitation'
|
|
217
|
+
| '/auth/first-run'
|
|
195
218
|
| '/auth/forgot-password'
|
|
196
219
|
| '/auth/handoff'
|
|
197
220
|
| '/auth/reset-password'
|
|
221
|
+
| '/auth/set-password'
|
|
198
222
|
| '/auth/sign-in'
|
|
199
223
|
| '/auth/sign-up'
|
|
200
224
|
| '/(screens)/dashboard/$'
|
|
@@ -210,9 +234,11 @@ export interface RootRouteChildren {
|
|
|
210
234
|
screensPortalRoute: typeof screensPortalRouteWithChildren
|
|
211
235
|
ApiSplatRoute: typeof ApiSplatRoute
|
|
212
236
|
AuthAcceptInvitationRoute: typeof AuthAcceptInvitationRoute
|
|
237
|
+
AuthFirstRunRoute: typeof AuthFirstRunRoute
|
|
213
238
|
AuthForgotPasswordRoute: typeof AuthForgotPasswordRoute
|
|
214
239
|
AuthHandoffRoute: typeof AuthHandoffRoute
|
|
215
240
|
AuthResetPasswordRoute: typeof AuthResetPasswordRoute
|
|
241
|
+
AuthSetPasswordRoute: typeof AuthSetPasswordRoute
|
|
216
242
|
AuthSignInRoute: typeof AuthSignInRoute
|
|
217
243
|
AuthSignUpRoute: typeof AuthSignUpRoute
|
|
218
244
|
}
|
|
@@ -261,6 +287,13 @@ declare module '@tanstack/react-router' {
|
|
|
261
287
|
preLoaderRoute: typeof AuthAcceptInvitationRouteImport
|
|
262
288
|
parentRoute: typeof rootRouteImport
|
|
263
289
|
}
|
|
290
|
+
'/auth/first-run': {
|
|
291
|
+
id: '/auth/first-run'
|
|
292
|
+
path: '/auth/first-run'
|
|
293
|
+
fullPath: '/auth/first-run'
|
|
294
|
+
preLoaderRoute: typeof AuthFirstRunRouteImport
|
|
295
|
+
parentRoute: typeof rootRouteImport
|
|
296
|
+
}
|
|
264
297
|
'/auth/forgot-password': {
|
|
265
298
|
id: '/auth/forgot-password'
|
|
266
299
|
path: '/auth/forgot-password'
|
|
@@ -282,6 +315,13 @@ declare module '@tanstack/react-router' {
|
|
|
282
315
|
preLoaderRoute: typeof AuthResetPasswordRouteImport
|
|
283
316
|
parentRoute: typeof rootRouteImport
|
|
284
317
|
}
|
|
318
|
+
'/auth/set-password': {
|
|
319
|
+
id: '/auth/set-password'
|
|
320
|
+
path: '/auth/set-password'
|
|
321
|
+
fullPath: '/auth/set-password'
|
|
322
|
+
preLoaderRoute: typeof AuthSetPasswordRouteImport
|
|
323
|
+
parentRoute: typeof rootRouteImport
|
|
324
|
+
}
|
|
285
325
|
'/auth/sign-in': {
|
|
286
326
|
id: '/auth/sign-in'
|
|
287
327
|
path: '/auth/sign-in'
|
|
@@ -361,9 +401,11 @@ const rootRouteChildren: RootRouteChildren = {
|
|
|
361
401
|
screensPortalRoute: screensPortalRouteWithChildren,
|
|
362
402
|
ApiSplatRoute: ApiSplatRoute,
|
|
363
403
|
AuthAcceptInvitationRoute: AuthAcceptInvitationRoute,
|
|
404
|
+
AuthFirstRunRoute: AuthFirstRunRoute,
|
|
364
405
|
AuthForgotPasswordRoute: AuthForgotPasswordRoute,
|
|
365
406
|
AuthHandoffRoute: AuthHandoffRoute,
|
|
366
407
|
AuthResetPasswordRoute: AuthResetPasswordRoute,
|
|
408
|
+
AuthSetPasswordRoute: AuthSetPasswordRoute,
|
|
367
409
|
AuthSignInRoute: AuthSignInRoute,
|
|
368
410
|
AuthSignUpRoute: AuthSignUpRoute,
|
|
369
411
|
}
|
|
@@ -1,7 +1,18 @@
|
|
|
1
1
|
import { createRouter } from '@tanstack/react-router'
|
|
2
2
|
import { routeTree } from './routeTree.gen'
|
|
3
3
|
import { flatSearch } from './screen-list.tsx'
|
|
4
|
+
import { ComponentsProvider, RouteError } from 'mithaq-admin/components.tsx'
|
|
5
|
+
import { components } from './components.ts'
|
|
4
6
|
|
|
5
7
|
// The search is read and written as the URL's own pairs, one string each, because a list
|
|
6
8
|
// keeps its `qs` query there.
|
|
7
|
-
export const getRouter = () =>
|
|
9
|
+
export const getRouter = () =>
|
|
10
|
+
createRouter({
|
|
11
|
+
routeTree,
|
|
12
|
+
scrollRestoration: true,
|
|
13
|
+
...flatSearch,
|
|
14
|
+
// Around every route, so each screen draws its controls from this map.
|
|
15
|
+
Wrap: ({ children }) => <ComponentsProvider components={components}>{children}</ComponentsProvider>,
|
|
16
|
+
// Drawn in place of the route that threw, so the shell around it stays.
|
|
17
|
+
defaultErrorComponent: RouteError,
|
|
18
|
+
})
|
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
// Written by `mithaq generate screens`. Do not edit.
|
|
2
2
|
/// <reference types="vite/client" />
|
|
3
|
-
// Every file the `dashboard` screen's references name, each loaded when a page draws it.
|
|
4
|
-
|
|
3
|
+
// Every file the `dashboard` screen's references name, each loaded when a page draws it, keyed as the reference prints it.
|
|
4
|
+
const named = (name: string, files: Record<string, () => Promise<unknown>>) => Object.fromEntries(Object.entries(files).map(([file, load]) => [`${name}:${file}`, load]))
|
|
5
|
+
export const files = {
|
|
6
|
+
...import.meta.glob(['./src/ui-dashboard/dashboard.tsx', './src/ui-dashboard/members.tsx', './src/ui-dashboard/theme-provider.tsx', './src/ui-dashboard/versions.tsx'], { base: '../../../../../../templates/asas/', exhaustive: true }),
|
|
7
|
+
...named('@asas/courses', import.meta.glob(['./courses/ui/archived-badge.tsx', './courses/ui/fee-cell.tsx', './courses/ui/no-courses.tsx', './courses/ui/status-cell.tsx', './courses/ui/unpublish-button.tsx', './enrollments/ui/session-cell.tsx', './enrollments/ui/session-labels.tsx'], { base: '../../../../../../templates/features/courses/', exhaustive: true })),
|
|
8
|
+
...named('@asas/media', import.meta.glob(['./media/ui/preview.tsx'], { base: '../../../../../../templates/features/media/', exhaustive: true })),
|
|
9
|
+
...named('@asas/mithaq', import.meta.glob(['./src/ui/activity-page.tsx', './src/ui/activity.tsx', './src/ui/app-shell.tsx', './src/ui/record-page.tsx', './src/ui/rich-text-nodes.tsx', './src/ui/table-page.tsx', './src/ui/top-shell.tsx'], { base: '../../../../../../templates/mithaq/', exhaustive: true })),
|
|
10
|
+
...named('@asas/roles', import.meta.glob(['./roles/ui/role-form.tsx', './roles/ui/roles.tsx'], { base: '../../../../../../templates/features/roles/', exhaustive: true })),
|
|
11
|
+
}
|