create-mithaq 0.0.0-stage → 0.1.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/LICENSE +22 -0
- package/LICENSES/payload.txt +22 -0
- package/LICENSES/ponytail.txt +21 -0
- package/index.js +127 -0
- package/package.json +19 -4
- package/template/apps/asas-platform/components.json +25 -0
- package/template/apps/asas-platform/gitignore +3 -0
- package/template/apps/asas-platform/package.json +55 -0
- package/template/apps/asas-platform/public/favicon.svg +1 -0
- package/template/apps/asas-platform/src/api.ts +147 -0
- package/template/apps/asas-platform/src/auth-frame.tsx +150 -0
- package/template/apps/asas-platform/src/components/mithaq/cells.tsx +112 -0
- package/template/apps/asas-platform/src/components/mithaq/controls.tsx +650 -0
- package/template/apps/asas-platform/src/components/mithaq/field-shell.tsx +53 -0
- package/template/apps/asas-platform/src/components/mithaq/filter-operators.ts +108 -0
- package/template/apps/asas-platform/src/components/mithaq/form.tsx +1467 -0
- package/template/apps/asas-platform/src/components/mithaq/list-columns.tsx +108 -0
- package/template/apps/asas-platform/src/components/mithaq/list-filters.tsx +368 -0
- package/template/apps/asas-platform/src/components/mithaq/list-pagination.tsx +153 -0
- package/template/apps/asas-platform/src/components/mithaq/list-query.ts +432 -0
- package/template/apps/asas-platform/src/components/mithaq/list-selection.tsx +74 -0
- package/template/apps/asas-platform/src/components/mithaq/list.tsx +865 -0
- package/template/apps/asas-platform/src/components/mithaq/nav.tsx +871 -0
- package/template/apps/asas-platform/src/components/mithaq/nodes.tsx +1024 -0
- package/template/apps/asas-platform/src/components/mithaq/relationship-cell.tsx +127 -0
- package/template/apps/asas-platform/src/components/mithaq/relationship-control.tsx +400 -0
- package/template/apps/asas-platform/src/components/mithaq/rich-text-nodes.ts +6 -0
- package/template/apps/asas-platform/src/components/mithaq/rich-text.tsx +1083 -0
- package/template/apps/asas-platform/src/components/mithaq/upload.tsx +686 -0
- package/template/apps/asas-platform/src/components/ui/accordion.tsx +74 -0
- package/template/apps/asas-platform/src/components/ui/alert-dialog.tsx +185 -0
- package/template/apps/asas-platform/src/components/ui/avatar.tsx +106 -0
- package/template/apps/asas-platform/src/components/ui/badge.tsx +48 -0
- package/template/apps/asas-platform/src/components/ui/breadcrumb.tsx +124 -0
- package/template/apps/asas-platform/src/components/ui/button-group.tsx +87 -0
- package/template/apps/asas-platform/src/components/ui/button.tsx +55 -0
- package/template/apps/asas-platform/src/components/ui/calendar.tsx +223 -0
- package/template/apps/asas-platform/src/components/ui/card.tsx +102 -0
- package/template/apps/asas-platform/src/components/ui/chart.tsx +371 -0
- package/template/apps/asas-platform/src/components/ui/checkbox.tsx +28 -0
- package/template/apps/asas-platform/src/components/ui/collapsible.tsx +19 -0
- package/template/apps/asas-platform/src/components/ui/combobox.tsx +308 -0
- package/template/apps/asas-platform/src/components/ui/dialog.tsx +158 -0
- package/template/apps/asas-platform/src/components/ui/direction.tsx +6 -0
- package/template/apps/asas-platform/src/components/ui/directional-icon.tsx +20 -0
- package/template/apps/asas-platform/src/components/ui/drawer.tsx +216 -0
- package/template/apps/asas-platform/src/components/ui/dropdown-menu.tsx +267 -0
- package/template/apps/asas-platform/src/components/ui/field.tsx +236 -0
- package/template/apps/asas-platform/src/components/ui/input-group.tsx +155 -0
- package/template/apps/asas-platform/src/components/ui/input-otp.tsx +84 -0
- package/template/apps/asas-platform/src/components/ui/input.tsx +19 -0
- package/template/apps/asas-platform/src/components/ui/label.tsx +19 -0
- package/template/apps/asas-platform/src/components/ui/popover.tsx +90 -0
- package/template/apps/asas-platform/src/components/ui/radio-group.tsx +37 -0
- package/template/apps/asas-platform/src/components/ui/resizable.tsx +47 -0
- package/template/apps/asas-platform/src/components/ui/scroll-area.tsx +54 -0
- package/template/apps/asas-platform/src/components/ui/select.tsx +204 -0
- package/template/apps/asas-platform/src/components/ui/separator.tsx +24 -0
- package/template/apps/asas-platform/src/components/ui/sheet.tsx +139 -0
- package/template/apps/asas-platform/src/components/ui/sidebar.tsx +714 -0
- package/template/apps/asas-platform/src/components/ui/skeleton.tsx +13 -0
- package/template/apps/asas-platform/src/components/ui/slider.tsx +55 -0
- package/template/apps/asas-platform/src/components/ui/spinner.tsx +10 -0
- package/template/apps/asas-platform/src/components/ui/switch.tsx +29 -0
- package/template/apps/asas-platform/src/components/ui/table.tsx +115 -0
- package/template/apps/asas-platform/src/components/ui/tabs.tsx +79 -0
- package/template/apps/asas-platform/src/components/ui/textarea.tsx +17 -0
- package/template/apps/asas-platform/src/components/ui/toggle-group.tsx +89 -0
- package/template/apps/asas-platform/src/components/ui/toggle.tsx +44 -0
- package/template/apps/asas-platform/src/components/ui/tooltip.tsx +63 -0
- package/template/apps/asas-platform/src/copy.ts +1 -0
- package/template/apps/asas-platform/src/hooks/use-mobile.ts +19 -0
- package/template/apps/asas-platform/src/lib/utils.ts +1 -0
- package/template/apps/asas-platform/src/links.ts +38 -0
- package/template/apps/asas-platform/src/locale-switch.tsx +26 -0
- package/template/apps/asas-platform/src/redirect.ts +1 -0
- package/template/apps/asas-platform/src/request-headers.ts +11 -0
- package/template/apps/asas-platform/src/routeTree.gen.ts +181 -0
- package/template/apps/asas-platform/src/router.tsx +7 -0
- package/template/apps/asas-platform/src/routes/(screens)/platform/files.ts +4 -0
- package/template/apps/asas-platform/src/routes/(screens)/platform/screen.json +3609 -0
- package/template/apps/asas-platform/src/routes/(screens)/platform/types.ts +145 -0
- package/template/apps/asas-platform/src/routes/(screens)/platform.$.tsx +17 -0
- package/template/apps/asas-platform/src/routes/(screens)/platform.index.tsx +10 -0
- package/template/apps/asas-platform/src/routes/(screens)/platform.tsx +13 -0
- package/template/apps/asas-platform/src/routes/__root.tsx +95 -0
- package/template/apps/asas-platform/src/routes/api/$.ts +30 -0
- package/template/apps/asas-platform/src/routes/auth.sign-in.tsx +72 -0
- package/template/apps/asas-platform/src/routes/unauthorized.tsx +122 -0
- package/template/apps/asas-platform/src/screen-form.tsx +34 -0
- package/template/apps/asas-platform/src/screen-list.tsx +139 -0
- package/template/apps/asas-platform/src/screen-names.ts +10 -0
- package/template/apps/asas-platform/src/screens.tsx +868 -0
- package/template/apps/asas-platform/src/server.ts +20 -0
- package/template/apps/asas-platform/src/slide.ts +22 -0
- package/template/apps/asas-platform/src/start.ts +42 -0
- package/template/apps/asas-platform/src/styles.css +200 -0
- package/template/apps/asas-platform/src/theme.ts +2 -0
- package/template/apps/asas-platform/tsconfig.json +19 -0
- package/template/apps/asas-platform/vite.config.ts +26 -0
- package/template/apps/asas-tanstack/components.json +25 -0
- package/template/apps/asas-tanstack/gitignore +3 -0
- package/template/apps/asas-tanstack/package.json +56 -0
- package/template/apps/asas-tanstack/public/favicon.svg +1 -0
- package/template/apps/asas-tanstack/src/api.ts +147 -0
- package/template/apps/asas-tanstack/src/auth-frame.tsx +150 -0
- package/template/apps/asas-tanstack/src/components/mithaq/cells.tsx +112 -0
- package/template/apps/asas-tanstack/src/components/mithaq/controls.tsx +650 -0
- package/template/apps/asas-tanstack/src/components/mithaq/field-shell.tsx +53 -0
- package/template/apps/asas-tanstack/src/components/mithaq/filter-operators.ts +108 -0
- package/template/apps/asas-tanstack/src/components/mithaq/form.tsx +1467 -0
- package/template/apps/asas-tanstack/src/components/mithaq/list-columns.tsx +108 -0
- package/template/apps/asas-tanstack/src/components/mithaq/list-filters.tsx +368 -0
- package/template/apps/asas-tanstack/src/components/mithaq/list-pagination.tsx +153 -0
- package/template/apps/asas-tanstack/src/components/mithaq/list-query.ts +432 -0
- package/template/apps/asas-tanstack/src/components/mithaq/list-selection.tsx +74 -0
- package/template/apps/asas-tanstack/src/components/mithaq/list.tsx +865 -0
- package/template/apps/asas-tanstack/src/components/mithaq/nav.tsx +871 -0
- package/template/apps/asas-tanstack/src/components/mithaq/nodes.tsx +1024 -0
- package/template/apps/asas-tanstack/src/components/mithaq/relationship-cell.tsx +127 -0
- package/template/apps/asas-tanstack/src/components/mithaq/relationship-control.tsx +400 -0
- package/template/apps/asas-tanstack/src/components/mithaq/rich-text-nodes.ts +6 -0
- package/template/apps/asas-tanstack/src/components/mithaq/rich-text.tsx +1083 -0
- package/template/apps/asas-tanstack/src/components/mithaq/upload.tsx +686 -0
- package/template/apps/asas-tanstack/src/components/ui/accordion.tsx +10 -0
- package/template/apps/asas-tanstack/src/components/ui/alert-dialog.tsx +173 -0
- package/template/apps/asas-tanstack/src/components/ui/avatar.tsx +104 -0
- package/template/apps/asas-tanstack/src/components/ui/badge.tsx +48 -0
- package/template/apps/asas-tanstack/src/components/ui/breadcrumb.tsx +125 -0
- package/template/apps/asas-tanstack/src/components/ui/button-group.tsx +87 -0
- package/template/apps/asas-tanstack/src/components/ui/button.tsx +56 -0
- package/template/apps/asas-tanstack/src/components/ui/calendar.tsx +223 -0
- package/template/apps/asas-tanstack/src/components/ui/card.tsx +94 -0
- package/template/apps/asas-tanstack/src/components/ui/chart.tsx +369 -0
- package/template/apps/asas-tanstack/src/components/ui/checkbox.tsx +27 -0
- package/template/apps/asas-tanstack/src/components/ui/collapsible.tsx +19 -0
- package/template/apps/asas-tanstack/src/components/ui/combobox.tsx +300 -0
- package/template/apps/asas-tanstack/src/components/ui/dialog.tsx +149 -0
- package/template/apps/asas-tanstack/src/components/ui/direction.tsx +5 -0
- package/template/apps/asas-tanstack/src/components/ui/directional-icon.tsx +20 -0
- package/template/apps/asas-tanstack/src/components/ui/drawer.tsx +215 -0
- package/template/apps/asas-tanstack/src/components/ui/dropdown-menu.tsx +267 -0
- package/template/apps/asas-tanstack/src/components/ui/field.tsx +225 -0
- package/template/apps/asas-tanstack/src/components/ui/input-group.tsx +147 -0
- package/template/apps/asas-tanstack/src/components/ui/input-otp.tsx +20 -0
- package/template/apps/asas-tanstack/src/components/ui/input.tsx +20 -0
- package/template/apps/asas-tanstack/src/components/ui/label.tsx +18 -0
- package/template/apps/asas-tanstack/src/components/ui/popover.tsx +50 -0
- package/template/apps/asas-tanstack/src/components/ui/radio-group.tsx +10 -0
- package/template/apps/asas-tanstack/src/components/ui/resizable.tsx +47 -0
- package/template/apps/asas-tanstack/src/components/ui/scroll-area.tsx +52 -0
- package/template/apps/asas-tanstack/src/components/ui/select.tsx +190 -0
- package/template/apps/asas-tanstack/src/components/ui/separator.tsx +23 -0
- package/template/apps/asas-tanstack/src/components/ui/sheet.tsx +127 -0
- package/template/apps/asas-tanstack/src/components/ui/sidebar.tsx +716 -0
- package/template/apps/asas-tanstack/src/components/ui/skeleton.tsx +13 -0
- package/template/apps/asas-tanstack/src/components/ui/slider.tsx +13 -0
- package/template/apps/asas-tanstack/src/components/ui/spinner.tsx +11 -0
- package/template/apps/asas-tanstack/src/components/ui/switch.tsx +8 -0
- package/template/apps/asas-tanstack/src/components/ui/table.tsx +119 -0
- package/template/apps/asas-tanstack/src/components/ui/tabs.tsx +80 -0
- package/template/apps/asas-tanstack/src/components/ui/textarea.tsx +18 -0
- package/template/apps/asas-tanstack/src/components/ui/toggle-group.tsx +8 -0
- package/template/apps/asas-tanstack/src/components/ui/toggle.tsx +44 -0
- package/template/apps/asas-tanstack/src/components/ui/tooltip.tsx +68 -0
- package/template/apps/asas-tanstack/src/copy.ts +870 -0
- package/template/apps/asas-tanstack/src/hooks/use-mobile.ts +19 -0
- package/template/apps/asas-tanstack/src/lib/utils.ts +6 -0
- package/template/apps/asas-tanstack/src/links.ts +38 -0
- package/template/apps/asas-tanstack/src/locale-switch.tsx +26 -0
- package/template/apps/asas-tanstack/src/quiet-abort.ts +25 -0
- package/template/apps/asas-tanstack/src/redirect.ts +20 -0
- package/template/apps/asas-tanstack/src/request-headers.ts +11 -0
- package/template/apps/asas-tanstack/src/routeTree.gen.ts +382 -0
- package/template/apps/asas-tanstack/src/router.tsx +7 -0
- package/template/apps/asas-tanstack/src/routes/(screens)/dashboard/files.ts +4 -0
- package/template/apps/asas-tanstack/src/routes/(screens)/dashboard/screen.json +3883 -0
- package/template/apps/asas-tanstack/src/routes/(screens)/dashboard/types.ts +158 -0
- package/template/apps/asas-tanstack/src/routes/(screens)/dashboard.$.tsx +17 -0
- package/template/apps/asas-tanstack/src/routes/(screens)/dashboard.index.tsx +10 -0
- package/template/apps/asas-tanstack/src/routes/(screens)/dashboard.tsx +13 -0
- package/template/apps/asas-tanstack/src/routes/(screens)/portal/files.ts +4 -0
- package/template/apps/asas-tanstack/src/routes/(screens)/portal/screen.json +1800 -0
- package/template/apps/asas-tanstack/src/routes/(screens)/portal/types.ts +92 -0
- package/template/apps/asas-tanstack/src/routes/(screens)/portal.$.tsx +17 -0
- package/template/apps/asas-tanstack/src/routes/(screens)/portal.index.tsx +10 -0
- package/template/apps/asas-tanstack/src/routes/(screens)/portal.tsx +13 -0
- package/template/apps/asas-tanstack/src/routes/__root.tsx +99 -0
- package/template/apps/asas-tanstack/src/routes/api/$.ts +11 -0
- package/template/apps/asas-tanstack/src/routes/auth.accept-invitation.tsx +101 -0
- package/template/apps/asas-tanstack/src/routes/auth.forgot-password.tsx +94 -0
- package/template/apps/asas-tanstack/src/routes/auth.handoff.ts +39 -0
- package/template/apps/asas-tanstack/src/routes/auth.reset-password.tsx +109 -0
- package/template/apps/asas-tanstack/src/routes/auth.sign-in.tsx +86 -0
- package/template/apps/asas-tanstack/src/routes/auth.sign-up.tsx +122 -0
- package/template/apps/asas-tanstack/src/routes/index.tsx +142 -0
- package/template/apps/asas-tanstack/src/routes/unauthorized.tsx +122 -0
- package/template/apps/asas-tanstack/src/screen-form.tsx +34 -0
- package/template/apps/asas-tanstack/src/screen-list.tsx +139 -0
- package/template/apps/asas-tanstack/src/screen-names.ts +10 -0
- package/template/apps/asas-tanstack/src/screens.tsx +868 -0
- package/template/apps/asas-tanstack/src/server.ts +16 -0
- package/template/apps/asas-tanstack/src/slide.ts +22 -0
- package/template/apps/asas-tanstack/src/start.ts +57 -0
- package/template/apps/asas-tanstack/src/styles.css +159 -0
- package/template/apps/asas-tanstack/src/theme.ts +5 -0
- package/template/apps/asas-tanstack/tsconfig.json +19 -0
- package/template/apps/asas-tanstack/vite.config.ts +28 -0
- package/template/package.json +16 -0
- package/template/templates/asas/.env.example +16 -0
- package/template/templates/asas/components.json +22 -0
- package/template/templates/asas/mithaq.hints.json +25 -0
- package/template/templates/asas/package.json +38 -0
- package/template/templates/asas/src/asas.ts +93 -0
- package/template/templates/asas/src/audit-log/audit-log.ts +187 -0
- package/template/templates/asas/src/audit-log/sink.ts +89 -0
- package/template/templates/asas/src/audit-log/ui/activity.tsx +243 -0
- package/template/templates/asas/src/courses/courses.ts +612 -0
- package/template/templates/asas/src/courses/ui/archive-button.tsx +25 -0
- package/template/templates/asas/src/courses/ui/fee-cell.tsx +19 -0
- package/template/templates/asas/src/courses/ui/no-courses-on-offer.tsx +11 -0
- package/template/templates/asas/src/courses/ui/no-courses.tsx +13 -0
- package/template/templates/asas/src/courses/ui/on-offer.ts +6 -0
- package/template/templates/asas/src/courses/ui/status-cell.tsx +31 -0
- package/template/templates/asas/src/enrollments/enrollments.ts +137 -0
- package/template/templates/asas/src/enrollments/ui/session-cell.tsx +65 -0
- package/template/templates/asas/src/kayan/auth/user/account.access.ts +8 -0
- package/template/templates/asas/src/kayan/auth/user/account.ts +31 -0
- package/template/templates/asas/src/kayan/auth/user/index.ts +18 -0
- package/template/templates/asas/src/kayan/auth/user/invitation.access.ts +4 -0
- package/template/templates/asas/src/kayan/auth/user/invitation.ts +27 -0
- package/template/templates/asas/src/kayan/auth/user/member.access.ts +10 -0
- package/template/templates/asas/src/kayan/auth/user/member.screens.ts +37 -0
- package/template/templates/asas/src/kayan/auth/user/member.ts +25 -0
- package/template/templates/asas/src/kayan/auth/user/organization.access.ts +20 -0
- package/template/templates/asas/src/kayan/auth/user/organization.screens.ts +37 -0
- package/template/templates/asas/src/kayan/auth/user/organization.ts +24 -0
- package/template/templates/asas/src/kayan/auth/user/organizationRole.access.ts +8 -0
- package/template/templates/asas/src/kayan/auth/user/organizationRole.ts +25 -0
- package/template/templates/asas/src/kayan/auth/user/session.access.ts +8 -0
- package/template/templates/asas/src/kayan/auth/user/session.ts +28 -0
- package/template/templates/asas/src/kayan/auth/user/user.access.ts +29 -0
- package/template/templates/asas/src/kayan/auth/user/user.screens.ts +45 -0
- package/template/templates/asas/src/kayan/auth/user/user.ts +31 -0
- package/template/templates/asas/src/kayan/auth/user/verification.access.ts +8 -0
- package/template/templates/asas/src/kayan/auth/user/verification.ts +23 -0
- package/template/templates/asas/src/local-users/local-users.ts +143 -0
- package/template/templates/asas/src/media/media.ts +137 -0
- package/template/templates/asas/src/media/ui/preview.tsx +143 -0
- package/template/templates/asas/src/member-roles/member-roles.ts +207 -0
- package/template/templates/asas/src/messages/account.json +106 -0
- package/template/templates/asas/src/messages/auditLog.json +186 -0
- package/template/templates/asas/src/messages/courses.json +270 -0
- package/template/templates/asas/src/messages/enrollments.json +42 -0
- package/template/templates/asas/src/messages/invitation.json +66 -0
- package/template/templates/asas/src/messages/localUsers.json +42 -0
- package/template/templates/asas/src/messages/media.json +66 -0
- package/template/templates/asas/src/messages/member.json +42 -0
- package/template/templates/asas/src/messages/memberRoles.json +42 -0
- package/template/templates/asas/src/messages/mithaq.json +170 -0
- package/template/templates/asas/src/messages/organization.json +50 -0
- package/template/templates/asas/src/messages/organizationRole.json +50 -0
- package/template/templates/asas/src/messages/roles.json +58 -0
- package/template/templates/asas/src/messages/session.json +82 -0
- package/template/templates/asas/src/messages/sessions.json +106 -0
- package/template/templates/asas/src/messages/settings.json +66 -0
- package/template/templates/asas/src/messages/tags.json +38 -0
- package/template/templates/asas/src/messages/user.json +90 -0
- package/template/templates/asas/src/messages/verification.json +50 -0
- package/template/templates/asas/src/migrations/20260920080701_parched_tombstone/migration.sql +177 -0
- package/template/templates/asas/src/migrations/20260920080701_parched_tombstone/snapshot.json +2169 -0
- package/template/templates/asas/src/migrations/20260920230505_zippy_ben_urich/migration.sql +1 -0
- package/template/templates/asas/src/migrations/20260920230505_zippy_ben_urich/snapshot.json +2182 -0
- package/template/templates/asas/src/migrations/20260920231219_slim_retro_girl/migration.sql +20 -0
- package/template/templates/asas/src/migrations/20260920231219_slim_retro_girl/snapshot.json +2409 -0
- package/template/templates/asas/src/migrations/20260922082945_military_ironclad/migration.sql +15 -0
- package/template/templates/asas/src/migrations/20260922082945_military_ironclad/snapshot.json +2627 -0
- package/template/templates/asas/src/migrations/20260922112630_bitter_chat/migration.sql +5 -0
- package/template/templates/asas/src/migrations/20260922112630_bitter_chat/snapshot.json +2691 -0
- package/template/templates/asas/src/migrations/20260923235915_foamy_rachel_grey/migration.sql +8 -0
- package/template/templates/asas/src/migrations/20260923235915_foamy_rachel_grey/snapshot.json +2795 -0
- package/template/templates/asas/src/migrations/20260926145709_clean_the_initiative/migration.sql +3 -0
- package/template/templates/asas/src/migrations/20260926145709_clean_the_initiative/snapshot.json +2834 -0
- package/template/templates/asas/src/migrations/20260927212525_bent_prowler/migration.sql +9 -0
- package/template/templates/asas/src/migrations/20260927212525_bent_prowler/snapshot.json +2870 -0
- package/template/templates/asas/src/migrations/20260927223441_tranquil_bromley/migration.sql +1 -0
- package/template/templates/asas/src/migrations/20260927223441_tranquil_bromley/snapshot.json +2881 -0
- package/template/templates/asas/src/migrations/20260928030047_outgoing_wraith/migration.sql +15 -0
- package/template/templates/asas/src/migrations/20260928030047_outgoing_wraith/snapshot.json +3073 -0
- package/template/templates/asas/src/migrations/20260929024407_grey_morlun/migration.sql +21 -0
- package/template/templates/asas/src/migrations/20260929024407_grey_morlun/snapshot.json +3098 -0
- package/template/templates/asas/src/migrations/20260929130530_bored_jackal/migration.sql +21 -0
- package/template/templates/asas/src/migrations/20260929130530_bored_jackal/snapshot.json +3124 -0
- package/template/templates/asas/src/migrations/20260930102924_material_newton_destine/migration.sql +32 -0
- package/template/templates/asas/src/migrations/20260930102924_material_newton_destine/snapshot.json +3324 -0
- package/template/templates/asas/src/migrations/20261003022353_clumsy_taskmaster/migration.sql +2 -0
- package/template/templates/asas/src/migrations/20261003022353_clumsy_taskmaster/snapshot.json +3350 -0
- package/template/templates/asas/src/migrations/20261003143249_premium_red_shift/migration.sql +21 -0
- package/template/templates/asas/src/migrations/20261003143249_premium_red_shift/snapshot.json +3635 -0
- package/template/templates/asas/src/migrations/20261008215349_square_norrin_radd/migration.sql +8 -0
- package/template/templates/asas/src/migrations/20261008215349_square_norrin_radd/snapshot.json +3635 -0
- package/template/templates/asas/src/migrations/20261008230204_many_scarecrow/migration.sql +18 -0
- package/template/templates/asas/src/migrations/20261008230204_many_scarecrow/snapshot.json +3635 -0
- package/template/templates/asas/src/migrations/20261010005521_elite_giant_girl/migration.sql +18 -0
- package/template/templates/asas/src/migrations/20261010005521_elite_giant_girl/snapshot.json +3635 -0
- package/template/templates/asas/src/migrations/20261010120822_needy_thunderbolt/migration.sql +11 -0
- package/template/templates/asas/src/migrations/20261010120822_needy_thunderbolt/snapshot.json +3667 -0
- package/template/templates/asas/src/migrations/20261012000752_organization_ownership/migration.sql +48 -0
- package/template/templates/asas/src/migrations/20261012000752_organization_ownership/snapshot.json +3891 -0
- package/template/templates/asas/src/migrations/drizzle.config.ts +11 -0
- package/template/templates/asas/src/migrations/schema.ts +29 -0
- package/template/templates/asas/src/mithaq.ts +406 -0
- package/template/templates/asas/src/pages.ts +74 -0
- package/template/templates/asas/src/platform-http.ts +96 -0
- package/template/templates/asas/src/rich-text-nodes.ts +11 -0
- package/template/templates/asas/src/roles/grants.ts +47 -0
- package/template/templates/asas/src/roles/roles.ts +184 -0
- package/template/templates/asas/src/roles/ui/role-form.tsx +226 -0
- package/template/templates/asas/src/roles/ui/roles.tsx +166 -0
- package/template/templates/asas/src/roles.ts +16 -0
- package/template/templates/asas/src/seed.ts +325 -0
- package/template/templates/asas/src/sessions/sessions.ts +155 -0
- package/template/templates/asas/src/settings/settings.ts +69 -0
- package/template/templates/asas/src/statements.ts +11 -0
- package/template/templates/asas/src/steps/expected-updated-at.ts +41 -0
- package/template/templates/asas/src/storage/defaults.ts +156 -0
- package/template/templates/asas/src/storage/index.ts +95 -0
- package/template/templates/asas/src/storage/local.ts +143 -0
- package/template/templates/asas/src/storage/r2.ts +5 -0
- package/template/templates/asas/src/storage/s3.ts +91 -0
- package/template/templates/asas/src/storage/uploadthing.ts +59 -0
- package/template/templates/asas/src/tags/tags.ts +80 -0
- package/template/templates/asas/src/tenant-access.ts +221 -0
- package/template/templates/asas/src/tenant-roles.ts +262 -0
- package/template/templates/asas/src/ui/app-shell.tsx +260 -0
- package/template/templates/asas/src/ui/kpi-card.tsx +25 -0
- package/template/templates/asas/src/ui/record-page.tsx +50 -0
- package/template/templates/asas/src/ui/rich-text-nodes.tsx +15 -0
- package/template/templates/asas/src/ui/screen-nav.tsx +28 -0
- package/template/templates/asas/src/ui/session-labels.tsx +36 -0
- package/template/templates/asas/src/ui/table-page.tsx +9 -0
- package/template/templates/asas/src/ui/top-shell.tsx +60 -0
- package/template/templates/asas/src/ui-dashboard/dashboard.tsx +294 -0
- package/template/templates/asas/src/ui-dashboard/members.tsx +630 -0
- package/template/templates/asas/src/ui-dashboard/theme-provider.tsx +10 -0
- package/template/templates/asas/src/ui-dashboard/versions.tsx +432 -0
- package/template/templates/asas/src/ui-platform/home.tsx +63 -0
- package/template/templates/asas/src/ui-platform/organization-actions.tsx +114 -0
- package/template/templates/asas/src/ui-platform/record-page.tsx +30 -0
- package/template/templates/asas/src/ui-platform/role-cells.tsx +52 -0
- package/template/templates/asas/src/ui-platform/user-actions.tsx +251 -0
- package/template/templates/asas/src/ui-portal/home.tsx +77 -0
- package/template/templates/asas/src/ui-portal/page.tsx +11 -0
- package/template/templates/auth/package.json +14 -0
- package/template/templates/auth/src/index.ts +690 -0
- package/template/templates/auth/src/platform-roles.ts +87 -0
- package/README.md +0 -3
|
@@ -0,0 +1,870 @@
|
|
|
1
|
+
// Imports no router, stylesheet or React, so a test can load this under plain `node`.
|
|
2
|
+
import auditLog from 'asas/messages/auditLog.json' with { type: 'json' }
|
|
3
|
+
import courses from 'asas/messages/courses.json' with { type: 'json' }
|
|
4
|
+
import enrollments from 'asas/messages/enrollments.json' with { type: 'json' }
|
|
5
|
+
import localUsers from 'asas/messages/localUsers.json' with { type: 'json' }
|
|
6
|
+
import media from 'asas/messages/media.json' with { type: 'json' }
|
|
7
|
+
import organization from 'asas/messages/organization.json' with { type: 'json' }
|
|
8
|
+
import memberRoles from 'asas/messages/memberRoles.json' with { type: 'json' }
|
|
9
|
+
import roles from 'asas/messages/roles.json' with { type: 'json' }
|
|
10
|
+
import sessions from 'asas/messages/sessions.json' with { type: 'json' }
|
|
11
|
+
import settings from 'asas/messages/settings.json' with { type: 'json' }
|
|
12
|
+
import tags from 'asas/messages/tags.json' with { type: 'json' }
|
|
13
|
+
|
|
14
|
+
// Restated, not imported: the original lives in a `.tsx` file and the test runner has no JSX compiler.
|
|
15
|
+
type Translate = (key: string, fallback?: string) => string | undefined
|
|
16
|
+
|
|
17
|
+
/** The locales this project declares. */
|
|
18
|
+
export const locales = ['ar', 'en'] as const
|
|
19
|
+
|
|
20
|
+
/** One of the locales this project declares. */
|
|
21
|
+
export type Locale = (typeof locales)[number]
|
|
22
|
+
|
|
23
|
+
/** The name of the cookie that carries a viewer's chosen locale. */
|
|
24
|
+
export const localeCookie = 'locale'
|
|
25
|
+
|
|
26
|
+
const localeCookieMaxAge = 60 * 60 * 24 * 365
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* The cookie value for a chosen locale. No `HttpOnly`, because the browser script
|
|
30
|
+
* writes it; no `Secure`, because the dev server is plain HTTP and the choice is not a credential.
|
|
31
|
+
*/
|
|
32
|
+
export const localeCookieValue = (locale: Locale): string =>
|
|
33
|
+
`${localeCookie}=${locale}; Path=/; Max-Age=${localeCookieMaxAge}; SameSite=Lax`
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Which locale one request reads in. The value comes from a request header a caller
|
|
37
|
+
* writes, so anything but a declared locale becomes `en`; nothing downstream asks again.
|
|
38
|
+
*/
|
|
39
|
+
export const localeOf = (asked: string | null | undefined): Locale =>
|
|
40
|
+
(locales as readonly string[]).includes(asked ?? '') ? (asked as Locale) : 'en'
|
|
41
|
+
|
|
42
|
+
/** Which way a document in one locale runs. */
|
|
43
|
+
export const dirOf = (locale: Locale): 'rtl' | 'ltr' => (locale === 'ar' ? 'rtl' : 'ltr')
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Every scope this app's `t` can answer from. Each entry carries a string per declared
|
|
47
|
+
* locale: a key left unanswered here shows an Arabic viewer the English fallback.
|
|
48
|
+
*/
|
|
49
|
+
export const scopes: Record<string, Record<string, Record<string, string>>> = {
|
|
50
|
+
courses: {
|
|
51
|
+
...courses,
|
|
52
|
+
'delete.confirm': { en: 'Delete this course', ar: 'احذف هذه الدورة' },
|
|
53
|
+
dangerZoneWarning: { en: 'These actions change this course for everyone.', ar: 'هذه الإجراءات تغير هذه الدورة للجميع.' },
|
|
54
|
+
none: { en: 'No courses yet.', ar: 'لا توجد دورات بعد.' },
|
|
55
|
+
noneOnOffer: { en: 'No courses on offer yet.', ar: 'لا توجد دورات معروضة بعد.' },
|
|
56
|
+
'operations.archive': { en: 'Archive', ar: 'أرشفة' },
|
|
57
|
+
'operations.archive.warning': { en: 'This archives {name}.', ar: 'يؤرشف هذا الإجراء {name}.' },
|
|
58
|
+
'operations.archive.portalReason': { en: 'Archived from the portal by {name}', ar: 'أُرشفت من البوابة بواسطة {name}' },
|
|
59
|
+
'operations.findWithSessions': { en: 'View with its sessions', ar: 'عرض مع جلساتها' },
|
|
60
|
+
new: { en: 'New course', ar: 'دورة جديدة' },
|
|
61
|
+
'archived.true': { en: 'Archived', ar: 'مؤرشف' },
|
|
62
|
+
'archived.false': { en: 'Active', ar: 'نشط' },
|
|
63
|
+
'operations.archive.reason.required': {
|
|
64
|
+
en: 'An archive reason is required.',
|
|
65
|
+
ar: 'سبب الأرشفة مطلوب.',
|
|
66
|
+
},
|
|
67
|
+
'operations.archive.reason.maxLength': {
|
|
68
|
+
en: 'An archive reason is at most 200 characters.',
|
|
69
|
+
ar: 'سبب الأرشفة 200 حرف على الأكثر.',
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
admin: {
|
|
73
|
+
nav: { en: 'Admin', ar: 'الإدارة' },
|
|
74
|
+
yes: { en: 'Yes', ar: 'نعم' },
|
|
75
|
+
no: { en: 'No', ar: 'لا' },
|
|
76
|
+
navigation: { en: 'Navigation', ar: 'التنقل' },
|
|
77
|
+
navigationAbout: { en: 'The pages you can open.', ar: 'الصفحات التي يمكنك فتحها.' },
|
|
78
|
+
mainNavigation: { en: 'Main navigation', ar: 'التنقل الرئيسي' },
|
|
79
|
+
notFound: { en: 'That page does not exist.', ar: 'هذه الصفحة غير موجودة.' },
|
|
80
|
+
notFoundTitle: { en: 'Page not found', ar: 'الصفحة غير موجودة' },
|
|
81
|
+
goHome: { en: 'Go to the home page', ar: 'الذهاب إلى الصفحة الرئيسية' },
|
|
82
|
+
new: { en: 'New', ar: 'جديد' },
|
|
83
|
+
createTitle: { en: 'Create {kind}', ar: 'إنشاء {kind}' },
|
|
84
|
+
save: { en: 'Save', ar: 'حفظ' },
|
|
85
|
+
afterCommitFailed: {
|
|
86
|
+
en: 'Saved, but a follow-up action failed, so something this save should have caused, such as an email or a notification, may be missing. Please contact an administrator.',
|
|
87
|
+
ar: 'تم الحفظ، لكن تعذر إجراء لاحق، فقد يكون ما كان ينبغي أن يتبع هذا الحفظ، كرسالة بريد أو إشعار، مفقودا. يرجى التواصل مع المسؤول.',
|
|
88
|
+
},
|
|
89
|
+
delete: { en: 'Delete', ar: 'حذف' },
|
|
90
|
+
impersonating: { en: 'You are impersonating', ar: 'أنت تنتحل صفة' },
|
|
91
|
+
stopImpersonating: { en: 'Stop impersonating', ar: 'إيقاف انتحال الصفة' },
|
|
92
|
+
cancel: { en: 'Cancel', ar: 'إلغاء' },
|
|
93
|
+
close: { en: 'Close', ar: 'إغلاق' },
|
|
94
|
+
deleteWarning: { en: 'This cannot be undone.', ar: 'لا يمكن التراجع عن هذا.' },
|
|
95
|
+
deleteConfirm: { en: 'Delete for good', ar: 'احذف نهائيا' },
|
|
96
|
+
deleteFailed: { en: 'Something went wrong, so nothing was deleted. Try again.', ar: 'حدث خطأ، فلم يُحذف شيء. حاول مرة أخرى.' },
|
|
97
|
+
discard: { en: 'Discard changes', ar: 'تجاهل التغييرات' },
|
|
98
|
+
discardWarning: {
|
|
99
|
+
en: 'You have unsaved changes. Leave without saving?',
|
|
100
|
+
ar: 'توجد تغييرات غير محفوظة. هل تريد المغادرة دون حفظ؟',
|
|
101
|
+
},
|
|
102
|
+
discardKeepsDraft: { en: 'The draft saved so far is kept.', ar: 'تبقى المسودة المحفوظة حتى الآن.' },
|
|
103
|
+
dangerZone: { en: 'Danger zone', ar: 'منطقة الخطر' },
|
|
104
|
+
dangerZoneWarning: {
|
|
105
|
+
en: 'These actions change this {kind} for everyone.',
|
|
106
|
+
ar: 'هذه الإجراءات تغير هذا السجل ({kind}) للجميع.',
|
|
107
|
+
},
|
|
108
|
+
edit: { en: 'Edit', ar: 'تعديل' },
|
|
109
|
+
view: { en: 'View', ar: 'عرض' },
|
|
110
|
+
rowActions: { en: 'Row actions', ar: 'إجراءات الصف' },
|
|
111
|
+
rowActionsFor: { en: 'Actions for {name}', ar: 'إجراءات {name}' },
|
|
112
|
+
openRow: { en: 'Press Enter to open this row.', ar: 'اضغط Enter لفتح هذا الصف.' },
|
|
113
|
+
untitled: { en: 'Untitled', ar: 'بدون عنوان' },
|
|
114
|
+
openUntitled: { en: 'Untitled, open', ar: 'بدون عنوان، فتح' },
|
|
115
|
+
missingComponent: {
|
|
116
|
+
en: 'No component is registered for "{component}".',
|
|
117
|
+
ar: 'لا يوجد مكون مسجل لـ "{component}".',
|
|
118
|
+
},
|
|
119
|
+
missingLayout: {
|
|
120
|
+
en: 'No component is registered for layout "{layout}".',
|
|
121
|
+
ar: 'لا يوجد مكون مسجل للتخطيط "{layout}".',
|
|
122
|
+
},
|
|
123
|
+
page: { en: 'Page', ar: 'صفحة' },
|
|
124
|
+
perPage: { en: 'Per page', ar: 'لكل صفحة' },
|
|
125
|
+
of: { en: 'of', ar: 'من' },
|
|
126
|
+
first: { en: 'First', ar: 'الأول' },
|
|
127
|
+
previous: { en: 'Previous', ar: 'السابق' },
|
|
128
|
+
next: { en: 'Next', ar: 'التالي' },
|
|
129
|
+
last: { en: 'Last', ar: 'الأخير' },
|
|
130
|
+
search: { en: 'Search', ar: 'بحث' },
|
|
131
|
+
bulkBar: { en: 'Ticked rows', ar: 'الصفوف المحددة' },
|
|
132
|
+
searchThrough: { en: '{relation} {field}', ar: '{field} ({relation})' },
|
|
133
|
+
clearSearch: { en: 'Clear search', ar: 'مسح البحث' },
|
|
134
|
+
filters: { en: 'Filters', ar: 'المرشحات' },
|
|
135
|
+
empty: { en: 'Nothing here yet.', ar: 'لا شيء هنا بعد.' },
|
|
136
|
+
loading: { en: 'Loading…', ar: 'جارٍ التحميل…' },
|
|
137
|
+
clear: { en: 'Clear', ar: 'مسح' },
|
|
138
|
+
unset: { en: 'unset', ar: 'غير محدد' },
|
|
139
|
+
pickDate: { en: 'Pick a date', ar: 'اختر تاريخا' },
|
|
140
|
+
'richText.undo': { en: 'Undo', ar: 'تراجع' },
|
|
141
|
+
'richText.redo': { en: 'Redo', ar: 'إعادة' },
|
|
142
|
+
'richText.toolbar': { en: 'Formatting', ar: 'التنسيق' },
|
|
143
|
+
'richText.blockFormatCurrent': { en: 'Block format: {block}', ar: 'نوع الفقرة: {block}' },
|
|
144
|
+
'richText.bold': { en: 'Bold', ar: 'عريض' },
|
|
145
|
+
'richText.italic': { en: 'Italic', ar: 'مائل' },
|
|
146
|
+
'richText.underline': { en: 'Underline', ar: 'تسطير' },
|
|
147
|
+
'richText.strikethrough': { en: 'Strikethrough', ar: 'يتوسطه خط' },
|
|
148
|
+
'richText.code': { en: 'Code', ar: 'شيفرة' },
|
|
149
|
+
'richText.addLink': { en: 'Add link', ar: 'إضافة رابط' },
|
|
150
|
+
'richText.removeLink': { en: 'Remove link', ar: 'إزالة الرابط' },
|
|
151
|
+
'richText.linkAddress': { en: 'Link address', ar: 'عنوان الرابط' },
|
|
152
|
+
'richText.editLink': { en: 'Edit link', ar: 'تعديل الرابط' },
|
|
153
|
+
'richText.saveLink': { en: 'Save link', ar: 'حفظ الرابط' },
|
|
154
|
+
'richText.cancelLink': { en: 'Cancel', ar: 'إلغاء' },
|
|
155
|
+
'richText.clearFormatting': { en: 'Clear formatting', ar: 'مسح التنسيق' },
|
|
156
|
+
'richText.alignLeft': { en: 'Align left', ar: 'محاذاة لليسار' },
|
|
157
|
+
'richText.alignCenter': { en: 'Align center', ar: 'توسيط' },
|
|
158
|
+
'richText.alignRight': { en: 'Align right', ar: 'محاذاة لليمين' },
|
|
159
|
+
'richText.justify': { en: 'Justify', ar: 'ضبط' },
|
|
160
|
+
'richText.outdent': { en: 'Outdent', ar: 'إنقاص المسافة البادئة' },
|
|
161
|
+
'richText.indent': { en: 'Indent', ar: 'زيادة المسافة البادئة' },
|
|
162
|
+
'richText.unknownNode': {
|
|
163
|
+
en: 'This text holds a "{type}" node this editor cannot draw, so it is shown as its words and cannot be changed here.',
|
|
164
|
+
ar: 'يحتوي هذا النص على عقدة "{type}" لا يستطيع هذا المحرر رسمها، فيُعرض بكلماته ولا يمكن تغييره هنا.',
|
|
165
|
+
},
|
|
166
|
+
'richText.unreadable': {
|
|
167
|
+
en: 'This editor cannot read this text, so it is shown as its words and cannot be changed here.',
|
|
168
|
+
ar: 'لا يستطيع هذا المحرر قراءة هذا النص، فيُعرض بكلماته ولا يمكن تغييره هنا.',
|
|
169
|
+
},
|
|
170
|
+
'upload.choose': { en: 'Choose a file', ar: 'اختر ملفا' },
|
|
171
|
+
'upload.add': { en: 'Add a file', ar: 'أضف ملفا' },
|
|
172
|
+
'upload.new': { en: 'Upload new', ar: 'رفع ملف جديد' },
|
|
173
|
+
'upload.file': { en: 'File', ar: 'الملف' },
|
|
174
|
+
'upload.noFile': { en: 'No file chosen', ar: 'لم يُختر أي ملف' },
|
|
175
|
+
'upload.required': { en: 'Choose a file first.', ar: 'اختر ملفا أولا.' },
|
|
176
|
+
'upload.takes': { en: 'Files of these types, {size} at most: {types}.', ar: 'ملفات من هذه الأنواع، بحد أقصى {size}: {types}.' },
|
|
177
|
+
'upload.send': { en: 'Upload', ar: 'رفع' },
|
|
178
|
+
'upload.sending': { en: 'Uploading… {percent}%', ar: 'جارٍ الرفع… {percent}٪' },
|
|
179
|
+
'upload.retry': { en: 'Try again', ar: 'أعد المحاولة' },
|
|
180
|
+
'upload.missing': { en: 'This file cannot be shown.', ar: 'لا يمكن عرض هذا الملف.' },
|
|
181
|
+
'upload.moveEarlier': { en: 'Move {name} earlier', ar: 'انقل {name} إلى السابق' },
|
|
182
|
+
'upload.moveLater': { en: 'Move {name} later', ar: 'انقل {name} إلى التالي' },
|
|
183
|
+
'upload.remove': { en: 'Remove {name}', ar: 'أزل {name}' },
|
|
184
|
+
'upload.image': { en: 'Image', ar: 'صورة' },
|
|
185
|
+
'upload.insert': { en: 'Insert an image', ar: 'إدراج صورة' },
|
|
186
|
+
'upload.insertHint': { en: 'Choose a file already here, or upload a new one.', ar: 'اختر ملفا موجودا هنا، أو ارفع ملفا جديدا.' },
|
|
187
|
+
time: { en: 'Time', ar: 'الوقت' },
|
|
188
|
+
showOptions: { en: 'Show options', ar: 'إظهار الخيارات' },
|
|
189
|
+
// base-ui names none of the combobox's icon-only buttons (`clear`, `showOptions`, `remove`), so a screen reader needs these.
|
|
190
|
+
remove: { en: 'Remove', ar: 'إزالة' },
|
|
191
|
+
andMore: { en: 'and {count} more', ar: 'و{count} أخرى' },
|
|
192
|
+
noMatches: { en: 'No rows match this filter.', ar: 'لا توجد صفوف تطابق هذا المرشح.' },
|
|
193
|
+
refused: { en: 'That list could not be read.', ar: 'تعذرت قراءة هذه القائمة.' },
|
|
194
|
+
cannotSee: { en: 'You can\'t see this', ar: 'لا يمكنك رؤية هذا' },
|
|
195
|
+
clearFilters: { en: 'Clear filters', ar: 'مسح المرشحات' },
|
|
196
|
+
selectAll: { en: 'Select every row on this page', ar: 'حدد كل صف في هذه الصفحة' },
|
|
197
|
+
selectRow: { en: 'Select this row', ar: 'حدد هذا الصف' },
|
|
198
|
+
selected: { en: '{count} selected', ar: '{count} محدد' },
|
|
199
|
+
actions: { en: 'Actions', ar: 'الإجراءات' },
|
|
200
|
+
bulkWarning_one: { en: '{plural} you ticked: 1. This applies to it.', ar: 'حددت واحدا من {plural}، وينطبق هذا عليه.' },
|
|
201
|
+
bulkWarning_two: { en: '{plural} you ticked: {count}. This applies to each of them.', ar: 'حددت اثنين من {plural}، وينطبق هذا عليهما.' },
|
|
202
|
+
bulkWarning_few: { en: '{plural} you ticked: {count}. This applies to each of them.', ar: 'حددت {count} من {plural}، وينطبق هذا عليها كلها.' },
|
|
203
|
+
bulkWarning_many: { en: '{plural} you ticked: {count}. This applies to each of them.', ar: 'حددت {count} من {plural}، وينطبق هذا عليها كلها.' },
|
|
204
|
+
bulkWarning_other: { en: '{plural} you ticked: {count}. This applies to each of them.', ar: 'حددت {count} من {plural}، وينطبق هذا عليها كلها.' },
|
|
205
|
+
bulkDone_one: { en: '{plural} done: 1.', ar: 'تم ذلك على واحد من {plural}.' },
|
|
206
|
+
bulkDone_two: { en: '{plural} done: {count}.', ar: 'تم ذلك على اثنين من {plural}.' },
|
|
207
|
+
bulkDone_few: { en: '{plural} done: {count}.', ar: 'تم ذلك على {count} من {plural}.' },
|
|
208
|
+
bulkDone_many: { en: '{plural} done: {count}.', ar: 'تم ذلك على {count} من {plural}.' },
|
|
209
|
+
bulkDone_other: { en: '{plural} done: {count}.', ar: 'تم ذلك على {count} من {plural}.' },
|
|
210
|
+
leaveAsIs: { en: 'Leave as is', ar: 'اتركه كما هو' },
|
|
211
|
+
bulkFilledOnly: { en: 'Only the fields you fill in change.', ar: 'تتغير الحقول التي تملؤها فقط.' },
|
|
212
|
+
bulkNothingFilled: { en: 'Fill in at least one field.', ar: 'املأ حقلًا واحدًا على الأقل.' },
|
|
213
|
+
bulkLeft_one: { en: '1 of the ticked rows was left as it is, because it has never been published.', ar: 'تُرك صف واحد محدد كما هو، لأنه لم يُنشر قط.' },
|
|
214
|
+
bulkLeft_two: { en: '{count} of the ticked rows were left as they are, because they have never been published.', ar: 'تُرك صفان محددان كما هما، لأنهما لم يُنشرا قط.' },
|
|
215
|
+
bulkLeft_few: { en: '{count} of the ticked rows were left as they are, because they have never been published.', ar: 'تُركت {count} صفوف محددة كما هي، لأنها لم تُنشر قط.' },
|
|
216
|
+
bulkLeft_many: { en: '{count} of the ticked rows were left as they are, because they have never been published.', ar: 'تُرك {count} صفا محددا كما هي، لأنها لم تُنشر قط.' },
|
|
217
|
+
bulkLeft_other: { en: '{count} of the ticked rows were left as they are, because they have never been published.', ar: 'تُرك {count} صف محدد كما هي، لأنها لم تُنشر قط.' },
|
|
218
|
+
toolbarWarning: { en: 'This runs on no row of the list.', ar: 'لا يعمل هذا على أي صف من القائمة.' },
|
|
219
|
+
rowWarning: { en: 'This applies to this row.', ar: 'ينطبق هذا على هذا الصف.' },
|
|
220
|
+
rowNamedWarning: { en: 'This applies to {name}.', ar: 'ينطبق هذا على {name}.' },
|
|
221
|
+
noColumns: {
|
|
222
|
+
en: 'Your role can\'t see any column of this list. Ask an administrator of your organization for access.',
|
|
223
|
+
ar: 'لا يستطيع دورك رؤية أي عمود في هذه القائمة. اطلب الوصول من مدير مؤسستك.',
|
|
224
|
+
},
|
|
225
|
+
queryRefused: {
|
|
226
|
+
en: 'This link asks the list for something it does not offer, so nothing was read.',
|
|
227
|
+
ar: 'يطلب هذا الرابط من القائمة ما لا تقدمه، فلم يُقرأ شيء.',
|
|
228
|
+
},
|
|
229
|
+
operationWarning: { en: 'This runs on the row you are editing.', ar: 'يعمل هذا على الصف الذي تحرره.' },
|
|
230
|
+
permissions: { en: 'Permissions', ar: 'الصلاحيات' },
|
|
231
|
+
record: { en: 'Record', ar: 'السجل' },
|
|
232
|
+
invalidFields: { en: 'Fields needing attention: {count}', ar: 'حقول تحتاج إلى مراجعة: {count}' },
|
|
233
|
+
organizations: { en: 'Organizations', ar: 'المؤسسات' },
|
|
234
|
+
organization: { en: 'Organization', ar: 'مؤسسة' },
|
|
235
|
+
noOrganization: { en: 'No organization', ar: 'لا توجد مؤسسة' },
|
|
236
|
+
signOut: { en: 'Sign out', ar: 'تسجيل الخروج' },
|
|
237
|
+
theme: { en: 'Toggle theme', ar: 'تبديل المظهر' },
|
|
238
|
+
themeLight: { en: 'Light', ar: 'فاتح' },
|
|
239
|
+
themeDark: { en: 'Dark', ar: 'داكن' },
|
|
240
|
+
themeSystem: { en: 'System', ar: 'النظام' },
|
|
241
|
+
// `toggleSidebar`: the primitive names itself in English alone, so an Arabic viewer hears English unless this is written.
|
|
242
|
+
quickCreate: { en: 'Quick Create', ar: 'إنشاء سريع' },
|
|
243
|
+
inbox: { en: 'Inbox', ar: 'صندوق الوارد' },
|
|
244
|
+
documents: { en: 'Documents', ar: 'المستندات' },
|
|
245
|
+
more: { en: 'More', ar: 'المزيد' },
|
|
246
|
+
open: { en: 'Open', ar: 'فتح' },
|
|
247
|
+
share: { en: 'Share', ar: 'مشاركة' },
|
|
248
|
+
trash: { en: 'Move to Trash', ar: 'نقل إلى المهملات' },
|
|
249
|
+
getHelp: { en: 'Get Help', ar: 'الحصول على مساعدة' },
|
|
250
|
+
toggleSidebar: { en: 'Toggle Sidebar', ar: 'تبديل الشريط الجانبي' },
|
|
251
|
+
},
|
|
252
|
+
portal: {
|
|
253
|
+
home: { en: 'Home', ar: 'الرئيسية' },
|
|
254
|
+
welcome: { en: 'Welcome, {name}', ar: 'مرحبا، {name}' },
|
|
255
|
+
about: { en: 'What you may open here, and how many of each you may read.', ar: 'ما يمكنك فتحه هنا، وعدد ما يمكنك قراءته من كل منها.' },
|
|
256
|
+
open: { en: 'Open the list', ar: 'افتح القائمة' },
|
|
257
|
+
},
|
|
258
|
+
auth: {
|
|
259
|
+
signIn: { en: 'Sign in', ar: 'تسجيل الدخول' },
|
|
260
|
+
signInDescription: { en: 'Sign in to reach the dashboard.', ar: 'سجل الدخول للوصول إلى لوحة التحكم.' },
|
|
261
|
+
signInPlatformDescription: { en: 'Sign in to reach the platform.', ar: 'سجل الدخول للوصول إلى المنصة.' },
|
|
262
|
+
signInPending: { en: 'Signing in…', ar: 'جارٍ تسجيل الدخول…' },
|
|
263
|
+
failed: { en: 'That sign-in did not work.', ar: 'لم ينجح تسجيل الدخول.' },
|
|
264
|
+
signUp: { en: 'Sign up', ar: 'إنشاء حساب' },
|
|
265
|
+
signUpDescription: { en: 'Make an account and its organization.', ar: 'أنشئ حسابا ومؤسسته.' },
|
|
266
|
+
signUpPending: { en: 'Signing up…', ar: 'جارٍ إنشاء الحساب…' },
|
|
267
|
+
signUpFailed: { en: 'That sign-up did not work.', ar: 'لم ينجح إنشاء الحساب.' },
|
|
268
|
+
organizationFailed: { en: 'That organization could not be created.', ar: 'تعذر إنشاء هذه المؤسسة.' },
|
|
269
|
+
name: { en: 'Name', ar: 'الاسم' },
|
|
270
|
+
organization: { en: 'Organization', ar: 'المؤسسة' },
|
|
271
|
+
email: { en: 'Email', ar: 'البريد الإلكتروني' },
|
|
272
|
+
password: { en: 'Password', ar: 'كلمة المرور' },
|
|
273
|
+
confirmPassword: { en: 'Confirm the password', ar: 'أكد كلمة المرور' },
|
|
274
|
+
passwordsDiffer: { en: 'The two passwords are not the same.', ar: 'كلمتا المرور غير متطابقتين.' },
|
|
275
|
+
required: { en: 'This field is required.', ar: 'هذا الحقل مطلوب.' },
|
|
276
|
+
invalidEmail: { en: 'Invalid email', ar: 'بريد إلكتروني غير صالح' },
|
|
277
|
+
passwordTooShort: { en: 'Password too short', ar: 'كلمة المرور قصيرة جدا' },
|
|
278
|
+
passwordTooLong: { en: 'Password too long', ar: 'كلمة المرور طويلة جدا' },
|
|
279
|
+
passwordRule: { en: 'At least {count} characters.', ar: '{count} أحرف على الأقل.' },
|
|
280
|
+
showPassword: { en: 'Show password', ar: 'إظهار كلمة المرور' },
|
|
281
|
+
forgotPasswordQuestion: { en: 'Forgot password?', ar: 'هل نسيت كلمة المرور؟' },
|
|
282
|
+
forgotPassword: { en: 'Forgot password', ar: 'نسيت كلمة المرور' },
|
|
283
|
+
forgotPasswordInstructions: {
|
|
284
|
+
en: 'Please enter your email below. You will receive an email message with instructions on how to reset your password.',
|
|
285
|
+
ar: 'أدخل بريدك الإلكتروني أدناه. ستصلك رسالة بريد إلكتروني فيها تعليمات إعادة تعيين كلمة المرور.',
|
|
286
|
+
},
|
|
287
|
+
submit: { en: 'Submit', ar: 'إرسال' },
|
|
288
|
+
emailSent: { en: 'Email sent', ar: 'تم إرسال البريد الإلكتروني' },
|
|
289
|
+
checkYourEmail: {
|
|
290
|
+
en: "If the email address is associated with an account, you will receive instructions to reset your password shortly. Please check your spam or junk mail folder if you don't see the email in your inbox.",
|
|
291
|
+
ar: 'إذا كان هذا البريد الإلكتروني مرتبطا بحساب، فستصلك قريبا تعليمات إعادة تعيين كلمة المرور. إذا لم تجد الرسالة في صندوق الوارد، فتحقق من مجلد البريد العشوائي أو غير المرغوب فيه.',
|
|
292
|
+
},
|
|
293
|
+
noMailer: {
|
|
294
|
+
en: 'No mailer is configured, so no email was sent. In development the reset link is written to the server log.',
|
|
295
|
+
ar: 'لم يُضبط أي مرسل بريد، لذا لم تُرسل أي رسالة. في بيئة التطوير يُكتب رابط إعادة التعيين في سجل الخادم.',
|
|
296
|
+
},
|
|
297
|
+
backToSignIn: { en: 'Back to login', ar: 'العودة إلى تسجيل الدخول' },
|
|
298
|
+
resetPassword: { en: 'Reset password', ar: 'إعادة تعيين كلمة المرور' },
|
|
299
|
+
newPassword: { en: 'New password', ar: 'كلمة مرور جديدة' },
|
|
300
|
+
passwordReset: { en: 'Password reset successfully.', ar: 'تمت إعادة تعيين كلمة المرور بنجاح.' },
|
|
301
|
+
tokenInvalid: { en: 'Token is either invalid or has expired.', ar: 'الرمز غير صالح أو انتهت صلاحيته.' },
|
|
302
|
+
alreadySignedIn: { en: 'You are already signed in', ar: 'سجلت الدخول بالفعل' },
|
|
303
|
+
backTo: { en: 'Back to {screen}', ar: 'العودة إلى {screen}' },
|
|
304
|
+
continue: { en: 'Continue', ar: 'متابعة' },
|
|
305
|
+
resetDisabled: {
|
|
306
|
+
en: 'Password reset is not available. Ask your administrator to reset your password.',
|
|
307
|
+
ar: 'إعادة تعيين كلمة المرور غير متاحة. اطلب من المسؤول إعادة تعيين كلمة المرور الخاصة بك.',
|
|
308
|
+
},
|
|
309
|
+
tooManyRequests: { en: 'Too many attempts. Wait a moment and try again.', ar: 'محاولات كثيرة جدا. انتظر قليلا ثم حاول مرة أخرى.' },
|
|
310
|
+
invalidCredentials: { en: 'The email or password provided is incorrect.', ar: 'البريد الإلكتروني أو كلمة المرور غير صحيحة.' },
|
|
311
|
+
emailNotVerified: { en: 'This email address is not verified yet.', ar: 'لم يوثق هذا البريد الإلكتروني بعد.' },
|
|
312
|
+
banned: { en: 'This account is banned, so it cannot sign in.', ar: 'هذا الحساب محظور، لذا لا يمكنه تسجيل الدخول.' },
|
|
313
|
+
userExists: { en: 'An account with this email already exists. Use another email.', ar: 'يوجد حساب بهذا البريد الإلكتروني. استخدم بريدا آخر.' },
|
|
314
|
+
requestFailed: { en: 'That request did not work.', ar: 'لم ينجح هذا الطلب.' },
|
|
315
|
+
resetFailed: { en: 'That reset did not work.', ar: 'لم تنجح إعادة التعيين.' },
|
|
316
|
+
noAccount: { en: 'No account yet?', ar: 'لا يوجد حساب بعد؟' },
|
|
317
|
+
invitation: { en: 'Invitation', ar: 'دعوة' },
|
|
318
|
+
invitationSignedOut: {
|
|
319
|
+
en: 'Sign in, or make an account with the email address the invitation was sent to, to accept it.',
|
|
320
|
+
ar: 'سجل الدخول، أو أنشئ حسابا بالبريد الإلكتروني الذي أُرسلت إليه الدعوة، لتقبلها.',
|
|
321
|
+
},
|
|
322
|
+
invitationReading: { en: 'Reading the invitation…', ar: 'جارٍ قراءة الدعوة…' },
|
|
323
|
+
invitationJoin: { en: 'You are invited to join {organization}.', ar: 'أنت مدعو للانضمام إلى {organization}.' },
|
|
324
|
+
invitationAccept: { en: 'Accept the invitation', ar: 'قبول الدعوة' },
|
|
325
|
+
invitationAccepting: { en: 'Accepting…', ar: 'جارٍ القبول…' },
|
|
326
|
+
invitationAcceptFailed: { en: 'That invitation could not be accepted.', ar: 'تعذر قبول هذه الدعوة.' },
|
|
327
|
+
invitationMissing: { en: 'This link names no invitation.', ar: 'هذا الرابط لا يشير إلى أي دعوة.' },
|
|
328
|
+
invitationInviterGone: {
|
|
329
|
+
en: 'Whoever sent this invitation is no longer a member of the organization, so it cannot be accepted. Ask a member to invite you again.',
|
|
330
|
+
ar: 'من أرسل هذه الدعوة لم يعد عضوا في المؤسسة، لذا لا يمكن قبولها. اطلب من أحد الأعضاء أن يدعوك مرة أخرى.',
|
|
331
|
+
},
|
|
332
|
+
invitationGone: {
|
|
333
|
+
en: 'This invitation has expired, was cancelled or was already accepted. Ask whoever invited you to send a new one.',
|
|
334
|
+
ar: 'انتهت صلاحية هذه الدعوة أو أُلغيت أو قُبلت من قبل. اطلب ممن دعاك أن يرسل دعوة جديدة.',
|
|
335
|
+
},
|
|
336
|
+
invitationNotYours: {
|
|
337
|
+
en: 'This invitation was sent to another email address. Sign out, then sign in with that address to accept it.',
|
|
338
|
+
ar: 'أُرسلت هذه الدعوة إلى بريد إلكتروني آخر. سجل الخروج، ثم سجل الدخول بذلك البريد لقبولها.',
|
|
339
|
+
},
|
|
340
|
+
signUpInvitedDescription: {
|
|
341
|
+
en: 'Make an account with the email address the invitation was sent to.',
|
|
342
|
+
ar: 'أنشئ حسابا بالبريد الإلكتروني الذي أُرسلت إليه الدعوة.',
|
|
343
|
+
},
|
|
344
|
+
haveAccount: { en: 'Already have an account?', ar: 'لديك حساب بالفعل؟' },
|
|
345
|
+
unauthorized: { en: 'Not for your role', ar: 'ليست لدورك' },
|
|
346
|
+
unauthorizedDescription: { en: 'Your role does not open that screen. These are the screens it opens:', ar: 'دورك لا يفتح تلك الشاشة. هذه هي الشاشات التي يفتحها:' },
|
|
347
|
+
unauthorizedPage: { en: 'Your role does not open that page: {page}.', ar: 'دورك لا يفتح تلك الصفحة: {page}.' },
|
|
348
|
+
noAccess: { en: 'Your account has no access yet', ar: 'لا يملك حسابك أي وصول بعد' },
|
|
349
|
+
noAccessDescription: {
|
|
350
|
+
en: '{email} is a member of {organization} and holds no role that opens a screen here. Ask an administrator of {organization} to give you one.',
|
|
351
|
+
ar: '{email} عضو في {organization} ولا يملك دورا يفتح أي شاشة هنا. اطلب من أحد مسؤولي {organization} أن يمنحك دورا.',
|
|
352
|
+
},
|
|
353
|
+
switchTo: { en: 'Switch to {organization}', ar: 'التبديل إلى {organization}' },
|
|
354
|
+
accountStatus: { en: 'See your account status', ar: 'اطّلع على حالة حسابك' },
|
|
355
|
+
noOrganization: {
|
|
356
|
+
en: '{email} belongs to no organization yet. Ask an administrator to invite you.',
|
|
357
|
+
ar: '{email} لا ينتمي إلى أي مؤسسة بعد. اطلب من أحد المسؤولين أن يدعوك.',
|
|
358
|
+
},
|
|
359
|
+
},
|
|
360
|
+
marketing: {
|
|
361
|
+
brand: { en: 'Asas', ar: 'أساس' },
|
|
362
|
+
getStarted: { en: 'Get started', ar: 'ابدأ الآن' },
|
|
363
|
+
openScreen: { en: 'Open {screen}', ar: 'افتح {screen}' },
|
|
364
|
+
heroTitle: { en: 'Run courses and enrollments without the busywork', ar: 'أدر الدورات والتسجيلات دون العمل الروتيني' },
|
|
365
|
+
heroSubtitle: {
|
|
366
|
+
en: 'Asas is a dashboard and a portal for organizations that teach: manage courses, see who enrolled, and keep every role to what it should see.',
|
|
367
|
+
ar: 'أساس لوحة تحكم وبوابة للمؤسسات التي تُعلّم: أدر الدورات، اطّلع على من سجل، واحصر كل دور بما ينبغي أن يراه.',
|
|
368
|
+
},
|
|
369
|
+
featuresTitle: { en: 'Everything a training organization needs', ar: 'كل ما تحتاجه مؤسسة تدريبية' },
|
|
370
|
+
featuresSubtitle: {
|
|
371
|
+
en: 'One system for the whole lifecycle, from listing a course to seeing who is enrolled in it.',
|
|
372
|
+
ar: 'نظام واحد لدورة الحياة كاملة، من نشر دورة إلى معرفة من سجل فيها.',
|
|
373
|
+
},
|
|
374
|
+
featureCoursesTitle: { en: 'Courses and sessions', ar: 'الدورات والجلسات' },
|
|
375
|
+
featureCoursesDescription: {
|
|
376
|
+
en: 'Create courses, set their fee and schedule, and open or archive them as they run.',
|
|
377
|
+
ar: 'أنشئ الدورات، حدد رسومها وجدولها، وافتحها أو أرشفها أثناء انعقادها.',
|
|
378
|
+
},
|
|
379
|
+
featureEnrollmentsTitle: { en: 'Enrollments', ar: 'التسجيلات' },
|
|
380
|
+
featureEnrollmentsDescription: {
|
|
381
|
+
en: 'See who enrolled in each course and when, with the day-by-day count on the dashboard.',
|
|
382
|
+
ar: 'اطلع على من سجل في كل دورة ومتى، مع العدد اليومي في لوحة التحكم.',
|
|
383
|
+
},
|
|
384
|
+
featureRolesTitle: { en: 'Roles and permissions', ar: 'الأدوار والصلاحيات' },
|
|
385
|
+
featureRolesDescription: {
|
|
386
|
+
en: 'Each organization sets its own roles, and every screen, field and action follows what a role may read or write.',
|
|
387
|
+
ar: 'تحدد كل مؤسسة أدوارها الخاصة، وتتبع كل شاشة وحقل وإجراء ما يحق للدور قراءته أو تعديله.',
|
|
388
|
+
},
|
|
389
|
+
featureBilingualTitle: { en: 'Arabic and English, either direction', ar: 'العربية والإنجليزية، بكلا الاتجاهين' },
|
|
390
|
+
featureBilingualDescription: {
|
|
391
|
+
en: 'Every screen and every label is written in both languages, and the layout mirrors correctly under Arabic.',
|
|
392
|
+
ar: 'كل شاشة وكل تسمية مكتوبة باللغتين، ويُعكس التخطيط بشكل صحيح تحت العربية.',
|
|
393
|
+
},
|
|
394
|
+
featurePortalTitle: { en: 'A dashboard and a customer portal', ar: 'لوحة تحكم وبوابة للعملاء' },
|
|
395
|
+
featurePortalDescription: {
|
|
396
|
+
en: 'Staff work from the dashboard; customers see their own shorter view of the same data in the portal.',
|
|
397
|
+
ar: 'يعمل الموظفون من لوحة التحكم؛ ويرى العملاء نسختهم المختصرة من البيانات نفسها في البوابة.',
|
|
398
|
+
},
|
|
399
|
+
howTitle: { en: 'How it works', ar: 'كيف يعمل' },
|
|
400
|
+
howStep1Title: { en: 'Set up your organization', ar: 'أنشئ مؤسستك' },
|
|
401
|
+
howStep1Description: { en: 'Sign up and create your organization in one step.', ar: 'أنشئ حسابك ومؤسستك في خطوة واحدة.' },
|
|
402
|
+
howStep2Title: { en: 'Add courses and roles', ar: 'أضف الدورات والأدوار' },
|
|
403
|
+
howStep2Description: {
|
|
404
|
+
en: 'List your courses and decide what each role in your organization may do.',
|
|
405
|
+
ar: 'أدرج دوراتك وحدد ما يحق لكل دور في مؤسستك القيام به.',
|
|
406
|
+
},
|
|
407
|
+
howStep3Title: { en: 'Open the portal to your customers', ar: 'افتح البوابة لعملائك' },
|
|
408
|
+
howStep3Description: {
|
|
409
|
+
en: 'Customers sign in to their own portal to see the courses they may enroll in.',
|
|
410
|
+
ar: 'يسجل العملاء الدخول إلى بوابتهم الخاصة لرؤية الدورات التي يمكنهم التسجيل فيها.',
|
|
411
|
+
},
|
|
412
|
+
ctaTitle: { en: 'Start running your courses on Asas', ar: 'ابدأ بإدارة دوراتك على أساس' },
|
|
413
|
+
ctaSubtitle: { en: 'Create your organization and add your first course in minutes.', ar: 'أنشئ مؤسستك وأضف أول دورة لك خلال دقائق.' },
|
|
414
|
+
footer: { en: 'Asas — courses and enrollments for training organizations.', ar: 'أساس — الدورات والتسجيلات للمؤسسات التدريبية.' },
|
|
415
|
+
},
|
|
416
|
+
dashboard: {
|
|
417
|
+
dashboard: { en: 'Dashboard', ar: 'لوحة التحكم' },
|
|
418
|
+
openPlatform: { en: 'Open the platform', ar: 'فتح المنصة' },
|
|
419
|
+
members: { en: 'Members', ar: 'الأعضاء' },
|
|
420
|
+
membersAbout: { en: 'Who works in this organization, and the role each holds.', ar: 'من يعمل في هذه المؤسسة، والدور الذي يشغله كل منهم.' },
|
|
421
|
+
membersRoles: { en: 'Roles', ar: 'الأدوار' },
|
|
422
|
+
membersName: { en: 'Name', ar: 'الاسم' },
|
|
423
|
+
membersEmail: { en: 'Email', ar: 'البريد الإلكتروني' },
|
|
424
|
+
membersJoined: { en: 'Joined', ar: 'تاريخ الانضمام' },
|
|
425
|
+
membersNone: { en: 'No one works in this organization yet.', ar: 'لا يعمل أحد في هذه المؤسسة بعد.' },
|
|
426
|
+
invite: { en: 'Invite', ar: 'دعوة' },
|
|
427
|
+
inviteTitle: { en: 'Invite someone', ar: 'دعوة شخص' },
|
|
428
|
+
inviteAbout: {
|
|
429
|
+
en: 'They join this organization as a member once they accept. Give them roles here after that.',
|
|
430
|
+
ar: 'ينضم إلى هذه المؤسسة عضوًا بعد أن يقبل الدعوة. امنحه الأدوار هنا بعد ذلك.',
|
|
431
|
+
},
|
|
432
|
+
inviteSend: { en: 'Send invitation', ar: 'إرسال الدعوة' },
|
|
433
|
+
inviteRefused: { en: 'The server refused that invitation.', ar: 'رفض الخادم هذه الدعوة.' },
|
|
434
|
+
inviteAlreadyMember: { en: 'This person is already a member of this organization.', ar: 'هذا الشخص عضو في هذه المؤسسة بالفعل.' },
|
|
435
|
+
inviteAlreadyInvited: { en: 'This person already has an invitation that is not yet accepted.', ar: 'لدى هذا الشخص دعوة لم تُقبل بعد.' },
|
|
436
|
+
inviteNotAllowed: { en: 'You may not invite people to this organization.', ar: 'لا يحق لك دعوة أشخاص إلى هذه المؤسسة.' },
|
|
437
|
+
inviteNoMailer: {
|
|
438
|
+
en: 'No mailer is configured, so no email is sent. In development the link is written to the server log, and each pending invitation has a link to copy.',
|
|
439
|
+
ar: 'لم يُضبط أي مرسل بريد، لذا لا تُرسل أي رسالة. في بيئة التطوير يُكتب الرابط في سجل الخادم، ولكل دعوة لم تُقبل بعد رابط يمكن نسخه.',
|
|
440
|
+
},
|
|
441
|
+
inviteCopy: { en: 'Copy link', ar: 'نسخ الرابط' },
|
|
442
|
+
inviteCopied: { en: 'Link copied', ar: 'تم نسخ الرابط' },
|
|
443
|
+
inviteCancel: { en: 'Cancel invitation', ar: 'إلغاء الدعوة' },
|
|
444
|
+
inviteCancelRefused: { en: 'The server refused to cancel that invitation.', ar: 'رفض الخادم إلغاء هذه الدعوة.' },
|
|
445
|
+
inviteCancelNotAllowed: { en: 'You may not cancel this invitation.', ar: 'لا يحق لك إلغاء هذه الدعوة.' },
|
|
446
|
+
removeMember: { en: 'Remove from organization', ar: 'إزالة من المؤسسة' },
|
|
447
|
+
removeAbout: {
|
|
448
|
+
en: 'They lose access to this organization and every role they hold in it. Inviting them again does not give the roles back.',
|
|
449
|
+
ar: 'يفقد هذا العضو الوصول إلى هذه المؤسسة وكل الأدوار التي يشغلها فيها. دعوته مرة أخرى لا تعيد إليه أدواره.',
|
|
450
|
+
},
|
|
451
|
+
removeConfirm: { en: 'Remove for good', ar: 'إزالة نهائيا' },
|
|
452
|
+
removeKeep: { en: 'Keep this member', ar: 'إبقاء هذا العضو' },
|
|
453
|
+
removeRefused: { en: 'The server refused to remove that member.', ar: 'رفض الخادم إزالة هذا العضو.' },
|
|
454
|
+
removeLastOwner: { en: 'The organization\'s only owner cannot be removed.', ar: 'لا يمكن إزالة المالك الوحيد للمؤسسة.' },
|
|
455
|
+
removeNotAllowed: { en: 'You may not remove members of this organization.', ar: 'لا يحق لك إزالة أعضاء هذه المؤسسة.' },
|
|
456
|
+
rolesHolderUnnamed: { en: 'A member', ar: 'أحد الأعضاء' },
|
|
457
|
+
invitesPending: { en: 'Invitations not yet accepted', ar: 'دعوات لم تُقبل بعد' },
|
|
458
|
+
inviteExpires: { en: 'Expires', ar: 'تنتهي في' },
|
|
459
|
+
membersActions: { en: 'Actions', ar: 'الإجراءات' },
|
|
460
|
+
membersEdit: { en: 'Edit roles', ar: 'تعديل الأدوار' },
|
|
461
|
+
membersFixed: { en: 'Fixed roles', ar: 'الأدوار الثابتة' },
|
|
462
|
+
membersCustom: { en: 'Custom roles', ar: 'الأدوار المخصصة' },
|
|
463
|
+
membersPermissions: { en: '{count} permissions', ar: 'الصلاحيات: {count}' },
|
|
464
|
+
membersNoRoles: { en: 'There is no role you may read to assign.', ar: 'لا يوجد دور يمكنك قراءته لإسناده.' },
|
|
465
|
+
membersRefused: { en: 'The server refused that change.', ar: 'رفض الخادم هذا التغيير.' },
|
|
466
|
+
everyPermission: { en: 'Every permission', ar: 'كل الصلاحيات' },
|
|
467
|
+
rolesAbout: {
|
|
468
|
+
en: 'Fixed roles ship with the project and cannot be changed here. Custom roles are this organization\'s own.',
|
|
469
|
+
ar: 'الأدوار الثابتة تأتي مع المشروع ولا يمكن تغييرها هنا. الأدوار المخصصة خاصة بهذه المؤسسة.',
|
|
470
|
+
},
|
|
471
|
+
rolesNew: { en: 'New role', ar: 'دور جديد' },
|
|
472
|
+
rolesKind: { en: 'Kind', ar: 'النوع' },
|
|
473
|
+
rolesFixed: { en: 'Fixed', ar: 'ثابت' },
|
|
474
|
+
rolesCustom: { en: 'Custom', ar: 'مخصص' },
|
|
475
|
+
rolesFixedAbout: {
|
|
476
|
+
en: 'This role ships with the project. What it holds is code, so it cannot be edited or deleted here.',
|
|
477
|
+
ar: 'يأتي هذا الدور مع المشروع. ما يمنحه مكتوب في الشيفرة، لذا لا يمكن تعديله أو حذفه هنا.',
|
|
478
|
+
},
|
|
479
|
+
rolesDeleteTitle: { en: 'Delete this role?', ar: 'حذف هذا الدور؟' },
|
|
480
|
+
rolesHeldTitle: { en: 'Members hold this role', ar: 'أعضاء يشغلون هذا الدور' },
|
|
481
|
+
rolesHeld: {
|
|
482
|
+
en: 'A role a member holds is not deleted. Take it from each of them on the Members page first.',
|
|
483
|
+
ar: 'لا يُحذف دور يشغله عضو. اسحبه من كل منهم في صفحة الأعضاء أولا.',
|
|
484
|
+
},
|
|
485
|
+
permissionsScreens: { en: 'Screens', ar: 'الشاشات' },
|
|
486
|
+
permissionsFields: { en: 'Fields', ar: 'الحقول' },
|
|
487
|
+
permissionsOther: { en: 'Other', ar: 'أخرى' },
|
|
488
|
+
permissionsRequired: { en: 'Permissions, required', ar: 'الصلاحيات، مطلوبة' },
|
|
489
|
+
membersOwnRole: {
|
|
490
|
+
en: 'This role lets you manage roles, so only another member who may manage roles takes it from you.',
|
|
491
|
+
ar: 'هذا الدور يتيح لك إدارة الأدوار، لذا لا يسحبه منك إلا عضو آخر يملك إدارة الأدوار.',
|
|
492
|
+
},
|
|
493
|
+
membersOwnerRole: {
|
|
494
|
+
en: 'The owner of the organization always holds this role.',
|
|
495
|
+
ar: 'مالك المؤسسة يشغل هذا الدور دائما.',
|
|
496
|
+
},
|
|
497
|
+
dashboardAbout: { en: 'What this organization holds, and how many have enrolled lately.', ar: 'ما تضمه هذه المؤسسة، وعدد من سجلوا مؤخرا.' },
|
|
498
|
+
dashboardAboutCatalogue: { en: 'What this organization holds.', ar: 'ما تضمه هذه المؤسسة.' },
|
|
499
|
+
kpiCourses: { en: 'Courses', ar: 'الدورات' },
|
|
500
|
+
kpiCoursesOpen: { en: '{count} not archived', ar: 'غير المؤرشفة: {count}' },
|
|
501
|
+
kpiFees: { en: 'Total fees', ar: 'مجموع الرسوم' },
|
|
502
|
+
kpiFeesFooter: { en: 'The fee of every course not archived, summed per currency', ar: 'رسوم كل دورة غير مؤرشفة، مجموعة لكل عملة' },
|
|
503
|
+
kpiEnrollments: { en: 'Enrollments', ar: 'التسجيلات' },
|
|
504
|
+
kpiAllTime: { en: 'Since the first one', ar: 'منذ أول تسجيل' },
|
|
505
|
+
kpiRecent: { en: 'New enrollments', ar: 'التسجيلات الجديدة' },
|
|
506
|
+
kpiInRange_few: { en: 'In the last {count} days', ar: 'خلال آخر {count} أيام' },
|
|
507
|
+
kpiInRange_many: { en: 'In the last {count} days', ar: 'خلال آخر {count} يومًا' },
|
|
508
|
+
kpiInRange_other: { en: 'In the last {count} days', ar: 'خلال آخر {count} يوم' },
|
|
509
|
+
chartEnrollments: { en: 'Enrollments per day', ar: 'التسجيلات في كل يوم' },
|
|
510
|
+
chartDays_few: { en: '{count} days', ar: '{count} أيام' },
|
|
511
|
+
chartDays_many: { en: '{count} days', ar: '{count} يومًا' },
|
|
512
|
+
chartDays_other: { en: '{count} days', ar: '{count} يوم' },
|
|
513
|
+
upcoming: { en: 'Upcoming sessions', ar: 'الجلسات القادمة' },
|
|
514
|
+
upcomingAbout: { en: 'The next sessions to start, soonest first.', ar: 'الجلسات التالية التي ستبدأ، الأقرب أولا.' },
|
|
515
|
+
upcomingNone: { en: 'No session is about to start.', ar: 'لا توجد جلسة على وشك البدء.' },
|
|
516
|
+
},
|
|
517
|
+
permissions: {
|
|
518
|
+
find: { en: 'List', ar: 'عرض القائمة' },
|
|
519
|
+
findByID: { en: 'View', ar: 'عرض' },
|
|
520
|
+
findOne: { en: 'View', ar: 'عرض' },
|
|
521
|
+
count: { en: 'Count', ar: 'العد' },
|
|
522
|
+
create: { en: 'Create', ar: 'إنشاء' },
|
|
523
|
+
update: { en: 'Edit', ar: 'تعديل' },
|
|
524
|
+
delete: { en: 'Delete', ar: 'حذف' },
|
|
525
|
+
updateMany: { en: 'Edit many', ar: 'تعديل عدة سجلات' },
|
|
526
|
+
deleteMany: { en: 'Delete many', ar: 'حذف عدة سجلات' },
|
|
527
|
+
findVersions: { en: 'List versions', ar: 'عرض الإصدارات' },
|
|
528
|
+
findVersionByID: { en: 'View a version', ar: 'عرض إصدار' },
|
|
529
|
+
restoreVersion: { en: 'Restore a version', ar: 'استعادة إصدار' },
|
|
530
|
+
},
|
|
531
|
+
locale: {
|
|
532
|
+
ar: { en: 'Arabic', ar: 'العربية' },
|
|
533
|
+
en: { en: 'English', ar: 'الإنجليزية' },
|
|
534
|
+
},
|
|
535
|
+
screens: {
|
|
536
|
+
dashboard: { en: 'Dashboard', ar: 'لوحة التحكم' },
|
|
537
|
+
portal: { en: 'Portal', ar: 'البوابة' },
|
|
538
|
+
platform: { en: 'Platform', ar: 'المنصة' },
|
|
539
|
+
},
|
|
540
|
+
platform: {
|
|
541
|
+
title: { en: 'Platform', ar: 'المنصة' },
|
|
542
|
+
brand: { en: 'Asas platform', ar: 'منصة أساس' },
|
|
543
|
+
about: { en: 'Every organization and every person on the platform, for its staff.', ar: 'كل مؤسسة وكل شخص على المنصة، لفريقها.' },
|
|
544
|
+
role: { en: 'Platform role', ar: 'دور المنصة' },
|
|
545
|
+
noRole: { en: 'No platform role', ar: 'بلا دور في المنصة' },
|
|
546
|
+
setRole: { en: 'Set role', ar: 'تعيين الدور' },
|
|
547
|
+
ban: { en: 'Ban', ar: 'حظر' },
|
|
548
|
+
unban: { en: 'Unban', ar: 'رفع الحظر' },
|
|
549
|
+
impersonate: { en: 'Impersonate', ar: 'انتحال الصفة' },
|
|
550
|
+
confirmRole: { en: 'Give {name} the platform role "{role}"?', ar: 'منح {name} دور المنصة "{role}"؟' },
|
|
551
|
+
pickRole: { en: 'Pick another platform role for {name}.', ar: 'اختر دورًا آخر في المنصة لـ {name}.' },
|
|
552
|
+
confirmBan: {
|
|
553
|
+
en: 'Ban {name}? They are signed out of both apps and cannot sign in until the ban ends.',
|
|
554
|
+
ar: 'حظر {name}؟ سيُسجَّل خروجه من التطبيقين ولن يتمكن من تسجيل الدخول حتى ينتهي الحظر.',
|
|
555
|
+
},
|
|
556
|
+
confirmUnban: { en: 'Lift the ban on {name}? They can sign in again.', ar: 'رفع الحظر عن {name}؟ سيتمكن من تسجيل الدخول مجددا.' },
|
|
557
|
+
confirmImpersonate: {
|
|
558
|
+
en: 'Impersonate {name}? You act as them in the tenant app until you stop.',
|
|
559
|
+
ar: 'انتحال صفة {name}؟ ستتصرف باسمه في تطبيق المؤسسة حتى تتوقف.',
|
|
560
|
+
},
|
|
561
|
+
roleSet: { en: '{name} now holds the platform role "{role}".', ar: 'أصبح دور {name} في المنصة "{role}".' },
|
|
562
|
+
banned: { en: '{name} is banned.', ar: 'تم حظر {name}.' },
|
|
563
|
+
unbanned: { en: 'The ban on {name} is lifted.', ar: 'تم رفع الحظر عن {name}.' },
|
|
564
|
+
renamed: { en: 'The organization is now named {name}.', ar: 'أصبح اسم المؤسسة {name}.' },
|
|
565
|
+
refusedBanned: { en: 'This person is banned, so they cannot be impersonated.', ar: 'هذا الشخص محظور، فلا يمكن انتحال صفته.' },
|
|
566
|
+
banReason: { en: 'Reason', ar: 'السبب' },
|
|
567
|
+
banReasonNeeded: { en: 'A ban needs a reason.', ar: 'يحتاج الحظر إلى سبب.' },
|
|
568
|
+
banEnds: { en: 'Ban lasts', ar: 'مدة الحظر' },
|
|
569
|
+
banUntilLifted: { en: 'Until it is lifted', ar: 'حتى يُرفع' },
|
|
570
|
+
banDay: { en: 'One day', ar: 'يوم واحد' },
|
|
571
|
+
banWeek: { en: 'Seven days', ar: 'سبعة أيام' },
|
|
572
|
+
banMonth: { en: 'Thirty days', ar: 'ثلاثون يومًا' },
|
|
573
|
+
rename: { en: 'Rename', ar: 'إعادة التسمية' },
|
|
574
|
+
slugPattern: {
|
|
575
|
+
en: 'A slug is lowercase letters and digits joined by single dashes, such as admin-org.',
|
|
576
|
+
ar: 'المعرف النصي أحرف إنجليزية صغيرة وأرقام تفصل بينها شرطات مفردة، مثل admin-org.',
|
|
577
|
+
},
|
|
578
|
+
renameAbout: {
|
|
579
|
+
en: 'The new name and slug take the place of the old ones for everyone in this organization.',
|
|
580
|
+
ar: 'يحل الاسم والمعرّف الجديدان محل القديمين لكل من في هذه المؤسسة.',
|
|
581
|
+
},
|
|
582
|
+
members: { en: 'Members', ar: 'الأعضاء' },
|
|
583
|
+
refused: { en: 'The platform refused that action.', ar: 'رفضت المنصة هذا الإجراء.' },
|
|
584
|
+
'membership.owner': { en: 'Owner', ar: 'المالك' },
|
|
585
|
+
'membership.admin': { en: 'Admin', ar: 'مشرف' },
|
|
586
|
+
'membership.member': { en: 'Member', ar: 'عضو' },
|
|
587
|
+
},
|
|
588
|
+
user: {
|
|
589
|
+
singular: { en: 'Person', ar: 'شخص' },
|
|
590
|
+
plural: { en: 'People', ar: 'الأشخاص' },
|
|
591
|
+
none: { en: 'No people yet.', ar: 'لا يوجد أشخاص بعد.' },
|
|
592
|
+
id: { en: 'ID', ar: 'المعرّف' },
|
|
593
|
+
name: { en: 'Name', ar: 'الاسم' },
|
|
594
|
+
email: { en: 'Email', ar: 'البريد الإلكتروني' },
|
|
595
|
+
emailVerified: { en: 'Email verified', ar: 'البريد موثق' },
|
|
596
|
+
image: { en: 'Image', ar: 'الصورة' },
|
|
597
|
+
role: { en: 'Platform role', ar: 'دور المنصة' },
|
|
598
|
+
banned: { en: 'Banned', ar: 'محظور' },
|
|
599
|
+
banReason: { en: 'Ban reason', ar: 'سبب الحظر' },
|
|
600
|
+
banExpires: { en: 'Ban ends', ar: 'ينتهي الحظر' },
|
|
601
|
+
createdAt: { en: 'Created at', ar: 'تاريخ الإنشاء' },
|
|
602
|
+
updatedAt: { en: 'Updated at', ar: 'تاريخ التعديل' },
|
|
603
|
+
},
|
|
604
|
+
organization: {
|
|
605
|
+
...organization,
|
|
606
|
+
singular: { en: 'Organization', ar: 'مؤسسة' },
|
|
607
|
+
plural: { en: 'Organizations', ar: 'المؤسسات' },
|
|
608
|
+
none: { en: 'No organizations yet.', ar: 'لا توجد مؤسسات بعد.' },
|
|
609
|
+
id: { en: 'ID', ar: 'المعرّف' },
|
|
610
|
+
name: { en: 'Name', ar: 'الاسم' },
|
|
611
|
+
slug: { en: 'Slug', ar: 'المعرّف النصي' },
|
|
612
|
+
logo: { en: 'Logo', ar: 'الشعار' },
|
|
613
|
+
metadata: { en: 'Metadata', ar: 'البيانات الوصفية' },
|
|
614
|
+
createdAt: { en: 'Created at', ar: 'تاريخ الإنشاء' },
|
|
615
|
+
updatedAt: { en: 'Updated at', ar: 'تاريخ التعديل' },
|
|
616
|
+
},
|
|
617
|
+
member: {
|
|
618
|
+
singular: { en: 'Member', ar: 'عضو' },
|
|
619
|
+
plural: { en: 'Members', ar: 'الأعضاء' },
|
|
620
|
+
none: { en: 'No members yet.', ar: 'لا يوجد أعضاء بعد.' },
|
|
621
|
+
id: { en: 'ID', ar: 'المعرّف' },
|
|
622
|
+
userId: { en: 'Person', ar: 'الشخص' },
|
|
623
|
+
organizationId: { en: 'Organization', ar: 'المؤسسة' },
|
|
624
|
+
role: { en: 'Membership role', ar: 'دور العضوية' },
|
|
625
|
+
createdAt: { en: 'Created at', ar: 'تاريخ الإنشاء' },
|
|
626
|
+
updatedAt: { en: 'Updated at', ar: 'تاريخ التعديل' },
|
|
627
|
+
},
|
|
628
|
+
settings: {
|
|
629
|
+
...settings,
|
|
630
|
+
singular: { en: 'Settings', ar: 'الإعدادات' },
|
|
631
|
+
plural: { en: 'Settings', ar: 'الإعدادات' },
|
|
632
|
+
},
|
|
633
|
+
roles: {
|
|
634
|
+
...roles,
|
|
635
|
+
singular: { en: 'Role', ar: 'دور' },
|
|
636
|
+
plural: { en: 'Roles', ar: 'الأدوار' },
|
|
637
|
+
'delete.confirm': { en: 'Delete this role', ar: 'احذف هذا الدور' },
|
|
638
|
+
new: { en: 'New role', ar: 'دور جديد' },
|
|
639
|
+
none: { en: 'No roles yet.', ar: 'لا توجد أدوار بعد.' },
|
|
640
|
+
dangerZoneWarning: {
|
|
641
|
+
en: 'Deleting this role takes it away for everyone. A role a member holds is not deleted: take it from each of them on the Members page first.',
|
|
642
|
+
ar: 'حذف هذا الدور يزيله للجميع. لا يُحذف دور يشغله عضو: اسحبه من كل منهم في صفحة الأعضاء أولا.',
|
|
643
|
+
},
|
|
644
|
+
'name.description': {
|
|
645
|
+
en: 'The role\'s slug, which every assignment of it names, such as course-editor. People read the role by its label below.',
|
|
646
|
+
ar: 'المعرف النصي للدور، الذي يسميه كل إسناد له، مثل course-editor. يقرأ الناس الدور بتسميته أدناه.',
|
|
647
|
+
},
|
|
648
|
+
},
|
|
649
|
+
sessions: {
|
|
650
|
+
...sessions,
|
|
651
|
+
singular: { en: 'Session', ar: 'جلسة' },
|
|
652
|
+
plural: { en: 'Sessions', ar: 'الجلسات' },
|
|
653
|
+
'operations.archiveMany': { en: 'Archive many', ar: 'أرشفة عدة جلسات' },
|
|
654
|
+
new: { en: 'New session', ar: 'جلسة جديدة' },
|
|
655
|
+
none: { en: 'No sessions yet.', ar: 'لا توجد جلسات بعد.' },
|
|
656
|
+
dangerZoneWarning: { en: 'These actions change this session for everyone.', ar: 'هذه الإجراءات تغير هذه الجلسة للجميع.' },
|
|
657
|
+
},
|
|
658
|
+
enrollments: {
|
|
659
|
+
...enrollments,
|
|
660
|
+
singular: { en: 'Enrollment', ar: 'تسجيل' },
|
|
661
|
+
plural: { en: 'Enrollments', ar: 'التسجيلات' },
|
|
662
|
+
'operations.others': { en: 'Everyone\'s enrollments', ar: 'تسجيلات الجميع' },
|
|
663
|
+
new: { en: 'New enrollment', ar: 'تسجيل جديد' },
|
|
664
|
+
none: { en: 'No enrollments yet.', ar: 'لا توجد تسجيلات بعد.' },
|
|
665
|
+
dangerZoneWarning: { en: 'These actions change this enrollment for everyone.', ar: 'هذه الإجراءات تغير هذا التسجيل للجميع.' },
|
|
666
|
+
},
|
|
667
|
+
tags: {
|
|
668
|
+
...tags,
|
|
669
|
+
new: { en: 'New tag', ar: 'وسم جديد' },
|
|
670
|
+
none: { en: 'No tags yet.', ar: 'لا توجد وسوم بعد.' },
|
|
671
|
+
dangerZoneWarning: { en: 'These actions change this tag for everyone.', ar: 'هذه الإجراءات تغير هذا الوسم للجميع.' },
|
|
672
|
+
},
|
|
673
|
+
media: {
|
|
674
|
+
...media,
|
|
675
|
+
new: { en: 'New image', ar: 'صورة جديدة' },
|
|
676
|
+
none: { en: 'No images yet.', ar: 'لا توجد صور بعد.' },
|
|
677
|
+
newAbout: { en: 'Choose an image and describe it. It is uploaded before it is saved.', ar: 'اختر صورة وصِفها. تُرفع قبل أن تُحفظ.' },
|
|
678
|
+
download: { en: 'Download', ar: 'تنزيل' },
|
|
679
|
+
replace: { en: 'Replace file', ar: 'استبدال الملف' },
|
|
680
|
+
replaceAbout: { en: 'Replace file uploads a new image and opens it. This one stays until you delete it.', ar: 'يرفع استبدال الملف صورة جديدة ويفتحها. تبقى هذه الصورة حتى تحذفها.' },
|
|
681
|
+
dangerZoneWarning: { en: 'These actions change this image for everyone.', ar: 'هذه الإجراءات تغير هذه الصورة للجميع.' },
|
|
682
|
+
},
|
|
683
|
+
localUsers: { ...localUsers, none: { en: 'No local accounts yet.', ar: 'لا توجد حسابات محلية بعد.' } },
|
|
684
|
+
auditLog,
|
|
685
|
+
memberRoles: {
|
|
686
|
+
...memberRoles,
|
|
687
|
+
singular: { en: 'Member role', ar: 'دور عضو' },
|
|
688
|
+
plural: { en: 'Member roles', ar: 'أدوار الأعضاء' },
|
|
689
|
+
none: { en: 'No member roles yet.', ar: 'لا توجد أدوار أعضاء بعد.' },
|
|
690
|
+
},
|
|
691
|
+
version: {
|
|
692
|
+
saveDraft: { en: 'Save draft', ar: 'حفظ المسودة' },
|
|
693
|
+
publishChanges: { en: 'Publish changes', ar: 'نشر التغييرات' },
|
|
694
|
+
status: { en: 'Status', ar: 'الحالة' },
|
|
695
|
+
draft: { en: 'Draft', ar: 'مسودة' },
|
|
696
|
+
published: { en: 'Published', ar: 'منشور' },
|
|
697
|
+
changed: { en: 'Changed', ar: 'تغييرات غير منشورة' },
|
|
698
|
+
saving: { en: 'Saving…', ar: 'جارٍ الحفظ…' },
|
|
699
|
+
saved: { en: 'Saved', ar: 'تم الحفظ' },
|
|
700
|
+
updatedAgo: { en: 'Updated {time}', ar: 'تم التحديث {time}' },
|
|
701
|
+
loading: { en: 'Loading versions…', ar: 'جارٍ تحميل الإصدارات…' },
|
|
702
|
+
failed: { en: 'The versions could not be read.', ar: 'تعذرت قراءة الإصدارات.' },
|
|
703
|
+
none: { en: 'No versions yet.', ar: 'لا توجد إصدارات بعد.' },
|
|
704
|
+
updatedAt: { en: 'Updated at', ar: 'تاريخ التحديث' },
|
|
705
|
+
autosave: { en: 'Autosave', ar: 'حفظ تلقائي' },
|
|
706
|
+
currentDraft: { en: 'Current draft', ar: 'المسودة الحالية' },
|
|
707
|
+
currentlyPublished: { en: 'Currently published', ar: 'نشر حاليا' },
|
|
708
|
+
previouslyPublished: { en: 'Previously published', ar: 'نشر سابقا' },
|
|
709
|
+
compareVersions: { en: 'Compare versions', ar: 'قارن الإصدارات' },
|
|
710
|
+
comparingAgainst: { en: 'Comparing against', ar: 'مقارنة مع' },
|
|
711
|
+
currentlyViewing: { en: 'Currently viewing', ar: 'الإصدار المعروض' },
|
|
712
|
+
previousVersion: { en: 'Previous version', ar: 'النسخة السابقة' },
|
|
713
|
+
modifiedOnly: { en: 'Modified only', ar: 'تم التعديل فقط' },
|
|
714
|
+
fieldChanged: { en: 'Changed', ar: 'تغيّر' },
|
|
715
|
+
restoreAsDraft: { en: 'Restore as draft', ar: 'استعادة كمسودة' },
|
|
716
|
+
restoreThisVersion: { en: 'Restore this version', ar: 'استعادة هذا الإصدار' },
|
|
717
|
+
confirmVersionRestoration: { en: 'Confirm version restoration', ar: 'تأكيد استعادة الإصدار' },
|
|
718
|
+
aboutToRestore: {
|
|
719
|
+
en: 'You are about to restore this {label} to the state it was in on {versionDate}.',
|
|
720
|
+
ar: 'أنت على وشك استعادة هذا السجل ({label}) كما كان في {versionDate}.',
|
|
721
|
+
},
|
|
722
|
+
restore: { en: 'Restore', ar: 'استعادة' },
|
|
723
|
+
problemRestoringVersion: { en: 'There was a problem restoring this version', ar: 'حدث خطأ في استعادة هذه النّسخة' },
|
|
724
|
+
more: { en: 'Show older', ar: 'عرض الأقدم' },
|
|
725
|
+
shownCopy: { en: 'Version shown', ar: 'النسخة المعروضة' },
|
|
726
|
+
editingDraft: { en: 'You are editing a draft. The published version is different.', ar: 'أنت تحرر مسودة. النسخة المنشورة مختلفة.' },
|
|
727
|
+
viewPublished: { en: 'View published', ar: 'عرض النسخة المنشورة' },
|
|
728
|
+
readOnlyPublished: { en: 'Read only. This is the published version.', ar: 'للقراءة فقط. هذه هي النسخة المنشورة.' },
|
|
729
|
+
confirmRevertToSaved: { en: 'Confirm revert to saved', ar: 'تأكيد الرّجوع للنسخة المنشورة' },
|
|
730
|
+
aboutToRevertToPublished: {
|
|
731
|
+
en: 'You are about to revert this document\'s changes to its published state. Are you sure?',
|
|
732
|
+
ar: 'أنت على وشك إعادة هذا المستند إلى حالته المنشورة. هل أنت متأكّد؟',
|
|
733
|
+
},
|
|
734
|
+
},
|
|
735
|
+
columns: {
|
|
736
|
+
title: { en: 'Columns', ar: 'الأعمدة' },
|
|
737
|
+
customize: { en: 'Customize Columns', ar: 'تخصيص الأعمدة' },
|
|
738
|
+
shown: { en: 'Shown', ar: 'معروضة' },
|
|
739
|
+
hidden: { en: 'Not shown', ar: 'غير معروضة' },
|
|
740
|
+
up: { en: 'Move up', ar: 'نقل لأعلى' },
|
|
741
|
+
down: { en: 'Move down', ar: 'نقل لأسفل' },
|
|
742
|
+
},
|
|
743
|
+
filter: {
|
|
744
|
+
where: { en: 'Where', ar: 'حيث' },
|
|
745
|
+
join: { en: 'Join', ar: 'الرابط' },
|
|
746
|
+
and: { en: 'and', ar: 'و' },
|
|
747
|
+
or: { en: 'or', ar: 'أو' },
|
|
748
|
+
field: { en: 'Field', ar: 'الحقل' },
|
|
749
|
+
operator: { en: 'Operator', ar: 'العامل' },
|
|
750
|
+
remove: { en: 'Remove', ar: 'إزالة' },
|
|
751
|
+
add: { en: 'Add filter', ar: 'إضافة مرشح' },
|
|
752
|
+
},
|
|
753
|
+
/**
|
|
754
|
+
* One entry per operator the panel offers. `contains` and `like` must read differently
|
|
755
|
+
* in every locale: the store splits `like` on whitespace and runs one `ilike` per word.
|
|
756
|
+
*/
|
|
757
|
+
operator: {
|
|
758
|
+
contains: { en: 'contains', ar: 'يحتوي' },
|
|
759
|
+
equals: { en: 'is', ar: 'يساوي' },
|
|
760
|
+
exists: { en: 'exists', ar: 'موجود' },
|
|
761
|
+
greater_than: { en: 'is after', ar: 'بعد' },
|
|
762
|
+
greater_than_equal: { en: 'is at least', ar: 'على الأقل' },
|
|
763
|
+
in: { en: 'is one of', ar: 'واحد من' },
|
|
764
|
+
less_than: { en: 'is before', ar: 'قبل' },
|
|
765
|
+
less_than_equal: { en: 'is at most', ar: 'على الأكثر' },
|
|
766
|
+
like: { en: 'matches every word', ar: 'يطابق كل كلمة' },
|
|
767
|
+
not_equals: { en: 'is not', ar: 'لا يساوي' },
|
|
768
|
+
not_in: { en: 'is none of', ar: 'ليس واحدا من' },
|
|
769
|
+
},
|
|
770
|
+
error: {
|
|
771
|
+
'invalid.value': { en: 'That value will not do.', ar: 'هذه القيمة غير صالحة.' },
|
|
772
|
+
'invalid.fields_one': { en: 'The following field is invalid: {fields}', ar: 'الحقل التالي غير صالح: {fields}' },
|
|
773
|
+
'invalid.fields_two': { en: 'The following fields are invalid: {fields}', ar: 'الحقلان التاليان غير صالحين: {fields}' },
|
|
774
|
+
'invalid.fields_other': { en: 'The following fields are invalid: {fields}', ar: 'الحقول التالية غير صالحة: {fields}' },
|
|
775
|
+
'forbidden.create': { en: 'You may not write this.', ar: 'لا يمكنك كتابة هذا.' },
|
|
776
|
+
'forbidden.update': { en: 'You may not change this.', ar: 'لا يمكنك تغيير هذا.' },
|
|
777
|
+
'forbidden.delete': { en: 'You may not delete this.', ar: 'لا يمكنك حذف هذا.' },
|
|
778
|
+
'forbidden.read': { en: 'You may not read this.', ar: 'لا يمكنك قراءة هذا.' },
|
|
779
|
+
'forbidden.permission': { en: 'You do not hold the permission this needs.', ar: 'لا تملك الصلاحية التي يتطلبها هذا.' },
|
|
780
|
+
'forbidden.local_auth_off': {
|
|
781
|
+
en: 'Local sign-in is off on this server: LOCAL_AUTH_SECRET is not set. Set it to a secret of 32 characters at least and restart the server.',
|
|
782
|
+
ar: 'تسجيل الدخول المحلي متوقف على هذا الخادم: لم يُضبط LOCAL_AUTH_SECRET. اضبطه بسر من 32 حرفا على الأقل وأعد تشغيل الخادم.',
|
|
783
|
+
},
|
|
784
|
+
'not_found.row': { en: 'That row is no longer there.', ar: 'لم يعد هذا السجل موجودا.' },
|
|
785
|
+
'conflict.unique': { en: 'Another row already holds that value.', ar: 'يحمل سجل آخر هذه القيمة بالفعل.' },
|
|
786
|
+
'conflict.stale': { en: 'This was changed by someone else since you opened it. Reload it and make your change again.', ar: 'غيّر شخص آخر هذا منذ فتحته. أعد تحميله ثم أعد إجراء تغييرك.' },
|
|
787
|
+
'invalid.reference': { en: 'That record is not one you may choose.', ar: 'هذا السجل ليس مما يمكنك اختياره.' },
|
|
788
|
+
'invalid.tenant_reference': { en: 'That record is not one of this organization\'s.', ar: 'هذا السجل ليس من سجلات هذه المؤسسة.' },
|
|
789
|
+
'forbidden.assign': { en: 'You may not hand over a role that holds a permission you do not hold.', ar: 'لا يمكنك منح دور يحمل صلاحية لا تملكها.' },
|
|
790
|
+
'invalid.role': { en: 'That role is not one of this organization\'s.', ar: 'هذا الدور ليس من أدوار هذه المؤسسة.' },
|
|
791
|
+
'forbidden.system_role': { en: 'This role ships with the project and cannot be changed.', ar: 'هذا الدور يأتي مع المشروع ولا يمكن تغييره.' },
|
|
792
|
+
'invalid.permission_fields': { en: 'A role that holds an operation of a collection must also hold at least one of its fields, or every read of it is refused.', ar: 'الدور الذي يملك عملية على مجموعة يجب أن يملك حقلا واحدا منها على الأقل، وإلا رُفضت كل قراءة لها.' },
|
|
793
|
+
'conflict.role_held': { en: 'Members hold this role, so it is not deleted or renamed until none does.', ar: 'يشغل أعضاء هذا الدور، لذا لا يُحذف ولا يُعاد تسميته حتى لا يشغله أحد.' },
|
|
794
|
+
'conflict.role_assigned': { en: 'An assignment of this organization still names that role, so no role takes the name until it is removed.', ar: 'ما زال إسناد في هذه المؤسسة يسمي هذا الدور، لذا لا يأخذ أي دور هذا الاسم حتى يُزال.' },
|
|
795
|
+
'forbidden.own_role': { en: 'You may not take from yourself the role that lets you manage roles.', ar: 'لا يمكنك سحب الدور الذي يتيح لك إدارة الأدوار من نفسك.' },
|
|
796
|
+
'forbidden.owner_role': { en: 'The owner of the organization always holds the administrator role, so it is not taken from them.', ar: 'مالك المؤسسة يشغل دور المدير دائما، لذا لا يُسحب منه.' },
|
|
797
|
+
'invalid.member_role': { en: 'A role is named exactly, with no spaces around it.', ar: 'يُسمّى الدور بدقة، دون مسافات حوله.' },
|
|
798
|
+
'conflict.last_manager': { en: 'This would leave the organization with nobody who may manage roles. Give another member such a role first.', ar: 'سيترك هذا المؤسسة دون أي عضو يملك إدارة الأدوار. امنح عضوا آخر دورا كهذا أولا.' },
|
|
799
|
+
'invalid.draft_sessions': { en: 'A course saved as a draft makes no sessions. Publish the course, then add its sessions.', ar: 'الدورة المحفوظة كمسودة لا تُنشئ جلسات. انشر الدورة أولًا، ثم أضف جلساتها.' },
|
|
800
|
+
'invalid.upload_request': { en: 'The file has no name, or no size, that can be uploaded.', ar: 'ليس للملف اسم أو حجم يمكن رفعه.' },
|
|
801
|
+
'invalid.upload_type': { en: 'Files of this type are not taken here.', ar: 'لا تُقبل هنا ملفات من هذا النوع.' },
|
|
802
|
+
'invalid.upload_size': { en: 'The file is larger than this place takes.', ar: 'الملف أكبر مما يُقبل هنا.' },
|
|
803
|
+
'invalid.upload_reference': { en: 'The upload has expired or is not this one. Upload the file again.', ar: 'انتهت صلاحية الرفع أو أنه ليس لهذا الملف. ارفع الملف مرة أخرى.' },
|
|
804
|
+
'invalid.upload_verify': { en: 'The file is not what it said it was, so it was not kept. Upload another.', ar: 'الملف ليس كما ادّعى، لذا لم يُحفظ. ارفع ملفا آخر.' },
|
|
805
|
+
'not_found.file': { en: 'That file is not here.', ar: 'هذا الملف غير موجود.' },
|
|
806
|
+
'conflict.referenced': {
|
|
807
|
+
en: 'Something still uses this, so it is not deleted. An image stays while a course shows it. A session stays while an enrollment records a seat in it, and a person stays while one records their seat, a withdrawn one included.',
|
|
808
|
+
ar: 'ما زال شيء يستخدم هذا، لذا لا يُحذف. تبقى الصورة ما دامت دورة تعرضها. وتبقى الحصة ما دام تسجيل يحفظ مقعدا فيها، ويبقى الشخص ما دام تسجيل يحفظ مقعده، ولو كان قد انسحب.',
|
|
809
|
+
},
|
|
810
|
+
'conflict.member_holds_roles': {
|
|
811
|
+
en: 'This member still holds a role in this organization. Take each role from them first, then remove them.',
|
|
812
|
+
ar: 'ما زال هذا العضو يشغل دورا في هذه المؤسسة. اسحب منه كل دور أولا، ثم أزله.',
|
|
813
|
+
},
|
|
814
|
+
'conflict.referencedBy': { en: '{kind} still use this, so it is not deleted.', ar: 'ما زالت {kind} تستخدم هذا، لذا لا يُحذف.' },
|
|
815
|
+
},
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
// A `Map`, so a code named for a key of `Object.prototype` answers nothing. A taken organization
|
|
819
|
+
// name has no entry: names may repeat, and sign-up makes the slug unique itself.
|
|
820
|
+
const refusalKeys = new Map([
|
|
821
|
+
['INVALID_EMAIL_OR_PASSWORD', 'auth.invalidCredentials'],
|
|
822
|
+
['EMAIL_NOT_VERIFIED', 'auth.emailNotVerified'],
|
|
823
|
+
['BANNED_USER', 'auth.banned'],
|
|
824
|
+
['USER_ALREADY_EXISTS_USE_ANOTHER_EMAIL', 'auth.userExists'],
|
|
825
|
+
['INVALID_EMAIL', 'auth.invalidEmail'],
|
|
826
|
+
['INVITATION_NOT_FOUND', 'auth.invitationGone'],
|
|
827
|
+
['YOU_ARE_NOT_THE_RECIPIENT_OF_THE_INVITATION', 'auth.invitationNotYours'],
|
|
828
|
+
['INVITER_IS_NO_LONGER_A_MEMBER_OF_THE_ORGANIZATION', 'auth.invitationInviterGone'],
|
|
829
|
+
['USER_IS_ALREADY_A_MEMBER_OF_THIS_ORGANIZATION', 'dashboard.inviteAlreadyMember'],
|
|
830
|
+
['USER_IS_ALREADY_INVITED_TO_THIS_ORGANIZATION', 'dashboard.inviteAlreadyInvited'],
|
|
831
|
+
['YOU_ARE_NOT_ALLOWED_TO_INVITE_USERS_TO_THIS_ORGANIZATION', 'dashboard.inviteNotAllowed'],
|
|
832
|
+
['YOU_ARE_NOT_ALLOWED_TO_CANCEL_THIS_INVITATION', 'dashboard.inviteCancelNotAllowed'],
|
|
833
|
+
['YOU_CANNOT_LEAVE_THE_ORGANIZATION_AS_THE_ONLY_OWNER', 'dashboard.removeLastOwner'],
|
|
834
|
+
['YOU_ARE_NOT_ALLOWED_TO_DELETE_THIS_MEMBER', 'dashboard.removeNotAllowed'],
|
|
835
|
+
['RESET_PASSWORD_DISABLED', 'auth.resetDisabled'],
|
|
836
|
+
['INVALID_TOKEN', 'auth.tokenInvalid'],
|
|
837
|
+
])
|
|
838
|
+
/** The key of this app's own sentence for a provider refusal, or nothing. The provider's `message` is English on every page and is never shown. */
|
|
839
|
+
export const refusalKey = (status: number, code: unknown): string | undefined =>
|
|
840
|
+
status === 429 ? 'auth.tooManyRequests' : typeof code === 'string' ? refusalKeys.get(code) : undefined
|
|
841
|
+
|
|
842
|
+
/** The `t` a screen is handed, for one locale. A key splits at its first dot into scope and key; an unanswered key returns the caller's fallback. */
|
|
843
|
+
export const translator =
|
|
844
|
+
(which: string): Translate =>
|
|
845
|
+
(key, fallback) => {
|
|
846
|
+
const dot = key.indexOf('.')
|
|
847
|
+
if (dot < 0) return fallback
|
|
848
|
+
return scopes[key.slice(0, dot)]?.[key.slice(dot + 1)]?.[which] ?? fallback
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
/**
|
|
852
|
+
* A route's `head`: the tab names the page, then the app, or the app alone where the page
|
|
853
|
+
* names nothing. `app` is a key the root route puts in its context beside the locale.
|
|
854
|
+
*/
|
|
855
|
+
export const documentHead = ({ locale, app }: { locale: Locale; app?: string }, page?: (t: Translate) => string | undefined) => {
|
|
856
|
+
const t = translator(locale)
|
|
857
|
+
const own = app ? t(app, app)! : ''
|
|
858
|
+
const name = page?.(t)
|
|
859
|
+
return { meta: [{ title: name && own ? `${name} · ${own}` : name || own }] }
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
/**
|
|
863
|
+
* Sets the cookie the request middleware reads, then reloads so the server draws the document
|
|
864
|
+
* in it. The unsaved-changes guard is dropped because the shell already asked in its own dialog.
|
|
865
|
+
*/
|
|
866
|
+
export const switchLocale = ({ to }: { to: string }): void => {
|
|
867
|
+
window.onbeforeunload = null
|
|
868
|
+
document.cookie = localeCookieValue(localeOf(to))
|
|
869
|
+
window.location.reload()
|
|
870
|
+
}
|