@liorian/sdk 0.28.0-alpha.56010ca
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/README.md +483 -0
- package/package.json +94 -0
- package/schemas/module.schema.json +818 -0
- package/src/application/index.ts +3 -0
- package/src/application/module-instance.ts +36 -0
- package/src/application/service/auth-api-service.ts +291 -0
- package/src/application/service/auth-user.service.ts +108 -0
- package/src/application/service/index.ts +12 -0
- package/src/application/service/module-activation-api.service.ts +105 -0
- package/src/application/service/notifications-api-service.ts +38 -0
- package/src/application/service/notifications-push.service.ts +299 -0
- package/src/application/service/notifications-socket-service.ts +76 -0
- package/src/application/service/organizations-api-service.ts +104 -0
- package/src/application/service/otp-api-service.ts +11 -0
- package/src/application/service/storage-api-service.ts +77 -0
- package/src/application/service/storefront-api.service.ts +72 -0
- package/src/application/service/user-preferences-api.service.ts +57 -0
- package/src/domain/config/app.config.ts +35 -0
- package/src/domain/config/auth.config.ts +30 -0
- package/src/domain/config/index.ts +4 -0
- package/src/domain/config/logo.config.ts +17 -0
- package/src/domain/entities/activities.interface.ts +18 -0
- package/src/domain/entities/catalog.interface.ts +96 -0
- package/src/domain/entities/index.ts +13 -0
- package/src/domain/entities/media.ts +22 -0
- package/src/domain/entities/module-activation.interface.ts +173 -0
- package/src/domain/entities/module.interface.ts +101 -0
- package/src/domain/entities/notification.interface.ts +23 -0
- package/src/domain/entities/objectable.type.ts +3 -0
- package/src/domain/entities/organization.interface.ts +81 -0
- package/src/domain/entities/user-auth.interface.ts +17 -0
- package/src/domain/entities/user-phone.interface.ts +11 -0
- package/src/domain/entities/user-profile.interface.ts +23 -0
- package/src/domain/entities/user.interface.ts +79 -0
- package/src/domain/enums/coloring.enum.ts +6 -0
- package/src/domain/enums/domains.enum.ts +282 -0
- package/src/domain/enums/index.ts +8 -0
- package/src/domain/enums/module-category.enum.ts +57 -0
- package/src/domain/enums/module.enum.ts +97 -0
- package/src/domain/enums/routine.enum.ts +12 -0
- package/src/domain/enums/user-profile.enum.ts +25 -0
- package/src/domain/enums/user-status.enum.ts +7 -0
- package/src/domain/index.ts +6 -0
- package/src/domain/typing/auth-caches.ts +12 -0
- package/src/domain/typing/auth-oauth.types.ts +172 -0
- package/src/domain/typing/devise.ts +2 -0
- package/src/domain/typing/index.ts +10 -0
- package/src/domain/typing/response.ts +30 -0
- package/src/domain/typing/routine.types.ts +113 -0
- package/src/domain/typing/session.interface.ts +28 -0
- package/src/domain/typing/statisticals.ts +11 -0
- package/src/domain/typing/user-media-upload.ts +9 -0
- package/src/domain/typing/values.ts +6 -0
- package/src/index.tsx +168 -0
- package/src/infrastructure/capabilities/cache-storage/capability.ts +129 -0
- package/src/infrastructure/capabilities/cache-storage/enum.ts +5 -0
- package/src/infrastructure/capabilities/cache-storage/index.ts +4 -0
- package/src/infrastructure/capabilities/cache-storage/types.ts +13 -0
- package/src/infrastructure/capabilities/index.ts +3 -0
- package/src/infrastructure/capabilities/stackable/capability.ts +55 -0
- package/src/infrastructure/capabilities/stackable/index.ts +3 -0
- package/src/infrastructure/capabilities/stackable/types.ts +24 -0
- package/src/infrastructure/common-classname.constant.ts +4 -0
- package/src/infrastructure/data/countries.ts +208 -0
- package/src/infrastructure/data/gender.ts +5 -0
- package/src/infrastructure/data/index.ts +3 -0
- package/src/infrastructure/dataset/index.ts +3 -0
- package/src/infrastructure/dataset/sign-in.dataset.ts +21 -0
- package/src/infrastructure/dataset/sign-up.dataset.ts +64 -0
- package/src/infrastructure/hooks/index.ts +10 -0
- package/src/infrastructure/hooks/use-activity-lock-draft.ts +69 -0
- package/src/infrastructure/hooks/use-auth.ts +24 -0
- package/src/infrastructure/hooks/use-elastic-interaction.ts +180 -0
- package/src/infrastructure/hooks/use-is-desktop.ts +25 -0
- package/src/infrastructure/hooks/use-is-tauri.ts +17 -0
- package/src/infrastructure/hooks/use-mobile.ts +19 -0
- package/src/infrastructure/hooks/use-notifications.ts +128 -0
- package/src/infrastructure/hooks/use-recent-colors.ts +113 -0
- package/src/infrastructure/hooks/use-recent-modules.ts +76 -0
- package/src/infrastructure/index.tsx +11 -0
- package/src/infrastructure/library/design-system.ts +95 -0
- package/src/infrastructure/library/index.tsx +5 -0
- package/src/infrastructure/library/motion-utils.ts +77 -0
- package/src/infrastructure/library/motion.tsx +31 -0
- package/src/infrastructure/library/scroll-progress.tsx +93 -0
- package/src/infrastructure/providers/auth-guard.provider.tsx +47 -0
- package/src/infrastructure/providers/auth.provider.tsx +168 -0
- package/src/infrastructure/providers/index.tsx +8 -0
- package/src/infrastructure/providers/module-usage.provider.tsx +95 -0
- package/src/infrastructure/providers/modules-guard.provider.tsx +64 -0
- package/src/infrastructure/providers/modules-routines.provider.tsx +33 -0
- package/src/infrastructure/providers/modules-switcher.provider.tsx +25 -0
- package/src/infrastructure/providers/query.provider.tsx +27 -0
- package/src/infrastructure/routines/__tests__/routine.test.ts +368 -0
- package/src/infrastructure/routines/index.tsx +3 -0
- package/src/infrastructure/routines/routine.hook.ts +121 -0
- package/src/infrastructure/routines/routine.ts +283 -0
- package/src/infrastructure/routines/routine.tsx +283 -0
- package/src/infrastructure/stores/activity-lock.store.ts +22 -0
- package/src/infrastructure/stores/auth-user-connected.store.ts +24 -0
- package/src/infrastructure/stores/dataset.store.ts +106 -0
- package/src/infrastructure/stores/index.ts +6 -0
- package/src/infrastructure/stores/module.store.ts +266 -0
- package/src/infrastructure/stores/upload.store.ts +198 -0
- package/src/infrastructure/utilities/access-label.util.ts +158 -0
- package/src/infrastructure/utilities/activities.util.tsx +54 -0
- package/src/infrastructure/utilities/activity-lock.service.ts +263 -0
- package/src/infrastructure/utilities/activity-tracker.service.ts +205 -0
- package/src/infrastructure/utilities/api-service.ts +237 -0
- package/src/infrastructure/utilities/auth-logout.util.ts +23 -0
- package/src/infrastructure/utilities/classname.util.ts +7 -0
- package/src/infrastructure/utilities/encryption.service.ts +125 -0
- package/src/infrastructure/utilities/form-snapshot.service.ts +304 -0
- package/src/infrastructure/utilities/format.util.ts +40 -0
- package/src/infrastructure/utilities/index.tsx +23 -0
- package/src/infrastructure/utilities/media-label.service.ts +47 -0
- package/src/infrastructure/utilities/modules.ts +11 -0
- package/src/infrastructure/utilities/permission.util.ts +22 -0
- package/src/infrastructure/utilities/push-permission.util.ts +43 -0
- package/src/infrastructure/utilities/route-access.ts +38 -0
- package/src/infrastructure/utilities/socket-service.ts +123 -0
- package/src/infrastructure/utilities/sso-auth.util.ts +188 -0
- package/src/infrastructure/utilities/stringable.util.ts +16 -0
- package/src/infrastructure/utilities/strings.util.ts +18 -0
- package/src/infrastructure/utilities/tauri.util.ts +15 -0
- package/src/infrastructure/utilities/utils.ts +6 -0
- package/src/infrastructure/utilities/values.ts +5 -0
- package/src/presentation/8starlabs-ui/button.tsx +94 -0
- package/src/presentation/8starlabs-ui/flip-clock.tsx +368 -0
- package/src/presentation/8starlabs-ui/heatmap.tsx +430 -0
- package/src/presentation/8starlabs-ui/hooks/index.tsx +2 -0
- package/src/presentation/8starlabs-ui/hooks/use-mobile.ts +21 -0
- package/src/presentation/8starlabs-ui/index.tsx +20 -0
- package/src/presentation/8starlabs-ui/json-viewer.tsx +972 -0
- package/src/presentation/8starlabs-ui/marquee.tsx +134 -0
- package/src/presentation/8starlabs-ui/partition-bar.tsx +198 -0
- package/src/presentation/8starlabs-ui/scroll-fade.tsx +158 -0
- package/src/presentation/8starlabs-ui/status-indicator.tsx +86 -0
- package/src/presentation/8starlabs-ui/system-banner.tsx +50 -0
- package/src/presentation/8starlabs-ui/timeline.tsx +576 -0
- package/src/presentation/8starlabs-ui/transport-badge.tsx +249 -0
- package/src/presentation/8starlabs-ui/ui/copy-button.tsx +60 -0
- package/src/presentation/8starlabs-ui/ui/index.tsx +2 -0
- package/src/presentation/analytics-section.tsx +85 -0
- package/src/presentation/app-sidebar.tsx +234 -0
- package/src/presentation/charts/area-widget.chart-skeleton.tsx +61 -0
- package/src/presentation/charts/area-widget.chart.tsx +128 -0
- package/src/presentation/charts/chart-widgets.types.ts +81 -0
- package/src/presentation/charts/index.tsx +16 -0
- package/src/presentation/charts/line-widget.chart-skeleton.tsx +64 -0
- package/src/presentation/charts/line-widget.chart.tsx +105 -0
- package/src/presentation/charts/pie-widget.chart-skeleton.tsx +56 -0
- package/src/presentation/charts/pie-widget.chart.tsx +168 -0
- package/src/presentation/charts/radar-widget.chart-skeleton.tsx +67 -0
- package/src/presentation/charts/radar-widget.chart.tsx +80 -0
- package/src/presentation/charts/radial-stacked-widget.chart-skeleton.tsx +66 -0
- package/src/presentation/charts/radial-stacked-widget.chart.tsx +120 -0
- package/src/presentation/charts/radial-widget.chart-skeleton.tsx +61 -0
- package/src/presentation/charts/radial-widget.chart.tsx +87 -0
- package/src/presentation/charts/tooltip-widget.chart-skeleton.tsx +64 -0
- package/src/presentation/charts/tooltip-widget.chart.tsx +89 -0
- package/src/presentation/components/activity-actions.tsx +20 -0
- package/src/presentation/components/activity-container.tsx +55 -0
- package/src/presentation/components/activity-content.tsx +20 -0
- package/src/presentation/components/activity-descriptor-parser.tsx +37 -0
- package/src/presentation/components/activity-header.tsx +20 -0
- package/src/presentation/components/activity-loader.tsx +19 -0
- package/src/presentation/components/activity-title.tsx +32 -0
- package/src/presentation/components/activity.tsx +22 -0
- package/src/presentation/components/auth/index.tsx +4 -0
- package/src/presentation/components/auth/sso-callback.view.tsx +44 -0
- package/src/presentation/components/auth/sso-disconnect.view.tsx +41 -0
- package/src/presentation/components/auth/sso-sign-in.view.tsx +29 -0
- package/src/presentation/components/auth-lock-screen.tsx +309 -0
- package/src/presentation/components/auth-session.view.tsx +17 -0
- package/src/presentation/components/data-table.tsx +814 -0
- package/src/presentation/components/dynamic-icon.tsx +16 -0
- package/src/presentation/components/floating-upload.tsx +291 -0
- package/src/presentation/components/index.tsx +40 -0
- package/src/presentation/components/local-time.tsx +170 -0
- package/src/presentation/components/markdown-parser.tsx +201 -0
- package/src/presentation/components/message-scroller.tsx +131 -0
- package/src/presentation/components/module-first-access-config.view.tsx +181 -0
- package/src/presentation/components/module-first-access-pending.view.tsx +38 -0
- package/src/presentation/components/module-guard.tsx +34 -0
- package/src/presentation/components/modules-first-access.guard.tsx +88 -0
- package/src/presentation/components/modules-guard-forbidden.tsx +46 -0
- package/src/presentation/components/notification-details.modal.tsx +145 -0
- package/src/presentation/components/notification-item.tsx +127 -0
- package/src/presentation/components/notifications-popover.tsx +128 -0
- package/src/presentation/components/push-notifications.provider.tsx +65 -0
- package/src/presentation/components/upload-progress-dialog.tsx +140 -0
- package/src/presentation/components/waiting-bar.tsx +22 -0
- package/src/presentation/components/waiting-section.tsx +15 -0
- package/src/presentation/components/waiting.tsx +14 -0
- package/src/presentation/data-grid/data-grid-empty.tsx +24 -0
- package/src/presentation/data-grid/data-grid-search-engine.tsx +32 -0
- package/src/presentation/data-grid/data-grid.tsx +892 -0
- package/src/presentation/data-grid/index.tsx +4 -0
- package/src/presentation/form-screen.tsx +95 -0
- package/src/presentation/icons/custom.tsx +20 -0
- package/src/presentation/icons/glyphIcons.tsx +53 -0
- package/src/presentation/icons/icons.enum.ts +4 -0
- package/src/presentation/icons/icons.util.ts +6 -0
- package/src/presentation/icons/index.tsx +8 -0
- package/src/presentation/icons/lucide.tsx +17 -0
- package/src/presentation/icons/remix.tsx +33 -0
- package/src/presentation/icons/types.ts +27 -0
- package/src/presentation/index.tsx +45 -0
- package/src/presentation/modals/components/ModalBox.tsx +74 -0
- package/src/presentation/modals/components/ModalPortal.tsx +31 -0
- package/src/presentation/modals/components/ModalStepper.tsx +319 -0
- package/src/presentation/modals/components/ModalWrapper.tsx +65 -0
- package/src/presentation/modals/components/index.tsx +5 -0
- package/src/presentation/modals/hooks/index.ts +2 -0
- package/src/presentation/modals/hooks/useModal.ts +38 -0
- package/src/presentation/modals/index.tsx +5 -0
- package/src/presentation/modals/stores/index.ts +2 -0
- package/src/presentation/modals/stores/useModalStore.ts +90 -0
- package/src/presentation/modals/types/index.ts +2 -0
- package/src/presentation/modals/types/modal.type.ts +33 -0
- package/src/presentation/module-menubar.tsx +300 -0
- package/src/presentation/module-widget.tsx +233 -0
- package/src/presentation/nav-documents.tsx +89 -0
- package/src/presentation/nav-main.tsx +62 -0
- package/src/presentation/nav-secondary.tsx +41 -0
- package/src/presentation/nav-user.tsx +109 -0
- package/src/presentation/permission-action-badge.tsx +35 -0
- package/src/presentation/reui/index.tsx +3 -0
- package/src/presentation/reui/stepper.tsx +508 -0
- package/src/presentation/reui/timeline.tsx +226 -0
- package/src/presentation/sheets/index.tsx +2 -0
- package/src/presentation/sheets/legacy-sheet-header.tsx +0 -0
- package/src/presentation/sheets/legacy-sheet.tsx +37 -0
- package/src/presentation/size.enum.ts +19 -0
- package/src/presentation/system/index.tsx +3 -0
- package/src/presentation/system/logo.theme.tsx +21 -0
- package/src/presentation/system/types.ts +10 -0
- package/src/presentation/theme/index.tsx +6 -0
- package/src/presentation/theme/prefer-color-scheme.tsx +50 -0
- package/src/presentation/theme/switch-color-scheme.tsx +16 -0
- package/src/presentation/theme/theme-switcher-button.tsx +20 -0
- package/src/presentation/theme/theme.enum.ts +4 -0
- package/src/presentation/theme/theme.store.ts +87 -0
- package/src/presentation/themes/index.tsx +2 -0
- package/src/presentation/themes/katon/dashboard-layout.tsx +1080 -0
- package/src/presentation/themes/katon/edge-section.tsx +19 -0
- package/src/presentation/themes/katon/header-menubar.tsx +270 -0
- package/src/presentation/themes/katon/header-modules-available.tsx +44 -0
- package/src/presentation/themes/katon/header-modules-recents.tsx +52 -0
- package/src/presentation/themes/katon/header-modules-store.tsx +25 -0
- package/src/presentation/themes/katon/header-options.tsx +13 -0
- package/src/presentation/themes/katon/header-organization-select.tsx +146 -0
- package/src/presentation/themes/katon/header-routines.tsx +74 -0
- package/src/presentation/themes/katon/header-tasks-connected-user.tsx +150 -0
- package/src/presentation/themes/katon/index.tsx +16 -0
- package/src/presentation/themes/katon/main-wrapper.tsx +34 -0
- package/src/presentation/themes/katon/module-item-link.tsx +32 -0
- package/src/presentation/themes/katon/view-frame.tsx +25 -0
- package/src/presentation/themes/katon/view-helmet.tsx +53 -0
- package/src/presentation/themes/katon/view-status.tsx +32 -0
- package/src/presentation/themes/katon/view-wrapper.tsx +15 -0
- package/src/presentation/themes/katon/view.tsx +42 -0
- package/src/presentation/ui/accordion-multiselect.tsx +206 -0
- package/src/presentation/ui/accordion.tsx +81 -0
- package/src/presentation/ui/alert-dialog.tsx +199 -0
- package/src/presentation/ui/alert.tsx +76 -0
- package/src/presentation/ui/aspect-ratio.tsx +11 -0
- package/src/presentation/ui/attachment.tsx +204 -0
- package/src/presentation/ui/avatar.tsx +112 -0
- package/src/presentation/ui/badge.tsx +49 -0
- package/src/presentation/ui/breadcrumb.tsx +122 -0
- package/src/presentation/ui/bubble.tsx +125 -0
- package/src/presentation/ui/button-group.tsx +83 -0
- package/src/presentation/ui/button.tsx +87 -0
- package/src/presentation/ui/calendar.tsx +222 -0
- package/src/presentation/ui/card.tsx +106 -0
- package/src/presentation/ui/carousel.tsx +242 -0
- package/src/presentation/ui/chart.tsx +373 -0
- package/src/presentation/ui/checkbox.tsx +33 -0
- package/src/presentation/ui/clickable.tsx +58 -0
- package/src/presentation/ui/collapsible.tsx +33 -0
- package/src/presentation/ui/color-swatch-selector.tsx +81 -0
- package/src/presentation/ui/combobox.tsx +299 -0
- package/src/presentation/ui/command.tsx +195 -0
- package/src/presentation/ui/context-menu.tsx +263 -0
- package/src/presentation/ui/dialog.tsx +168 -0
- package/src/presentation/ui/direction.tsx +22 -0
- package/src/presentation/ui/drawer.tsx +134 -0
- package/src/presentation/ui/dropdown-menu.tsx +269 -0
- package/src/presentation/ui/empty.tsx +104 -0
- package/src/presentation/ui/field.tsx +238 -0
- package/src/presentation/ui/granularity-selector.tsx +58 -0
- package/src/presentation/ui/hover-card.tsx +44 -0
- package/src/presentation/ui/index.tsx +74 -0
- package/src/presentation/ui/input-group.tsx +156 -0
- package/src/presentation/ui/input-otp.tsx +87 -0
- package/src/presentation/ui/input.tsx +19 -0
- package/src/presentation/ui/item.tsx +196 -0
- package/src/presentation/ui/kpi-card.tsx +203 -0
- package/src/presentation/ui/label-selector.tsx +100 -0
- package/src/presentation/ui/label.tsx +24 -0
- package/src/presentation/ui/legacy-birth-date-input.tsx +43 -0
- package/src/presentation/ui/legacy-color-picker/index.tsx +42 -0
- package/src/presentation/ui/legacy-color-picker/legacy-color-picker.content.tsx +37 -0
- package/src/presentation/ui/legacy-color-picker/legacy-color-picker.context.tsx +42 -0
- package/src/presentation/ui/legacy-color-picker/legacy-color-picker.hex-input.tsx +97 -0
- package/src/presentation/ui/legacy-color-picker/legacy-color-picker.picker.tsx +266 -0
- package/src/presentation/ui/legacy-color-picker/legacy-color-picker.presets.ts +22 -0
- package/src/presentation/ui/legacy-color-picker/legacy-color-picker.quick-list.tsx +49 -0
- package/src/presentation/ui/legacy-color-picker/legacy-color-picker.recent.tsx +43 -0
- package/src/presentation/ui/legacy-color-picker/legacy-color-picker.swatches.tsx +111 -0
- package/src/presentation/ui/legacy-color-picker/legacy-color-picker.trigger.tsx +128 -0
- package/src/presentation/ui/legacy-color-picker/legacy-color-picker.tsx +110 -0
- package/src/presentation/ui/legacy-color-picker/legacy-color-picker.types.ts +1 -0
- package/src/presentation/ui/legacy-color-picker/legacy-color-picker.utils.ts +114 -0
- package/src/presentation/ui/legacy-country-input.tsx +171 -0
- package/src/presentation/ui/legacy-gender-input.tsx +22 -0
- package/src/presentation/ui/legacy-input.tsx +106 -0
- package/src/presentation/ui/legacy-phone-input.tsx +213 -0
- package/src/presentation/ui/legacy-select-input.tsx +114 -0
- package/src/presentation/ui/legacy-text-area.tsx +111 -0
- package/src/presentation/ui/list-items.tsx +59 -0
- package/src/presentation/ui/marker.tsx +69 -0
- package/src/presentation/ui/media-player/index.tsx +12 -0
- package/src/presentation/ui/media-player/media-player.context.tsx +36 -0
- package/src/presentation/ui/media-player/media-player.tsx +167 -0
- package/src/presentation/ui/media-player/player-controls.tsx +207 -0
- package/src/presentation/ui/media-player/players/audio-player.tsx +78 -0
- package/src/presentation/ui/media-player/players/index.tsx +4 -0
- package/src/presentation/ui/media-player/players/video-player.tsx +193 -0
- package/src/presentation/ui/media-player/players/voice-note-player.tsx +108 -0
- package/src/presentation/ui/media-player/use-media-player.hook.ts +263 -0
- package/src/presentation/ui/menubar.tsx +281 -0
- package/src/presentation/ui/message.tsx +92 -0
- package/src/presentation/ui/navigation-menu.tsx +172 -0
- package/src/presentation/ui/pagination.tsx +129 -0
- package/src/presentation/ui/popover.tsx +89 -0
- package/src/presentation/ui/progress.tsx +31 -0
- package/src/presentation/ui/resizable.tsx +50 -0
- package/src/presentation/ui/select.tsx +192 -0
- package/src/presentation/ui/separator.tsx +28 -0
- package/src/presentation/ui/sheet.tsx +147 -0
- package/src/presentation/ui/sidebar.tsx +702 -0
- package/src/presentation/ui/skeleton.tsx +13 -0
- package/src/presentation/ui/slide-to-confirm.tsx +129 -0
- package/src/presentation/ui/slider.tsx +59 -0
- package/src/presentation/ui/sonner.tsx +58 -0
- package/src/presentation/ui/switch.tsx +33 -0
- package/src/presentation/ui/table.tsx +116 -0
- package/src/presentation/ui/tabs.tsx +90 -0
- package/src/presentation/ui/text-gradient.tsx +84 -0
- package/src/presentation/ui/textarea.tsx +18 -0
- package/src/presentation/ui/timeline-steps.tsx +235 -0
- package/src/presentation/ui/toggle-group.tsx +89 -0
- package/src/presentation/ui/toggle.tsx +47 -0
- package/src/presentation/ui/tooltip.tsx +57 -0
- package/src/presentation/uploading/index.tsx +3 -0
- package/src/presentation/uploading/media-upload-field.tsx +152 -0
- package/src/presentation/uploading/storage-media.tsx +210 -0
- package/src/styles.css +403 -0
- package/src/themes.css +1038 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import {MarkdownParser} from "./markdown-parser";
|
|
4
|
+
import {getNestedValue} from "../../infrastructure/utilities/values";
|
|
5
|
+
import {authUserConnectedStore} from "../../infrastructure/stores/auth-user-connected.store";
|
|
6
|
+
|
|
7
|
+
export interface ActivityDescriptorParserProps {
|
|
8
|
+
template: string;
|
|
9
|
+
context: Record<string, any>;
|
|
10
|
+
className?: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function ActivityDescriptorParser({template, context, className}: ActivityDescriptorParserProps) {
|
|
14
|
+
const connectedUser = authUserConnectedStore(state => state.getCurrentUser);
|
|
15
|
+
|
|
16
|
+
const fullContext: Record<string, any> = {
|
|
17
|
+
...connectedUser,
|
|
18
|
+
...context,
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
let result = template;
|
|
22
|
+
|
|
23
|
+
const placeholderRegex = /\[([^\]]+)\](?!\()/g;
|
|
24
|
+
let match;
|
|
25
|
+
|
|
26
|
+
while ((match = placeholderRegex.exec(template)) !== null) {
|
|
27
|
+
const placeholder = match[0];
|
|
28
|
+
const path = match[1];
|
|
29
|
+
|
|
30
|
+
const value = getNestedValue(fullContext, path);
|
|
31
|
+
const stringValue = value !== null && value !== undefined ? `**${value}**` : '';
|
|
32
|
+
|
|
33
|
+
result = result.replace(new RegExp(placeholder.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'g'), stringValue);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return <MarkdownParser text={result} className={className}/>;
|
|
37
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import { ReactNode } from "react"
|
|
4
|
+
import { cn } from "../../infrastructure/utilities/utils"
|
|
5
|
+
|
|
6
|
+
export interface ActivityHeaderProps {
|
|
7
|
+
children: ReactNode
|
|
8
|
+
className?: string
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function ActivityHeader({ children, className }: ActivityHeaderProps) {
|
|
12
|
+
return (
|
|
13
|
+
<div
|
|
14
|
+
data-slot="activity-header"
|
|
15
|
+
className={cn("flex flex-row items-center justify-between gap-3", className)}
|
|
16
|
+
>
|
|
17
|
+
{children}
|
|
18
|
+
</div>
|
|
19
|
+
)
|
|
20
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Motion } from "../../infrastructure/library/motion"
|
|
2
|
+
import { elasticPulse } from "../../infrastructure/library/motion-utils"
|
|
3
|
+
import {LoaderIcon} from "lucide-react"
|
|
4
|
+
import {cn} from "../../infrastructure/utilities/utils"
|
|
5
|
+
|
|
6
|
+
export interface ActivityLoaderProps {
|
|
7
|
+
size?: number
|
|
8
|
+
className?: string
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function ActivityLoader({size = 24, className}: ActivityLoaderProps){
|
|
12
|
+
return (
|
|
13
|
+
<div className={cn("flex-auto flex flex-col items-center justify-center", className)}>
|
|
14
|
+
<Motion animation={elasticPulse()}>
|
|
15
|
+
<LoaderIcon size={size} className={"animate-spin"} />
|
|
16
|
+
</Motion>
|
|
17
|
+
</div>
|
|
18
|
+
)
|
|
19
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import { ReactNode } from "react"
|
|
4
|
+
import { cn } from "../../infrastructure/utilities/utils"
|
|
5
|
+
|
|
6
|
+
export interface ActivityTitleProps {
|
|
7
|
+
label: ReactNode
|
|
8
|
+
description?: ReactNode
|
|
9
|
+
icon?: ReactNode
|
|
10
|
+
className?: string
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function ActivityTitle({ label, description, icon, className }: ActivityTitleProps) {
|
|
14
|
+
return (
|
|
15
|
+
<div
|
|
16
|
+
data-slot="activity-title"
|
|
17
|
+
className={cn("flex items-center gap-3 min-w-0", className)}
|
|
18
|
+
>
|
|
19
|
+
{icon && (
|
|
20
|
+
<span className="flex size-10 shrink-0 items-center justify-center rounded-xl bg-primary/10 text-primary">
|
|
21
|
+
{icon}
|
|
22
|
+
</span>
|
|
23
|
+
)}
|
|
24
|
+
<div className="flex flex-col flex-auto min-w-0 overflow-hidden">
|
|
25
|
+
<h1 className="text-2xl font-bold truncate text-ellipsis">{label}</h1>
|
|
26
|
+
{description && (
|
|
27
|
+
<p className="text-sm text-muted-foreground">{description}</p>
|
|
28
|
+
)}
|
|
29
|
+
</div>
|
|
30
|
+
</div>
|
|
31
|
+
)
|
|
32
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import {ActivityContainer} from "./activity-container"
|
|
2
|
+
import {ActivityLoader} from "./activity-loader"
|
|
3
|
+
import {ActivityContent} from "./activity-content"
|
|
4
|
+
import {ActivityHeader} from "./activity-header"
|
|
5
|
+
import {ActivityTitle} from "./activity-title"
|
|
6
|
+
import {ActivityActions} from "./activity-actions"
|
|
7
|
+
|
|
8
|
+
export const Activity = {
|
|
9
|
+
Container: ActivityContainer,
|
|
10
|
+
Content: ActivityContent,
|
|
11
|
+
Header: ActivityHeader,
|
|
12
|
+
Title: ActivityTitle,
|
|
13
|
+
Actions: ActivityActions,
|
|
14
|
+
Loader: ActivityLoader,
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export type {ActivityContainerProps} from "./activity-container"
|
|
18
|
+
export type {ActivityLoaderProps} from "./activity-loader"
|
|
19
|
+
export type {ActivityContentProps} from "./activity-content"
|
|
20
|
+
export type {ActivityHeaderProps} from "./activity-header"
|
|
21
|
+
export type {ActivityTitleProps} from "./activity-title"
|
|
22
|
+
export type {ActivityActionsProps} from "./activity-actions"
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import {useEffect, useRef} from "react";
|
|
4
|
+
import {useRouter} from "next/navigation";
|
|
5
|
+
import {handleSsoCallback, isSsoCallbackInPopup} from "../../../infrastructure/utilities/sso-auth.util";
|
|
6
|
+
import {Activity} from "../activity";
|
|
7
|
+
|
|
8
|
+
export interface SsoCallbackViewProps {
|
|
9
|
+
/** Destination après une authentification réussie (mode redirection complète). */
|
|
10
|
+
successRedirect?: string
|
|
11
|
+
/** Destination en cas d'échec de l'échange du code d'autorisation. */
|
|
12
|
+
errorRedirect?: string
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Écran de rappel SSO : échange le code d'autorisation contre une session puis
|
|
17
|
+
* redirige. En mode popup, le résultat est renvoyé à l'onglet d'origine via
|
|
18
|
+
* `postMessage` et le popup est refermé.
|
|
19
|
+
*/
|
|
20
|
+
export function SsoCallbackView({successRedirect = '/', errorRedirect = '/auth/sign-in'}: SsoCallbackViewProps) {
|
|
21
|
+
const router = useRouter();
|
|
22
|
+
const done = useRef(false);
|
|
23
|
+
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
if (done.current) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
done.current = true;
|
|
29
|
+
handleSsoCallback()
|
|
30
|
+
.then(() => {
|
|
31
|
+
if (!isSsoCallbackInPopup()) router.replace(successRedirect);
|
|
32
|
+
})
|
|
33
|
+
.catch(() => {
|
|
34
|
+
if (!isSsoCallbackInPopup()) router.replace(errorRedirect);
|
|
35
|
+
});
|
|
36
|
+
}, [router, successRedirect, errorRedirect]);
|
|
37
|
+
|
|
38
|
+
return (
|
|
39
|
+
<div className="flex min-h-svh flex-col items-center justify-center gap-4 bg-background">
|
|
40
|
+
<Activity.Loader size={24}/>
|
|
41
|
+
<p className="text-sm text-muted-foreground">Finalisation de la connexion…</p>
|
|
42
|
+
</div>
|
|
43
|
+
);
|
|
44
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import {UnplugIcon} from "lucide-react";
|
|
4
|
+
import {useEffect} from "react";
|
|
5
|
+
import {useRouter} from "next/navigation";
|
|
6
|
+
import {AuthConfig} from "../../../domain/config/auth.config";
|
|
7
|
+
|
|
8
|
+
export interface SsoDisconnectViewProps {
|
|
9
|
+
/** Délai avant redirection automatique vers la page de connexion (ms). */
|
|
10
|
+
redirectAfterMs?: number
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Écran de déconnexion : confirme la fin de session puis redirige vers la
|
|
15
|
+
* connexion SSO après quelques secondes.
|
|
16
|
+
*/
|
|
17
|
+
export function SsoDisconnectView({redirectAfterMs = 3000}: SsoDisconnectViewProps) {
|
|
18
|
+
const router = useRouter();
|
|
19
|
+
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
const timeout = setTimeout(() => {
|
|
22
|
+
router.replace(AuthConfig.routes.login)
|
|
23
|
+
router.refresh()
|
|
24
|
+
}, redirectAfterMs);
|
|
25
|
+
return () => clearTimeout(timeout);
|
|
26
|
+
}, [router, redirectAfterMs]);
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<div className="flex min-h-svh flex-col items-center justify-center gap-6 bg-background p-6 md:p-10">
|
|
30
|
+
<div className="w-full max-w-xl flex flex-col items-start md:flex-row md:items-center gap-6">
|
|
31
|
+
<div className="">
|
|
32
|
+
<UnplugIcon className={"w-16 h-16 text-primary"}/>
|
|
33
|
+
</div>
|
|
34
|
+
<div className="">
|
|
35
|
+
<h1>Vous êtes maintenant déconnecté</h1>
|
|
36
|
+
<p>Redirection vers la page d'accueil dans quelques secondes...</p>
|
|
37
|
+
</div>
|
|
38
|
+
</div>
|
|
39
|
+
</div>
|
|
40
|
+
)
|
|
41
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import {useEffect} from "react";
|
|
4
|
+
import {startSsoLogin} from "../../../infrastructure/utilities/sso-auth.util";
|
|
5
|
+
import {Activity} from "../activity";
|
|
6
|
+
|
|
7
|
+
export interface SsoSignInViewProps {
|
|
8
|
+
/** Destination si le SSO ne peut pas être démarré (popup/redirection bloquée). */
|
|
9
|
+
fallbackRedirect?: string
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Écran de connexion SSO : redirige vers Liorian Auth (flux Authorization Code
|
|
14
|
+
* + PKCE) dès le montage. Réutilisable par toutes les applications consommatrices.
|
|
15
|
+
*/
|
|
16
|
+
export function SsoSignInView({fallbackRedirect = '/auth/sign-up'}: SsoSignInViewProps) {
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
startSsoLogin().catch(() => {
|
|
19
|
+
window.location.assign(fallbackRedirect);
|
|
20
|
+
});
|
|
21
|
+
}, [fallbackRedirect]);
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<div className="flex min-h-svh flex-col items-center justify-center gap-4 bg-background">
|
|
25
|
+
<Activity.Loader size={24}/>
|
|
26
|
+
<p className="text-sm text-muted-foreground">Connexion…</p>
|
|
27
|
+
</div>
|
|
28
|
+
);
|
|
29
|
+
}
|
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import * as React from "react"
|
|
4
|
+
import {useEffect, useMemo, useState} from "react"
|
|
5
|
+
import {Eye, EyeOff, FingerprintIcon, KeyRoundIcon, LockKeyholeIcon} from "lucide-react"
|
|
6
|
+
import {AppConfig} from "../../domain/config/app.config"
|
|
7
|
+
import {AuthUserService} from "../../application/service/auth-user.service"
|
|
8
|
+
import {AuthApiService, webauthnBytes} from "../../application/service/auth-api-service"
|
|
9
|
+
import {ActivityLockService} from "../../infrastructure/utilities/activity-lock.service"
|
|
10
|
+
import {startSsoLogin, startSsoLoginPopup, SSO_CALLBACK_MESSAGE} from "../../infrastructure/utilities/sso-auth.util"
|
|
11
|
+
import {Avatar, AvatarFallback} from "../ui/avatar"
|
|
12
|
+
import {Button} from "../ui/button"
|
|
13
|
+
import {Input} from "../ui/input"
|
|
14
|
+
import {Label} from "../ui/label"
|
|
15
|
+
import {StorageMedia} from "../uploading/storage-media"
|
|
16
|
+
import {View} from "../themes/katon/view"
|
|
17
|
+
import {cn} from "../../infrastructure/utilities/utils"
|
|
18
|
+
import type {UserInterface} from "../../domain/entities/user.interface"
|
|
19
|
+
import {Activity} from "./activity";
|
|
20
|
+
import {ThemeLogo} from "../system/logo.theme";
|
|
21
|
+
import {LegacyInput} from "../ui/legacy-input";
|
|
22
|
+
|
|
23
|
+
export interface AuthLockScreenProps {
|
|
24
|
+
/** Classes supplémentaires appliquées au conteneur. */
|
|
25
|
+
className?: string
|
|
26
|
+
/** URL de destination après authentification réussie (navigation complète). Par défaut, recharge la page courante. */
|
|
27
|
+
redirectUrl?: string
|
|
28
|
+
/** Callback invoqué après une authentification réussie. */
|
|
29
|
+
onAuthenticated?: () => void
|
|
30
|
+
/** Callback invoqué après un déverrouillage réussi (session déjà valide). */
|
|
31
|
+
onUnlocked?: () => void
|
|
32
|
+
/** Libellé de l'action d'authentification. */
|
|
33
|
+
actionLabel?: string
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Écran de verrouillage de type macOS.
|
|
38
|
+
*
|
|
39
|
+
* - Si aucune session active : présente l'avatar (ou les initiales) et un bouton pour
|
|
40
|
+
* s'authentifier via Liorian Auth (popup, redirection en repli).
|
|
41
|
+
* - Si une session est déjà valide (utilisateur connecté) : demande le mot de passe ou
|
|
42
|
+
* un déverrouillage par passkey / empreinte WebAuthn.
|
|
43
|
+
*/
|
|
44
|
+
export function AuthLockScreen(
|
|
45
|
+
{
|
|
46
|
+
className,
|
|
47
|
+
redirectUrl,
|
|
48
|
+
onAuthenticated,
|
|
49
|
+
onUnlocked,
|
|
50
|
+
actionLabel = 'Se connecter avec Liorian Auth',
|
|
51
|
+
}: AuthLockScreenProps) {
|
|
52
|
+
const [connecting, setConnecting] = useState(false)
|
|
53
|
+
const [user, setUser] = useState<UserInterface | null>(null)
|
|
54
|
+
const [mode, setMode] = useState<'sso' | 'unlock'>(() => AuthUserService.isAuthenticated() ? 'unlock' : 'sso')
|
|
55
|
+
const [password, setPassword] = useState('')
|
|
56
|
+
const [showPassword, setShowPassword] = useState(false)
|
|
57
|
+
const [unlocking, setUnlocking] = useState(false)
|
|
58
|
+
const [error, setError] = useState<string | null>(null)
|
|
59
|
+
|
|
60
|
+
useEffect(() => {
|
|
61
|
+
setUser(AuthUserService.getUser())
|
|
62
|
+
}, [])
|
|
63
|
+
|
|
64
|
+
const identity = useMemo(() => {
|
|
65
|
+
const name = user?.userData?.firstname
|
|
66
|
+
? `${user.userData.firstname} ${user.userData.lastname ?? ''}`.trim()
|
|
67
|
+
: user?.username || AppConfig.APP_NAME || 'Liorian';
|
|
68
|
+
|
|
69
|
+
const avatarId = user?.avatar?.id;
|
|
70
|
+
let initials = 'S';
|
|
71
|
+
if (user?.userData?.firstname && user?.userData?.lastname) {
|
|
72
|
+
initials = `${user.userData.firstname[0]}${user.userData.lastname[0]}`.toUpperCase();
|
|
73
|
+
} else if (user?.username) {
|
|
74
|
+
initials = user.username.substring(0, 2).toUpperCase();
|
|
75
|
+
} else if (user?.email) {
|
|
76
|
+
initials = user.email.substring(0, 2).toUpperCase();
|
|
77
|
+
} else if (AppConfig.APP_NAME) {
|
|
78
|
+
initials = AppConfig.APP_NAME.substring(0, 2).toUpperCase();
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return {name, avatarId, initials};
|
|
82
|
+
}, [user]);
|
|
83
|
+
|
|
84
|
+
useEffect(() => {
|
|
85
|
+
const onMessage = (event: MessageEvent) => {
|
|
86
|
+
if (event.origin !== window.location.origin) return;
|
|
87
|
+
if (event.data?.source !== 'liorian-auth') return;
|
|
88
|
+
if (event.data?.type !== SSO_CALLBACK_MESSAGE) return;
|
|
89
|
+
|
|
90
|
+
if (event.data?.success) {
|
|
91
|
+
setConnecting(false);
|
|
92
|
+
onAuthenticated?.();
|
|
93
|
+
// La session a été installée dans le `localStorage` partagé : on force une
|
|
94
|
+
// navigation complète pour que `AuthProvider` ré-hydrate le store depuis le stockage.
|
|
95
|
+
if (redirectUrl) {
|
|
96
|
+
window.location.assign(redirectUrl);
|
|
97
|
+
} else {
|
|
98
|
+
window.location.reload();
|
|
99
|
+
}
|
|
100
|
+
} else {
|
|
101
|
+
setConnecting(false);
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
window.addEventListener('message', onMessage);
|
|
105
|
+
return () => window.removeEventListener('message', onMessage);
|
|
106
|
+
}, [redirectUrl, onAuthenticated]);
|
|
107
|
+
|
|
108
|
+
const handleAuthenticate = async () => {
|
|
109
|
+
if (connecting) return;
|
|
110
|
+
setConnecting(true);
|
|
111
|
+
try {
|
|
112
|
+
const popup = await startSsoLoginPopup();
|
|
113
|
+
if (!popup) {
|
|
114
|
+
await startSsoLogin();
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Si le popup est fermé sans message de succès, réactiver le bouton.
|
|
119
|
+
const watchPopup = setInterval(() => {
|
|
120
|
+
if (popup.closed) {
|
|
121
|
+
clearInterval(watchPopup);
|
|
122
|
+
setConnecting(false);
|
|
123
|
+
}
|
|
124
|
+
}, 500);
|
|
125
|
+
window.addEventListener('beforeunload', () => clearInterval(watchPopup));
|
|
126
|
+
} catch (e) {
|
|
127
|
+
console.error('Impossible de démarrer l’authentification SSO', e);
|
|
128
|
+
setConnecting(false);
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
const handleUnlockWithPassword = async (e: React.FormEvent<HTMLFormElement>) => {
|
|
133
|
+
e.preventDefault();
|
|
134
|
+
if (unlocking || !password) return;
|
|
135
|
+
setUnlocking(true);
|
|
136
|
+
setError(null);
|
|
137
|
+
try {
|
|
138
|
+
const response = await AuthApiService.verifyPassword(password);
|
|
139
|
+
const valid = response?.data?.data?.valid;
|
|
140
|
+
if (!valid) {
|
|
141
|
+
setError('Mot de passe incorrect');
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
ActivityLockService.unlock();
|
|
145
|
+
onUnlocked?.();
|
|
146
|
+
} catch (err: any) {
|
|
147
|
+
setError(err?.response?.data?.message || 'Mot de passe incorrect');
|
|
148
|
+
} finally {
|
|
149
|
+
setUnlocking(false);
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
const handleUnlockWithPasskey = async () => {
|
|
154
|
+
if (unlocking) return;
|
|
155
|
+
setUnlocking(true);
|
|
156
|
+
setError(null);
|
|
157
|
+
try {
|
|
158
|
+
const options = await AuthApiService.webauthnAuthnOptions();
|
|
159
|
+
const credential = (await window.navigator.credentials.get({
|
|
160
|
+
publicKey: options as unknown as PublicKeyCredentialRequestOptions,
|
|
161
|
+
})) as PublicKeyCredential | null;
|
|
162
|
+
if (!credential) {
|
|
163
|
+
throw new Error('Aucune clé de sécurité reconnue.');
|
|
164
|
+
}
|
|
165
|
+
const webauthn = credential as PublicKeyCredential & {
|
|
166
|
+
response: AuthenticatorAssertionResponse;
|
|
167
|
+
};
|
|
168
|
+
const {clientDataJSON, authenticatorData, signature, userHandle} = webauthn.response;
|
|
169
|
+
await AuthApiService.webauthnAuthnVerify({
|
|
170
|
+
credentialId: webauthn.id,
|
|
171
|
+
rawId: Array.from(new Uint8Array(webauthn.rawId)),
|
|
172
|
+
response: {
|
|
173
|
+
clientDataJSON: webauthnBytes(clientDataJSON),
|
|
174
|
+
authenticatorData: webauthnBytes(authenticatorData),
|
|
175
|
+
signature: webauthnBytes(signature),
|
|
176
|
+
userHandle: webauthnBytes(userHandle),
|
|
177
|
+
},
|
|
178
|
+
});
|
|
179
|
+
ActivityLockService.unlock();
|
|
180
|
+
onUnlocked?.();
|
|
181
|
+
} catch (err: any) {
|
|
182
|
+
setError(err?.message || 'Impossible de se déverrouiller');
|
|
183
|
+
} finally {
|
|
184
|
+
setUnlocking(false);
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
return (
|
|
189
|
+
<View>
|
|
190
|
+
<View.Frame className={cn('flex min-h-svh flex-col', className)}>
|
|
191
|
+
<div className="flex flex-1 flex-col items-center justify-center gap-6 p-6">
|
|
192
|
+
<div className="flex flex-row justify-center items-center">
|
|
193
|
+
<div className="w-12">
|
|
194
|
+
<ThemeLogo variant={'square'}/>
|
|
195
|
+
</div>
|
|
196
|
+
</div>
|
|
197
|
+
|
|
198
|
+
<div className="flex flex-col items-center justify-end flex-auto gap-5">
|
|
199
|
+
<Avatar size="lg"
|
|
200
|
+
className="size-48! overflow-hidden rounded-full border-4 border-border shadow-lg">
|
|
201
|
+
{identity.avatarId ? (
|
|
202
|
+
<StorageMedia id={identity.avatarId} className="size-full object-cover"/>
|
|
203
|
+
) : (
|
|
204
|
+
<AvatarFallback className="text-3xl font-semibold">{identity.initials}</AvatarFallback>
|
|
205
|
+
)}
|
|
206
|
+
</Avatar>
|
|
207
|
+
<div className="flex flex-col items-center gap-1 text-center">
|
|
208
|
+
<p className="text-xl font-semibold text-foreground">{identity.name}</p>
|
|
209
|
+
{/*<p className="flex items-center gap-1.5 text-sm text-muted-foreground">*/}
|
|
210
|
+
{/* <LockKeyholeIcon className="size-3.5"/>*/}
|
|
211
|
+
{/* Session verrouillée*/}
|
|
212
|
+
{/*</p>*/}
|
|
213
|
+
</div>
|
|
214
|
+
</div>
|
|
215
|
+
|
|
216
|
+
<div className="flex flex-col gap-3 pb-6 w-full max-w-lg ">
|
|
217
|
+
{mode === 'unlock' ? (
|
|
218
|
+
<div className="w-full flex flex-col gap-3">
|
|
219
|
+
<form onSubmit={handleUnlockWithPassword} className="flex w-full flex-col gap-3">
|
|
220
|
+
<div className="">
|
|
221
|
+
{/*<Label htmlFor="lock-password" className="sr-only">Mot de passe</Label>*/}
|
|
222
|
+
<LegacyInput
|
|
223
|
+
id={"lock-password"}
|
|
224
|
+
label="Mot de passe"
|
|
225
|
+
input={{
|
|
226
|
+
type: showPassword ? "text" : "password",
|
|
227
|
+
placeholder: "••••••••",
|
|
228
|
+
required: true,
|
|
229
|
+
autoFocus: true,
|
|
230
|
+
value: password,
|
|
231
|
+
onChange: (e) => setPassword(e.target.value),
|
|
232
|
+
disabled: unlocking,
|
|
233
|
+
// className: "h-11 rounded-full px-4"
|
|
234
|
+
}}
|
|
235
|
+
icon={
|
|
236
|
+
<button
|
|
237
|
+
type="button"
|
|
238
|
+
onClick={() => setShowPassword(!showPassword)}
|
|
239
|
+
className="text-muted-foreground/60 hover:text-white transition-colors cursor-pointer flex items-center justify-center"
|
|
240
|
+
>
|
|
241
|
+
{showPassword
|
|
242
|
+
? <EyeOff className="size-4"/>
|
|
243
|
+
: <Eye className="size-4"/>}
|
|
244
|
+
</button>
|
|
245
|
+
}
|
|
246
|
+
/>
|
|
247
|
+
</div>
|
|
248
|
+
{error && (
|
|
249
|
+
<p className="px-2 text-center text-xs font-medium text-destructive">{error}</p>
|
|
250
|
+
)}
|
|
251
|
+
|
|
252
|
+
<div className="flex flex-row gap-3 items-center">
|
|
253
|
+
<Button
|
|
254
|
+
type="button"
|
|
255
|
+
variant="outline"
|
|
256
|
+
size="lg"
|
|
257
|
+
className=" rounded-full"
|
|
258
|
+
onClick={handleUnlockWithPasskey}
|
|
259
|
+
disabled={unlocking}
|
|
260
|
+
>
|
|
261
|
+
<FingerprintIcon className="size-4"/>
|
|
262
|
+
Clé de sécurité
|
|
263
|
+
</Button>
|
|
264
|
+
<Button
|
|
265
|
+
type="submit"
|
|
266
|
+
size="lg"
|
|
267
|
+
className="flex-auto rounded-full"
|
|
268
|
+
disabled={unlocking || !password}
|
|
269
|
+
>
|
|
270
|
+
<span className="flex-none">
|
|
271
|
+
{
|
|
272
|
+
unlocking
|
|
273
|
+
? <Activity.Loader/>
|
|
274
|
+
: <KeyRoundIcon className="size-4"/>
|
|
275
|
+
}
|
|
276
|
+
</span>
|
|
277
|
+
<span className="flex-auto">Déverrouiller</span>
|
|
278
|
+
</Button>
|
|
279
|
+
</div>
|
|
280
|
+
|
|
281
|
+
</form>
|
|
282
|
+
</div>
|
|
283
|
+
) : (
|
|
284
|
+
<div className="w-full flex items-center justify-center">
|
|
285
|
+
<Button
|
|
286
|
+
size="lg"
|
|
287
|
+
className="w-full flex flex-row items-center"
|
|
288
|
+
onClick={handleAuthenticate}
|
|
289
|
+
disabled={connecting}>
|
|
290
|
+
<span className="flex-none">
|
|
291
|
+
{connecting ? (
|
|
292
|
+
<Activity.Loader/>
|
|
293
|
+
) : (
|
|
294
|
+
<LockKeyholeIcon className="size-4"/>
|
|
295
|
+
)}
|
|
296
|
+
</span>
|
|
297
|
+
<span className="flex-auto">
|
|
298
|
+
{connecting ? 'Connexion…' : actionLabel}
|
|
299
|
+
</span>
|
|
300
|
+
</Button>
|
|
301
|
+
</div>
|
|
302
|
+
)}
|
|
303
|
+
</div>
|
|
304
|
+
|
|
305
|
+
</div>
|
|
306
|
+
</View.Frame>
|
|
307
|
+
</View>
|
|
308
|
+
)
|
|
309
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import {Waiting} from "./waiting";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Écran de synchronisation affiché pendant la (ré)hydratation de la session.
|
|
7
|
+
* Partagé par `AuthProvider` et `AuthGuard`.
|
|
8
|
+
*/
|
|
9
|
+
export function AuthSessionView() {
|
|
10
|
+
return (
|
|
11
|
+
<div className="w-screen h-screen flex justify-center items-center flex-col gap-4">
|
|
12
|
+
<div className="max-w-md w-full mx-6">
|
|
13
|
+
<Waiting label={"Synchronisation..."}/>
|
|
14
|
+
</div>
|
|
15
|
+
</div>
|
|
16
|
+
)
|
|
17
|
+
}
|