@serhii.olishevskyi/docs 1.1.2 → 1.1.3
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/dist/index.d.mts +14 -1
- package/dist/index.d.ts +14 -1
- package/dist/index.js +400 -2
- package/dist/index.mjs +402 -2
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -182,6 +182,14 @@ interface UserStatusChipComponentProps {
|
|
|
182
182
|
};
|
|
183
183
|
}
|
|
184
184
|
|
|
185
|
+
interface MyAvatarComponentProps {
|
|
186
|
+
size?: number;
|
|
187
|
+
disableBorder?: boolean;
|
|
188
|
+
disableShadow?: boolean;
|
|
189
|
+
disablePopover?: boolean;
|
|
190
|
+
sx?: SxProps<Theme>;
|
|
191
|
+
}
|
|
192
|
+
|
|
185
193
|
declare const UI: {
|
|
186
194
|
Inputs: {
|
|
187
195
|
TextField: React$1.FC<TextFieldComponentProps>;
|
|
@@ -198,6 +206,11 @@ declare const UI: {
|
|
|
198
206
|
UserPopover: React$1.FC<UserPopoverComponentProps>;
|
|
199
207
|
UserRoleChip: React$1.FC<UserRoleChipComponentProps>;
|
|
200
208
|
UserStatusChip: React$1.FC<UserStatusChipComponentProps>;
|
|
209
|
+
MyAvatar: React$1.FC<MyAvatarComponentProps>;
|
|
210
|
+
};
|
|
211
|
+
Widgets: {
|
|
212
|
+
ProtectedLanguageSelector: React$1.FC<{}>;
|
|
213
|
+
PublicLanguageSelector: React$1.FC<{}>;
|
|
201
214
|
};
|
|
202
215
|
};
|
|
203
216
|
|
|
@@ -475,4 +488,4 @@ declare const Providers: {
|
|
|
475
488
|
readonly AIProvider: React$1.FC<AIProviderProps>;
|
|
476
489
|
};
|
|
477
490
|
|
|
478
|
-
export { type AIConfig, type AIGenerateOptions, AIProvider, type AIProviderProps, type AIProviderType, AppSettingsProvider, AuthProvider, BreadcrumbProvider, type ConfirmOptions, type ConfirmResult, ConfirmationProvider, type ConfirmationProviderProps, type CopyClipboardButtonComponentProps as CopyClipboardButtonProps, type DialogSeverity, type DisplayState, type EmailInputComponentProps as EmailInputProps, type Language, LocalizationProvider, type NumberInputComponentProps as NumberInputProps, Providers, type SupabaseConfig, SupabaseProvider, type SupabaseProviderProps, type TextFieldComponentProps as TextFieldProps, type ThemeColors, type ThemeConfig, type ThemeMode, ThemeProvider, ToastProvider, type ToastType, type TranslatableTooltipComponentProps as TranslatableTooltipProps, TranslateProvider, TranslateText, TranslationEditProvider, type TypographyConfig, UI, type UrlComponentProps as UrlProps, type UserAvatarComponentProps as UserAvatarProps, type UserPopoverComponentProps as UserPopoverProps, type UserRoleChipComponentProps as UserRoleChipProps, UserSettingsProvider, type UserStatusChipComponentProps as UserStatusChipProps, useAI, useAppSettings, useAppTheme, useAuth, useBreadcrumb, useConfirmation, useLocalization, useSupabase, useToast, useTranslationEdit, useTranslationNamespace, useUserSettings };
|
|
491
|
+
export { type AIConfig, type AIGenerateOptions, AIProvider, type AIProviderProps, type AIProviderType, AppSettingsProvider, AuthProvider, BreadcrumbProvider, type ConfirmOptions, type ConfirmResult, ConfirmationProvider, type ConfirmationProviderProps, type CopyClipboardButtonComponentProps as CopyClipboardButtonProps, type DialogSeverity, type DisplayState, type EmailInputComponentProps as EmailInputProps, type Language, LocalizationProvider, type MyAvatarComponentProps as MyAvatarProps, type NumberInputComponentProps as NumberInputProps, Providers, type SupabaseConfig, SupabaseProvider, type SupabaseProviderProps, type TextFieldComponentProps as TextFieldProps, type ThemeColors, type ThemeConfig, type ThemeMode, ThemeProvider, ToastProvider, type ToastType, type TranslatableTooltipComponentProps as TranslatableTooltipProps, TranslateProvider, TranslateText, TranslationEditProvider, type TypographyConfig, UI, type UrlComponentProps as UrlProps, type UserAvatarComponentProps as UserAvatarProps, type UserPopoverComponentProps as UserPopoverProps, type UserRoleChipComponentProps as UserRoleChipProps, UserSettingsProvider, type UserStatusChipComponentProps as UserStatusChipProps, useAI, useAppSettings, useAppTheme, useAuth, useBreadcrumb, useConfirmation, useLocalization, useSupabase, useToast, useTranslationEdit, useTranslationNamespace, useUserSettings };
|
package/dist/index.d.ts
CHANGED
|
@@ -182,6 +182,14 @@ interface UserStatusChipComponentProps {
|
|
|
182
182
|
};
|
|
183
183
|
}
|
|
184
184
|
|
|
185
|
+
interface MyAvatarComponentProps {
|
|
186
|
+
size?: number;
|
|
187
|
+
disableBorder?: boolean;
|
|
188
|
+
disableShadow?: boolean;
|
|
189
|
+
disablePopover?: boolean;
|
|
190
|
+
sx?: SxProps<Theme>;
|
|
191
|
+
}
|
|
192
|
+
|
|
185
193
|
declare const UI: {
|
|
186
194
|
Inputs: {
|
|
187
195
|
TextField: React$1.FC<TextFieldComponentProps>;
|
|
@@ -198,6 +206,11 @@ declare const UI: {
|
|
|
198
206
|
UserPopover: React$1.FC<UserPopoverComponentProps>;
|
|
199
207
|
UserRoleChip: React$1.FC<UserRoleChipComponentProps>;
|
|
200
208
|
UserStatusChip: React$1.FC<UserStatusChipComponentProps>;
|
|
209
|
+
MyAvatar: React$1.FC<MyAvatarComponentProps>;
|
|
210
|
+
};
|
|
211
|
+
Widgets: {
|
|
212
|
+
ProtectedLanguageSelector: React$1.FC<{}>;
|
|
213
|
+
PublicLanguageSelector: React$1.FC<{}>;
|
|
201
214
|
};
|
|
202
215
|
};
|
|
203
216
|
|
|
@@ -475,4 +488,4 @@ declare const Providers: {
|
|
|
475
488
|
readonly AIProvider: React$1.FC<AIProviderProps>;
|
|
476
489
|
};
|
|
477
490
|
|
|
478
|
-
export { type AIConfig, type AIGenerateOptions, AIProvider, type AIProviderProps, type AIProviderType, AppSettingsProvider, AuthProvider, BreadcrumbProvider, type ConfirmOptions, type ConfirmResult, ConfirmationProvider, type ConfirmationProviderProps, type CopyClipboardButtonComponentProps as CopyClipboardButtonProps, type DialogSeverity, type DisplayState, type EmailInputComponentProps as EmailInputProps, type Language, LocalizationProvider, type NumberInputComponentProps as NumberInputProps, Providers, type SupabaseConfig, SupabaseProvider, type SupabaseProviderProps, type TextFieldComponentProps as TextFieldProps, type ThemeColors, type ThemeConfig, type ThemeMode, ThemeProvider, ToastProvider, type ToastType, type TranslatableTooltipComponentProps as TranslatableTooltipProps, TranslateProvider, TranslateText, TranslationEditProvider, type TypographyConfig, UI, type UrlComponentProps as UrlProps, type UserAvatarComponentProps as UserAvatarProps, type UserPopoverComponentProps as UserPopoverProps, type UserRoleChipComponentProps as UserRoleChipProps, UserSettingsProvider, type UserStatusChipComponentProps as UserStatusChipProps, useAI, useAppSettings, useAppTheme, useAuth, useBreadcrumb, useConfirmation, useLocalization, useSupabase, useToast, useTranslationEdit, useTranslationNamespace, useUserSettings };
|
|
491
|
+
export { type AIConfig, type AIGenerateOptions, AIProvider, type AIProviderProps, type AIProviderType, AppSettingsProvider, AuthProvider, BreadcrumbProvider, type ConfirmOptions, type ConfirmResult, ConfirmationProvider, type ConfirmationProviderProps, type CopyClipboardButtonComponentProps as CopyClipboardButtonProps, type DialogSeverity, type DisplayState, type EmailInputComponentProps as EmailInputProps, type Language, LocalizationProvider, type MyAvatarComponentProps as MyAvatarProps, type NumberInputComponentProps as NumberInputProps, Providers, type SupabaseConfig, SupabaseProvider, type SupabaseProviderProps, type TextFieldComponentProps as TextFieldProps, type ThemeColors, type ThemeConfig, type ThemeMode, ThemeProvider, ToastProvider, type ToastType, type TranslatableTooltipComponentProps as TranslatableTooltipProps, TranslateProvider, TranslateText, TranslationEditProvider, type TypographyConfig, UI, type UrlComponentProps as UrlProps, type UserAvatarComponentProps as UserAvatarProps, type UserPopoverComponentProps as UserPopoverProps, type UserRoleChipComponentProps as UserRoleChipProps, UserSettingsProvider, type UserStatusChipComponentProps as UserStatusChipProps, useAI, useAppSettings, useAppTheme, useAuth, useBreadcrumb, useConfirmation, useLocalization, useSupabase, useToast, useTranslationEdit, useTranslationNamespace, useUserSettings };
|
package/dist/index.js
CHANGED
|
@@ -3452,6 +3452,399 @@ init_CopyClipboardButtonComponent();
|
|
|
3452
3452
|
init_UserRoleChipComponent();
|
|
3453
3453
|
init_UserStatusChipComponent();
|
|
3454
3454
|
init_UserPopoverComponent();
|
|
3455
|
+
|
|
3456
|
+
// src/UI/components/data.display/MyAvatarComponent.tsx
|
|
3457
|
+
var import_react23 = require("react");
|
|
3458
|
+
var import_material16 = require("@mui/material");
|
|
3459
|
+
init_context();
|
|
3460
|
+
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
3461
|
+
var getInitials2 = (name) => {
|
|
3462
|
+
if (!name) return "?";
|
|
3463
|
+
const parts = name.trim().split(" ");
|
|
3464
|
+
if (parts.length >= 2) {
|
|
3465
|
+
return `${parts[0][0]}${parts[1][0]}`.toUpperCase();
|
|
3466
|
+
}
|
|
3467
|
+
return name[0].toUpperCase();
|
|
3468
|
+
};
|
|
3469
|
+
var MyAvatarComponent = ({
|
|
3470
|
+
size = 40,
|
|
3471
|
+
disableBorder = false,
|
|
3472
|
+
disableShadow = false,
|
|
3473
|
+
disablePopover = false,
|
|
3474
|
+
sx = {}
|
|
3475
|
+
}) => {
|
|
3476
|
+
const { profile: userProfile, loading: isLoading } = useAuth();
|
|
3477
|
+
const [anchorEl, setAnchorEl] = (0, import_react23.useState)(null);
|
|
3478
|
+
const handlePopoverOpen = (event) => {
|
|
3479
|
+
if (!disablePopover) {
|
|
3480
|
+
setAnchorEl(event.currentTarget);
|
|
3481
|
+
}
|
|
3482
|
+
};
|
|
3483
|
+
const handlePopoverClose = () => {
|
|
3484
|
+
setAnchorEl(null);
|
|
3485
|
+
};
|
|
3486
|
+
const isPopoverOpen = Boolean(anchorEl);
|
|
3487
|
+
if (isLoading) {
|
|
3488
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
3489
|
+
import_material16.Skeleton,
|
|
3490
|
+
{
|
|
3491
|
+
variant: "circular",
|
|
3492
|
+
width: size,
|
|
3493
|
+
height: size,
|
|
3494
|
+
sx: { display: "inline-block", flexShrink: 0, ...sx }
|
|
3495
|
+
}
|
|
3496
|
+
);
|
|
3497
|
+
}
|
|
3498
|
+
const initials = getInitials2(userProfile?.display_name || "");
|
|
3499
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
|
|
3500
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
3501
|
+
import_material16.Avatar,
|
|
3502
|
+
{
|
|
3503
|
+
src: userProfile?.avatar_url || void 0,
|
|
3504
|
+
alt: userProfile?.display_name || "User Avatar",
|
|
3505
|
+
onMouseEnter: handlePopoverOpen,
|
|
3506
|
+
onMouseLeave: handlePopoverClose,
|
|
3507
|
+
sx: {
|
|
3508
|
+
width: size,
|
|
3509
|
+
height: size,
|
|
3510
|
+
fontSize: size * 0.4,
|
|
3511
|
+
fontWeight: 600,
|
|
3512
|
+
bgcolor: "primary.main",
|
|
3513
|
+
color: "primary.contrastText",
|
|
3514
|
+
cursor: disablePopover ? void 0 : "pointer",
|
|
3515
|
+
transition: "transform 0.2s ease, box-shadow 0.2s ease",
|
|
3516
|
+
border: disableBorder ? "none" : "2px solid",
|
|
3517
|
+
borderColor: "background.paper",
|
|
3518
|
+
boxShadow: disableShadow ? "none" : 2,
|
|
3519
|
+
"&:hover": {
|
|
3520
|
+
transform: disablePopover ? "none" : "scale(1.05)"
|
|
3521
|
+
},
|
|
3522
|
+
...sx
|
|
3523
|
+
},
|
|
3524
|
+
children: !userProfile?.avatar_url && initials
|
|
3525
|
+
}
|
|
3526
|
+
),
|
|
3527
|
+
!disablePopover && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
3528
|
+
import_material16.Popover,
|
|
3529
|
+
{
|
|
3530
|
+
id: `avatar-popover-${userProfile?.id}`,
|
|
3531
|
+
open: isPopoverOpen,
|
|
3532
|
+
anchorEl,
|
|
3533
|
+
anchorOrigin: {
|
|
3534
|
+
vertical: "bottom",
|
|
3535
|
+
horizontal: "center"
|
|
3536
|
+
},
|
|
3537
|
+
transformOrigin: {
|
|
3538
|
+
vertical: "top",
|
|
3539
|
+
horizontal: "center"
|
|
3540
|
+
},
|
|
3541
|
+
onClose: handlePopoverClose,
|
|
3542
|
+
disableRestoreFocus: true,
|
|
3543
|
+
disableAutoFocus: true,
|
|
3544
|
+
disableEnforceFocus: true,
|
|
3545
|
+
sx: {
|
|
3546
|
+
pointerEvents: "none",
|
|
3547
|
+
mt: 1
|
|
3548
|
+
},
|
|
3549
|
+
slotProps: {
|
|
3550
|
+
paper: {
|
|
3551
|
+
sx: {
|
|
3552
|
+
p: 1.5,
|
|
3553
|
+
borderRadius: 2,
|
|
3554
|
+
boxShadow: 3
|
|
3555
|
+
}
|
|
3556
|
+
}
|
|
3557
|
+
},
|
|
3558
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_material16.Box, { sx: { display: "flex", flexDirection: "column", alignItems: "center", gap: 0.5 }, children: [
|
|
3559
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_material16.Typography, { variant: "subtitle2", sx: { fontWeight: 600 }, children: userProfile?.display_name }),
|
|
3560
|
+
userProfile?.email && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_material16.Typography, { variant: "caption", color: "text.secondary", children: userProfile.email })
|
|
3561
|
+
] })
|
|
3562
|
+
}
|
|
3563
|
+
)
|
|
3564
|
+
] });
|
|
3565
|
+
};
|
|
3566
|
+
|
|
3567
|
+
// src/i18n/LanguageSelector.tsx
|
|
3568
|
+
var import_react24 = require("react");
|
|
3569
|
+
var import_react_i18next5 = require("react-i18next");
|
|
3570
|
+
var import_material17 = require("@mui/material");
|
|
3571
|
+
init_LocalizationProvider();
|
|
3572
|
+
init_UserSettingsProvider();
|
|
3573
|
+
init_SupabaseProvider();
|
|
3574
|
+
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
3575
|
+
var LanguageSelector = () => {
|
|
3576
|
+
const supabase = useSupabase();
|
|
3577
|
+
const { i18n: i18n2 } = (0, import_react_i18next5.useTranslation)();
|
|
3578
|
+
const [languages, setLanguages] = (0, import_react24.useState)([]);
|
|
3579
|
+
const [loading, setLoading] = (0, import_react24.useState)(true);
|
|
3580
|
+
const { changeLanguage } = useLocalization();
|
|
3581
|
+
const { settings: userSettings, setLanguage } = useUserSettings();
|
|
3582
|
+
const [anchorEl, setAnchorEl] = (0, import_react24.useState)(null);
|
|
3583
|
+
const open = Boolean(anchorEl);
|
|
3584
|
+
(0, import_react24.useEffect)(() => {
|
|
3585
|
+
const fetchLanguages = async () => {
|
|
3586
|
+
try {
|
|
3587
|
+
const { data, error } = await supabase.from("languages").select("code, name, svg_flag").eq("enabled", true);
|
|
3588
|
+
if (error) throw error;
|
|
3589
|
+
setLanguages(data || []);
|
|
3590
|
+
if (userSettings.language) changeLanguage(userSettings.language);
|
|
3591
|
+
} catch (err) {
|
|
3592
|
+
console.error("\u041F\u043E\u043C\u0438\u043B\u043A\u0430 \u0437\u0430\u0432\u0430\u043D\u0442\u0430\u0436\u0435\u043D\u043D\u044F \u043C\u043E\u0432:", err);
|
|
3593
|
+
} finally {
|
|
3594
|
+
setLoading(false);
|
|
3595
|
+
}
|
|
3596
|
+
};
|
|
3597
|
+
fetchLanguages();
|
|
3598
|
+
}, []);
|
|
3599
|
+
const handleClick = (event) => {
|
|
3600
|
+
setAnchorEl(event.currentTarget);
|
|
3601
|
+
};
|
|
3602
|
+
const handleClose = () => {
|
|
3603
|
+
setAnchorEl(null);
|
|
3604
|
+
};
|
|
3605
|
+
const handleSelectLanguage = (langCode) => {
|
|
3606
|
+
changeLanguage(langCode);
|
|
3607
|
+
setLanguage(langCode);
|
|
3608
|
+
handleClose();
|
|
3609
|
+
};
|
|
3610
|
+
if (loading) {
|
|
3611
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_material17.CircularProgress, { size: 20, color: "inherit", sx: { mx: 1 } });
|
|
3612
|
+
}
|
|
3613
|
+
const rawCurrentLang = i18n2.language || "uk";
|
|
3614
|
+
const currentLangCode = rawCurrentLang.split("-")[0];
|
|
3615
|
+
const currentLang = languages.find((l) => l.code === currentLangCode) || languages[0];
|
|
3616
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_jsx_runtime27.Fragment, { children: [
|
|
3617
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_material17.Tooltip, { title: currentLang ? currentLang.name : "\u041C\u043E\u0432\u0430", arrow: true, placement: "bottom", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
3618
|
+
import_material17.IconButton,
|
|
3619
|
+
{
|
|
3620
|
+
onClick: handleClick,
|
|
3621
|
+
size: "small",
|
|
3622
|
+
"aria-controls": open ? "language-menu" : void 0,
|
|
3623
|
+
"aria-haspopup": "true",
|
|
3624
|
+
"aria-expanded": open ? "true" : void 0,
|
|
3625
|
+
sx: {
|
|
3626
|
+
p: 1,
|
|
3627
|
+
borderRadius: 2,
|
|
3628
|
+
transition: "background-color 0.2s",
|
|
3629
|
+
"&:hover": {
|
|
3630
|
+
backgroundColor: "action.hover"
|
|
3631
|
+
}
|
|
3632
|
+
},
|
|
3633
|
+
children: currentLang?.svg_flag && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
3634
|
+
import_material17.Box,
|
|
3635
|
+
{
|
|
3636
|
+
sx: {
|
|
3637
|
+
width: 24,
|
|
3638
|
+
height: 16,
|
|
3639
|
+
borderRadius: "3px",
|
|
3640
|
+
overflow: "hidden",
|
|
3641
|
+
flexShrink: 0,
|
|
3642
|
+
boxShadow: "0 0 2px rgba(0,0,0,0.3)",
|
|
3643
|
+
display: "flex",
|
|
3644
|
+
alignItems: "center",
|
|
3645
|
+
justifyContent: "center",
|
|
3646
|
+
"& svg": { width: "100%", height: "100%", display: "block", objectFit: "cover" }
|
|
3647
|
+
},
|
|
3648
|
+
dangerouslySetInnerHTML: { __html: currentLang.svg_flag }
|
|
3649
|
+
}
|
|
3650
|
+
)
|
|
3651
|
+
}
|
|
3652
|
+
) }),
|
|
3653
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
3654
|
+
import_material17.Menu,
|
|
3655
|
+
{
|
|
3656
|
+
id: "language-menu",
|
|
3657
|
+
anchorEl,
|
|
3658
|
+
open,
|
|
3659
|
+
onClose: handleClose,
|
|
3660
|
+
slotProps: {
|
|
3661
|
+
paper: {
|
|
3662
|
+
elevation: 3,
|
|
3663
|
+
sx: {
|
|
3664
|
+
mt: 1,
|
|
3665
|
+
minWidth: 150,
|
|
3666
|
+
borderRadius: 2
|
|
3667
|
+
}
|
|
3668
|
+
}
|
|
3669
|
+
},
|
|
3670
|
+
transformOrigin: { horizontal: "right", vertical: "top" },
|
|
3671
|
+
anchorOrigin: { horizontal: "right", vertical: "bottom" },
|
|
3672
|
+
children: languages.map((lang) => {
|
|
3673
|
+
const isSelected = lang.code === currentLangCode;
|
|
3674
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
|
|
3675
|
+
import_material17.MenuItem,
|
|
3676
|
+
{
|
|
3677
|
+
selected: isSelected,
|
|
3678
|
+
onClick: () => handleSelectLanguage(lang.code),
|
|
3679
|
+
sx: {
|
|
3680
|
+
display: "flex",
|
|
3681
|
+
alignItems: "center",
|
|
3682
|
+
gap: 1.5,
|
|
3683
|
+
py: 1,
|
|
3684
|
+
px: 2
|
|
3685
|
+
},
|
|
3686
|
+
children: [
|
|
3687
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
3688
|
+
import_material17.Box,
|
|
3689
|
+
{
|
|
3690
|
+
sx: {
|
|
3691
|
+
width: 22,
|
|
3692
|
+
height: 15,
|
|
3693
|
+
borderRadius: "2px",
|
|
3694
|
+
overflow: "hidden",
|
|
3695
|
+
flexShrink: 0,
|
|
3696
|
+
boxShadow: "0 0 1px rgba(0,0,0,0.4)",
|
|
3697
|
+
"& svg": { width: "100%", height: "100%", display: "block" }
|
|
3698
|
+
},
|
|
3699
|
+
dangerouslySetInnerHTML: { __html: lang.svg_flag }
|
|
3700
|
+
}
|
|
3701
|
+
),
|
|
3702
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_material17.Typography, { variant: "body2", sx: { fontWeight: isSelected ? 600 : 400 }, children: lang.name })
|
|
3703
|
+
]
|
|
3704
|
+
},
|
|
3705
|
+
lang.code
|
|
3706
|
+
);
|
|
3707
|
+
})
|
|
3708
|
+
}
|
|
3709
|
+
)
|
|
3710
|
+
] });
|
|
3711
|
+
};
|
|
3712
|
+
var PublicLanguageSelector = () => {
|
|
3713
|
+
const supabase = useSupabase();
|
|
3714
|
+
const { i18n: i18n2 } = (0, import_react_i18next5.useTranslation)();
|
|
3715
|
+
const { changeLanguage } = useLocalization();
|
|
3716
|
+
const [languages, setLanguages] = (0, import_react24.useState)([]);
|
|
3717
|
+
const [loading, setLoading] = (0, import_react24.useState)(true);
|
|
3718
|
+
const [anchorEl, setAnchorEl] = (0, import_react24.useState)(null);
|
|
3719
|
+
const open = Boolean(anchorEl);
|
|
3720
|
+
(0, import_react24.useEffect)(() => {
|
|
3721
|
+
const fetchLanguages = async () => {
|
|
3722
|
+
try {
|
|
3723
|
+
const { data, error } = await supabase.from("languages").select("code, name, svg_flag").eq("enabled", true);
|
|
3724
|
+
if (error) throw error;
|
|
3725
|
+
setLanguages(data || []);
|
|
3726
|
+
} catch (err) {
|
|
3727
|
+
console.error("\u041F\u043E\u043C\u0438\u043B\u043A\u0430 \u0437\u0430\u0432\u0430\u043D\u0442\u0430\u0436\u0435\u043D\u043D\u044F \u043C\u043E\u0432:", err);
|
|
3728
|
+
} finally {
|
|
3729
|
+
setLoading(false);
|
|
3730
|
+
}
|
|
3731
|
+
};
|
|
3732
|
+
fetchLanguages();
|
|
3733
|
+
}, []);
|
|
3734
|
+
const handleClick = (event) => {
|
|
3735
|
+
setAnchorEl(event.currentTarget);
|
|
3736
|
+
};
|
|
3737
|
+
const handleClose = () => {
|
|
3738
|
+
setAnchorEl(null);
|
|
3739
|
+
};
|
|
3740
|
+
const handleSelectLanguage = (langCode) => {
|
|
3741
|
+
changeLanguage(langCode);
|
|
3742
|
+
handleClose();
|
|
3743
|
+
};
|
|
3744
|
+
if (loading) {
|
|
3745
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_material17.CircularProgress, { size: 20, color: "inherit", sx: { mx: 1 } });
|
|
3746
|
+
}
|
|
3747
|
+
const rawCurrentLang = i18n2.language || "uk";
|
|
3748
|
+
const currentLangCode = rawCurrentLang.split("-")[0];
|
|
3749
|
+
const currentLang = languages.find((l) => l.code === currentLangCode) || languages[0];
|
|
3750
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_jsx_runtime27.Fragment, { children: [
|
|
3751
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_material17.Tooltip, { title: currentLang ? currentLang.name : "\u041C\u043E\u0432\u0430", arrow: true, placement: "bottom", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
3752
|
+
import_material17.IconButton,
|
|
3753
|
+
{
|
|
3754
|
+
onClick: handleClick,
|
|
3755
|
+
size: "small",
|
|
3756
|
+
"aria-controls": open ? "language-menu" : void 0,
|
|
3757
|
+
"aria-haspopup": "true",
|
|
3758
|
+
"aria-expanded": open ? "true" : void 0,
|
|
3759
|
+
sx: {
|
|
3760
|
+
p: 1,
|
|
3761
|
+
borderRadius: 2,
|
|
3762
|
+
transition: "background-color 0.2s",
|
|
3763
|
+
"&:hover": {
|
|
3764
|
+
backgroundColor: "action.hover"
|
|
3765
|
+
}
|
|
3766
|
+
},
|
|
3767
|
+
children: currentLang?.svg_flag && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
3768
|
+
import_material17.Box,
|
|
3769
|
+
{
|
|
3770
|
+
sx: {
|
|
3771
|
+
width: 24,
|
|
3772
|
+
height: 16,
|
|
3773
|
+
borderRadius: "3px",
|
|
3774
|
+
overflow: "hidden",
|
|
3775
|
+
flexShrink: 0,
|
|
3776
|
+
boxShadow: "0 0 2px rgba(0,0,0,0.3)",
|
|
3777
|
+
display: "flex",
|
|
3778
|
+
alignItems: "center",
|
|
3779
|
+
justifyContent: "center",
|
|
3780
|
+
"& svg": { width: "100%", height: "100%", display: "block", objectFit: "cover" }
|
|
3781
|
+
},
|
|
3782
|
+
dangerouslySetInnerHTML: { __html: currentLang.svg_flag }
|
|
3783
|
+
}
|
|
3784
|
+
)
|
|
3785
|
+
}
|
|
3786
|
+
) }),
|
|
3787
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
3788
|
+
import_material17.Menu,
|
|
3789
|
+
{
|
|
3790
|
+
id: "language-menu",
|
|
3791
|
+
anchorEl,
|
|
3792
|
+
open,
|
|
3793
|
+
onClose: handleClose,
|
|
3794
|
+
slotProps: {
|
|
3795
|
+
paper: {
|
|
3796
|
+
elevation: 3,
|
|
3797
|
+
sx: {
|
|
3798
|
+
mt: 1,
|
|
3799
|
+
minWidth: 150,
|
|
3800
|
+
borderRadius: 2
|
|
3801
|
+
}
|
|
3802
|
+
}
|
|
3803
|
+
},
|
|
3804
|
+
transformOrigin: { horizontal: "right", vertical: "top" },
|
|
3805
|
+
anchorOrigin: { horizontal: "right", vertical: "bottom" },
|
|
3806
|
+
children: languages.map((lang) => {
|
|
3807
|
+
const isSelected = lang.code === currentLangCode;
|
|
3808
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
|
|
3809
|
+
import_material17.MenuItem,
|
|
3810
|
+
{
|
|
3811
|
+
selected: isSelected,
|
|
3812
|
+
onClick: () => handleSelectLanguage(lang.code),
|
|
3813
|
+
sx: {
|
|
3814
|
+
display: "flex",
|
|
3815
|
+
alignItems: "center",
|
|
3816
|
+
gap: 1.5,
|
|
3817
|
+
py: 1,
|
|
3818
|
+
px: 2
|
|
3819
|
+
},
|
|
3820
|
+
children: [
|
|
3821
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
3822
|
+
import_material17.Box,
|
|
3823
|
+
{
|
|
3824
|
+
sx: {
|
|
3825
|
+
width: 22,
|
|
3826
|
+
height: 15,
|
|
3827
|
+
borderRadius: "2px",
|
|
3828
|
+
overflow: "hidden",
|
|
3829
|
+
flexShrink: 0,
|
|
3830
|
+
boxShadow: "0 0 1px rgba(0,0,0,0.4)",
|
|
3831
|
+
"& svg": { width: "100%", height: "100%", display: "block" }
|
|
3832
|
+
},
|
|
3833
|
+
dangerouslySetInnerHTML: { __html: lang.svg_flag }
|
|
3834
|
+
}
|
|
3835
|
+
),
|
|
3836
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_material17.Typography, { variant: "body2", sx: { fontWeight: isSelected ? 600 : 400 }, children: lang.name })
|
|
3837
|
+
]
|
|
3838
|
+
},
|
|
3839
|
+
lang.code
|
|
3840
|
+
);
|
|
3841
|
+
})
|
|
3842
|
+
}
|
|
3843
|
+
)
|
|
3844
|
+
] });
|
|
3845
|
+
};
|
|
3846
|
+
|
|
3847
|
+
// src/UI/index.ts
|
|
3455
3848
|
var UI = {
|
|
3456
3849
|
Inputs: {
|
|
3457
3850
|
TextField: TextFieldComponent,
|
|
@@ -3467,11 +3860,16 @@ var UI = {
|
|
|
3467
3860
|
UserAvatar: UserAvatarComponent,
|
|
3468
3861
|
UserPopover: UserPopoverComponent_default,
|
|
3469
3862
|
UserRoleChip: UserRoleChipComponent,
|
|
3470
|
-
UserStatusChip: UserStatusChipComponent
|
|
3471
|
-
|
|
3863
|
+
UserStatusChip: UserStatusChipComponent,
|
|
3864
|
+
MyAvatar: MyAvatarComponent
|
|
3865
|
+
},
|
|
3472
3866
|
/*Layout: {
|
|
3473
3867
|
Row: FormRow,
|
|
3474
3868
|
},*/
|
|
3869
|
+
Widgets: {
|
|
3870
|
+
ProtectedLanguageSelector: LanguageSelector,
|
|
3871
|
+
PublicLanguageSelector
|
|
3872
|
+
}
|
|
3475
3873
|
};
|
|
3476
3874
|
|
|
3477
3875
|
// src/index.ts
|
package/dist/index.mjs
CHANGED
|
@@ -844,6 +844,401 @@ var UserAvatarComponent = ({
|
|
|
844
844
|
] });
|
|
845
845
|
};
|
|
846
846
|
|
|
847
|
+
// src/UI/components/data.display/MyAvatarComponent.tsx
|
|
848
|
+
import { useState as useState6 } from "react";
|
|
849
|
+
import { Avatar as Avatar2, Box as Box4, Popover as Popover2, Typography as Typography3, Skeleton } from "@mui/material";
|
|
850
|
+
import { Fragment as Fragment5, jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
851
|
+
var getInitials2 = (name) => {
|
|
852
|
+
if (!name) return "?";
|
|
853
|
+
const parts = name.trim().split(" ");
|
|
854
|
+
if (parts.length >= 2) {
|
|
855
|
+
return `${parts[0][0]}${parts[1][0]}`.toUpperCase();
|
|
856
|
+
}
|
|
857
|
+
return name[0].toUpperCase();
|
|
858
|
+
};
|
|
859
|
+
var MyAvatarComponent = ({
|
|
860
|
+
size = 40,
|
|
861
|
+
disableBorder = false,
|
|
862
|
+
disableShadow = false,
|
|
863
|
+
disablePopover = false,
|
|
864
|
+
sx = {}
|
|
865
|
+
}) => {
|
|
866
|
+
const { profile: userProfile, loading: isLoading } = useAuth();
|
|
867
|
+
const [anchorEl, setAnchorEl] = useState6(null);
|
|
868
|
+
const handlePopoverOpen = (event) => {
|
|
869
|
+
if (!disablePopover) {
|
|
870
|
+
setAnchorEl(event.currentTarget);
|
|
871
|
+
}
|
|
872
|
+
};
|
|
873
|
+
const handlePopoverClose = () => {
|
|
874
|
+
setAnchorEl(null);
|
|
875
|
+
};
|
|
876
|
+
const isPopoverOpen = Boolean(anchorEl);
|
|
877
|
+
if (isLoading) {
|
|
878
|
+
return /* @__PURE__ */ jsx6(
|
|
879
|
+
Skeleton,
|
|
880
|
+
{
|
|
881
|
+
variant: "circular",
|
|
882
|
+
width: size,
|
|
883
|
+
height: size,
|
|
884
|
+
sx: { display: "inline-block", flexShrink: 0, ...sx }
|
|
885
|
+
}
|
|
886
|
+
);
|
|
887
|
+
}
|
|
888
|
+
const initials = getInitials2(userProfile?.display_name || "");
|
|
889
|
+
return /* @__PURE__ */ jsxs5(Fragment5, { children: [
|
|
890
|
+
/* @__PURE__ */ jsx6(
|
|
891
|
+
Avatar2,
|
|
892
|
+
{
|
|
893
|
+
src: userProfile?.avatar_url || void 0,
|
|
894
|
+
alt: userProfile?.display_name || "User Avatar",
|
|
895
|
+
onMouseEnter: handlePopoverOpen,
|
|
896
|
+
onMouseLeave: handlePopoverClose,
|
|
897
|
+
sx: {
|
|
898
|
+
width: size,
|
|
899
|
+
height: size,
|
|
900
|
+
fontSize: size * 0.4,
|
|
901
|
+
fontWeight: 600,
|
|
902
|
+
bgcolor: "primary.main",
|
|
903
|
+
color: "primary.contrastText",
|
|
904
|
+
cursor: disablePopover ? void 0 : "pointer",
|
|
905
|
+
transition: "transform 0.2s ease, box-shadow 0.2s ease",
|
|
906
|
+
border: disableBorder ? "none" : "2px solid",
|
|
907
|
+
borderColor: "background.paper",
|
|
908
|
+
boxShadow: disableShadow ? "none" : 2,
|
|
909
|
+
"&:hover": {
|
|
910
|
+
transform: disablePopover ? "none" : "scale(1.05)"
|
|
911
|
+
},
|
|
912
|
+
...sx
|
|
913
|
+
},
|
|
914
|
+
children: !userProfile?.avatar_url && initials
|
|
915
|
+
}
|
|
916
|
+
),
|
|
917
|
+
!disablePopover && /* @__PURE__ */ jsx6(
|
|
918
|
+
Popover2,
|
|
919
|
+
{
|
|
920
|
+
id: `avatar-popover-${userProfile?.id}`,
|
|
921
|
+
open: isPopoverOpen,
|
|
922
|
+
anchorEl,
|
|
923
|
+
anchorOrigin: {
|
|
924
|
+
vertical: "bottom",
|
|
925
|
+
horizontal: "center"
|
|
926
|
+
},
|
|
927
|
+
transformOrigin: {
|
|
928
|
+
vertical: "top",
|
|
929
|
+
horizontal: "center"
|
|
930
|
+
},
|
|
931
|
+
onClose: handlePopoverClose,
|
|
932
|
+
disableRestoreFocus: true,
|
|
933
|
+
disableAutoFocus: true,
|
|
934
|
+
disableEnforceFocus: true,
|
|
935
|
+
sx: {
|
|
936
|
+
pointerEvents: "none",
|
|
937
|
+
mt: 1
|
|
938
|
+
},
|
|
939
|
+
slotProps: {
|
|
940
|
+
paper: {
|
|
941
|
+
sx: {
|
|
942
|
+
p: 1.5,
|
|
943
|
+
borderRadius: 2,
|
|
944
|
+
boxShadow: 3
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
},
|
|
948
|
+
children: /* @__PURE__ */ jsxs5(Box4, { sx: { display: "flex", flexDirection: "column", alignItems: "center", gap: 0.5 }, children: [
|
|
949
|
+
/* @__PURE__ */ jsx6(Typography3, { variant: "subtitle2", sx: { fontWeight: 600 }, children: userProfile?.display_name }),
|
|
950
|
+
userProfile?.email && /* @__PURE__ */ jsx6(Typography3, { variant: "caption", color: "text.secondary", children: userProfile.email })
|
|
951
|
+
] })
|
|
952
|
+
}
|
|
953
|
+
)
|
|
954
|
+
] });
|
|
955
|
+
};
|
|
956
|
+
|
|
957
|
+
// src/i18n/LanguageSelector.tsx
|
|
958
|
+
import { useEffect as useEffect3, useState as useState7 } from "react";
|
|
959
|
+
import { useTranslation as useTranslation2 } from "react-i18next";
|
|
960
|
+
import {
|
|
961
|
+
Box as Box5,
|
|
962
|
+
Typography as Typography4,
|
|
963
|
+
CircularProgress,
|
|
964
|
+
IconButton as IconButton4,
|
|
965
|
+
Menu,
|
|
966
|
+
MenuItem,
|
|
967
|
+
Tooltip as Tooltip4
|
|
968
|
+
} from "@mui/material";
|
|
969
|
+
import { Fragment as Fragment6, jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
970
|
+
var LanguageSelector = () => {
|
|
971
|
+
const supabase = useSupabase();
|
|
972
|
+
const { i18n } = useTranslation2();
|
|
973
|
+
const [languages, setLanguages] = useState7([]);
|
|
974
|
+
const [loading, setLoading] = useState7(true);
|
|
975
|
+
const { changeLanguage } = useLocalization();
|
|
976
|
+
const { settings: userSettings, setLanguage } = useUserSettings();
|
|
977
|
+
const [anchorEl, setAnchorEl] = useState7(null);
|
|
978
|
+
const open = Boolean(anchorEl);
|
|
979
|
+
useEffect3(() => {
|
|
980
|
+
const fetchLanguages = async () => {
|
|
981
|
+
try {
|
|
982
|
+
const { data, error } = await supabase.from("languages").select("code, name, svg_flag").eq("enabled", true);
|
|
983
|
+
if (error) throw error;
|
|
984
|
+
setLanguages(data || []);
|
|
985
|
+
if (userSettings.language) changeLanguage(userSettings.language);
|
|
986
|
+
} catch (err) {
|
|
987
|
+
console.error("\u041F\u043E\u043C\u0438\u043B\u043A\u0430 \u0437\u0430\u0432\u0430\u043D\u0442\u0430\u0436\u0435\u043D\u043D\u044F \u043C\u043E\u0432:", err);
|
|
988
|
+
} finally {
|
|
989
|
+
setLoading(false);
|
|
990
|
+
}
|
|
991
|
+
};
|
|
992
|
+
fetchLanguages();
|
|
993
|
+
}, []);
|
|
994
|
+
const handleClick = (event) => {
|
|
995
|
+
setAnchorEl(event.currentTarget);
|
|
996
|
+
};
|
|
997
|
+
const handleClose = () => {
|
|
998
|
+
setAnchorEl(null);
|
|
999
|
+
};
|
|
1000
|
+
const handleSelectLanguage = (langCode) => {
|
|
1001
|
+
changeLanguage(langCode);
|
|
1002
|
+
setLanguage(langCode);
|
|
1003
|
+
handleClose();
|
|
1004
|
+
};
|
|
1005
|
+
if (loading) {
|
|
1006
|
+
return /* @__PURE__ */ jsx7(CircularProgress, { size: 20, color: "inherit", sx: { mx: 1 } });
|
|
1007
|
+
}
|
|
1008
|
+
const rawCurrentLang = i18n.language || "uk";
|
|
1009
|
+
const currentLangCode = rawCurrentLang.split("-")[0];
|
|
1010
|
+
const currentLang = languages.find((l) => l.code === currentLangCode) || languages[0];
|
|
1011
|
+
return /* @__PURE__ */ jsxs6(Fragment6, { children: [
|
|
1012
|
+
/* @__PURE__ */ jsx7(Tooltip4, { title: currentLang ? currentLang.name : "\u041C\u043E\u0432\u0430", arrow: true, placement: "bottom", children: /* @__PURE__ */ jsx7(
|
|
1013
|
+
IconButton4,
|
|
1014
|
+
{
|
|
1015
|
+
onClick: handleClick,
|
|
1016
|
+
size: "small",
|
|
1017
|
+
"aria-controls": open ? "language-menu" : void 0,
|
|
1018
|
+
"aria-haspopup": "true",
|
|
1019
|
+
"aria-expanded": open ? "true" : void 0,
|
|
1020
|
+
sx: {
|
|
1021
|
+
p: 1,
|
|
1022
|
+
borderRadius: 2,
|
|
1023
|
+
transition: "background-color 0.2s",
|
|
1024
|
+
"&:hover": {
|
|
1025
|
+
backgroundColor: "action.hover"
|
|
1026
|
+
}
|
|
1027
|
+
},
|
|
1028
|
+
children: currentLang?.svg_flag && /* @__PURE__ */ jsx7(
|
|
1029
|
+
Box5,
|
|
1030
|
+
{
|
|
1031
|
+
sx: {
|
|
1032
|
+
width: 24,
|
|
1033
|
+
height: 16,
|
|
1034
|
+
borderRadius: "3px",
|
|
1035
|
+
overflow: "hidden",
|
|
1036
|
+
flexShrink: 0,
|
|
1037
|
+
boxShadow: "0 0 2px rgba(0,0,0,0.3)",
|
|
1038
|
+
display: "flex",
|
|
1039
|
+
alignItems: "center",
|
|
1040
|
+
justifyContent: "center",
|
|
1041
|
+
"& svg": { width: "100%", height: "100%", display: "block", objectFit: "cover" }
|
|
1042
|
+
},
|
|
1043
|
+
dangerouslySetInnerHTML: { __html: currentLang.svg_flag }
|
|
1044
|
+
}
|
|
1045
|
+
)
|
|
1046
|
+
}
|
|
1047
|
+
) }),
|
|
1048
|
+
/* @__PURE__ */ jsx7(
|
|
1049
|
+
Menu,
|
|
1050
|
+
{
|
|
1051
|
+
id: "language-menu",
|
|
1052
|
+
anchorEl,
|
|
1053
|
+
open,
|
|
1054
|
+
onClose: handleClose,
|
|
1055
|
+
slotProps: {
|
|
1056
|
+
paper: {
|
|
1057
|
+
elevation: 3,
|
|
1058
|
+
sx: {
|
|
1059
|
+
mt: 1,
|
|
1060
|
+
minWidth: 150,
|
|
1061
|
+
borderRadius: 2
|
|
1062
|
+
}
|
|
1063
|
+
}
|
|
1064
|
+
},
|
|
1065
|
+
transformOrigin: { horizontal: "right", vertical: "top" },
|
|
1066
|
+
anchorOrigin: { horizontal: "right", vertical: "bottom" },
|
|
1067
|
+
children: languages.map((lang) => {
|
|
1068
|
+
const isSelected = lang.code === currentLangCode;
|
|
1069
|
+
return /* @__PURE__ */ jsxs6(
|
|
1070
|
+
MenuItem,
|
|
1071
|
+
{
|
|
1072
|
+
selected: isSelected,
|
|
1073
|
+
onClick: () => handleSelectLanguage(lang.code),
|
|
1074
|
+
sx: {
|
|
1075
|
+
display: "flex",
|
|
1076
|
+
alignItems: "center",
|
|
1077
|
+
gap: 1.5,
|
|
1078
|
+
py: 1,
|
|
1079
|
+
px: 2
|
|
1080
|
+
},
|
|
1081
|
+
children: [
|
|
1082
|
+
/* @__PURE__ */ jsx7(
|
|
1083
|
+
Box5,
|
|
1084
|
+
{
|
|
1085
|
+
sx: {
|
|
1086
|
+
width: 22,
|
|
1087
|
+
height: 15,
|
|
1088
|
+
borderRadius: "2px",
|
|
1089
|
+
overflow: "hidden",
|
|
1090
|
+
flexShrink: 0,
|
|
1091
|
+
boxShadow: "0 0 1px rgba(0,0,0,0.4)",
|
|
1092
|
+
"& svg": { width: "100%", height: "100%", display: "block" }
|
|
1093
|
+
},
|
|
1094
|
+
dangerouslySetInnerHTML: { __html: lang.svg_flag }
|
|
1095
|
+
}
|
|
1096
|
+
),
|
|
1097
|
+
/* @__PURE__ */ jsx7(Typography4, { variant: "body2", sx: { fontWeight: isSelected ? 600 : 400 }, children: lang.name })
|
|
1098
|
+
]
|
|
1099
|
+
},
|
|
1100
|
+
lang.code
|
|
1101
|
+
);
|
|
1102
|
+
})
|
|
1103
|
+
}
|
|
1104
|
+
)
|
|
1105
|
+
] });
|
|
1106
|
+
};
|
|
1107
|
+
var PublicLanguageSelector = () => {
|
|
1108
|
+
const supabase = useSupabase();
|
|
1109
|
+
const { i18n } = useTranslation2();
|
|
1110
|
+
const { changeLanguage } = useLocalization();
|
|
1111
|
+
const [languages, setLanguages] = useState7([]);
|
|
1112
|
+
const [loading, setLoading] = useState7(true);
|
|
1113
|
+
const [anchorEl, setAnchorEl] = useState7(null);
|
|
1114
|
+
const open = Boolean(anchorEl);
|
|
1115
|
+
useEffect3(() => {
|
|
1116
|
+
const fetchLanguages = async () => {
|
|
1117
|
+
try {
|
|
1118
|
+
const { data, error } = await supabase.from("languages").select("code, name, svg_flag").eq("enabled", true);
|
|
1119
|
+
if (error) throw error;
|
|
1120
|
+
setLanguages(data || []);
|
|
1121
|
+
} catch (err) {
|
|
1122
|
+
console.error("\u041F\u043E\u043C\u0438\u043B\u043A\u0430 \u0437\u0430\u0432\u0430\u043D\u0442\u0430\u0436\u0435\u043D\u043D\u044F \u043C\u043E\u0432:", err);
|
|
1123
|
+
} finally {
|
|
1124
|
+
setLoading(false);
|
|
1125
|
+
}
|
|
1126
|
+
};
|
|
1127
|
+
fetchLanguages();
|
|
1128
|
+
}, []);
|
|
1129
|
+
const handleClick = (event) => {
|
|
1130
|
+
setAnchorEl(event.currentTarget);
|
|
1131
|
+
};
|
|
1132
|
+
const handleClose = () => {
|
|
1133
|
+
setAnchorEl(null);
|
|
1134
|
+
};
|
|
1135
|
+
const handleSelectLanguage = (langCode) => {
|
|
1136
|
+
changeLanguage(langCode);
|
|
1137
|
+
handleClose();
|
|
1138
|
+
};
|
|
1139
|
+
if (loading) {
|
|
1140
|
+
return /* @__PURE__ */ jsx7(CircularProgress, { size: 20, color: "inherit", sx: { mx: 1 } });
|
|
1141
|
+
}
|
|
1142
|
+
const rawCurrentLang = i18n.language || "uk";
|
|
1143
|
+
const currentLangCode = rawCurrentLang.split("-")[0];
|
|
1144
|
+
const currentLang = languages.find((l) => l.code === currentLangCode) || languages[0];
|
|
1145
|
+
return /* @__PURE__ */ jsxs6(Fragment6, { children: [
|
|
1146
|
+
/* @__PURE__ */ jsx7(Tooltip4, { title: currentLang ? currentLang.name : "\u041C\u043E\u0432\u0430", arrow: true, placement: "bottom", children: /* @__PURE__ */ jsx7(
|
|
1147
|
+
IconButton4,
|
|
1148
|
+
{
|
|
1149
|
+
onClick: handleClick,
|
|
1150
|
+
size: "small",
|
|
1151
|
+
"aria-controls": open ? "language-menu" : void 0,
|
|
1152
|
+
"aria-haspopup": "true",
|
|
1153
|
+
"aria-expanded": open ? "true" : void 0,
|
|
1154
|
+
sx: {
|
|
1155
|
+
p: 1,
|
|
1156
|
+
borderRadius: 2,
|
|
1157
|
+
transition: "background-color 0.2s",
|
|
1158
|
+
"&:hover": {
|
|
1159
|
+
backgroundColor: "action.hover"
|
|
1160
|
+
}
|
|
1161
|
+
},
|
|
1162
|
+
children: currentLang?.svg_flag && /* @__PURE__ */ jsx7(
|
|
1163
|
+
Box5,
|
|
1164
|
+
{
|
|
1165
|
+
sx: {
|
|
1166
|
+
width: 24,
|
|
1167
|
+
height: 16,
|
|
1168
|
+
borderRadius: "3px",
|
|
1169
|
+
overflow: "hidden",
|
|
1170
|
+
flexShrink: 0,
|
|
1171
|
+
boxShadow: "0 0 2px rgba(0,0,0,0.3)",
|
|
1172
|
+
display: "flex",
|
|
1173
|
+
alignItems: "center",
|
|
1174
|
+
justifyContent: "center",
|
|
1175
|
+
"& svg": { width: "100%", height: "100%", display: "block", objectFit: "cover" }
|
|
1176
|
+
},
|
|
1177
|
+
dangerouslySetInnerHTML: { __html: currentLang.svg_flag }
|
|
1178
|
+
}
|
|
1179
|
+
)
|
|
1180
|
+
}
|
|
1181
|
+
) }),
|
|
1182
|
+
/* @__PURE__ */ jsx7(
|
|
1183
|
+
Menu,
|
|
1184
|
+
{
|
|
1185
|
+
id: "language-menu",
|
|
1186
|
+
anchorEl,
|
|
1187
|
+
open,
|
|
1188
|
+
onClose: handleClose,
|
|
1189
|
+
slotProps: {
|
|
1190
|
+
paper: {
|
|
1191
|
+
elevation: 3,
|
|
1192
|
+
sx: {
|
|
1193
|
+
mt: 1,
|
|
1194
|
+
minWidth: 150,
|
|
1195
|
+
borderRadius: 2
|
|
1196
|
+
}
|
|
1197
|
+
}
|
|
1198
|
+
},
|
|
1199
|
+
transformOrigin: { horizontal: "right", vertical: "top" },
|
|
1200
|
+
anchorOrigin: { horizontal: "right", vertical: "bottom" },
|
|
1201
|
+
children: languages.map((lang) => {
|
|
1202
|
+
const isSelected = lang.code === currentLangCode;
|
|
1203
|
+
return /* @__PURE__ */ jsxs6(
|
|
1204
|
+
MenuItem,
|
|
1205
|
+
{
|
|
1206
|
+
selected: isSelected,
|
|
1207
|
+
onClick: () => handleSelectLanguage(lang.code),
|
|
1208
|
+
sx: {
|
|
1209
|
+
display: "flex",
|
|
1210
|
+
alignItems: "center",
|
|
1211
|
+
gap: 1.5,
|
|
1212
|
+
py: 1,
|
|
1213
|
+
px: 2
|
|
1214
|
+
},
|
|
1215
|
+
children: [
|
|
1216
|
+
/* @__PURE__ */ jsx7(
|
|
1217
|
+
Box5,
|
|
1218
|
+
{
|
|
1219
|
+
sx: {
|
|
1220
|
+
width: 22,
|
|
1221
|
+
height: 15,
|
|
1222
|
+
borderRadius: "2px",
|
|
1223
|
+
overflow: "hidden",
|
|
1224
|
+
flexShrink: 0,
|
|
1225
|
+
boxShadow: "0 0 1px rgba(0,0,0,0.4)",
|
|
1226
|
+
"& svg": { width: "100%", height: "100%", display: "block" }
|
|
1227
|
+
},
|
|
1228
|
+
dangerouslySetInnerHTML: { __html: lang.svg_flag }
|
|
1229
|
+
}
|
|
1230
|
+
),
|
|
1231
|
+
/* @__PURE__ */ jsx7(Typography4, { variant: "body2", sx: { fontWeight: isSelected ? 600 : 400 }, children: lang.name })
|
|
1232
|
+
]
|
|
1233
|
+
},
|
|
1234
|
+
lang.code
|
|
1235
|
+
);
|
|
1236
|
+
})
|
|
1237
|
+
}
|
|
1238
|
+
)
|
|
1239
|
+
] });
|
|
1240
|
+
};
|
|
1241
|
+
|
|
847
1242
|
// src/UI/index.ts
|
|
848
1243
|
var UI = {
|
|
849
1244
|
Inputs: {
|
|
@@ -860,11 +1255,16 @@ var UI = {
|
|
|
860
1255
|
UserAvatar: UserAvatarComponent,
|
|
861
1256
|
UserPopover: UserPopoverComponent_default,
|
|
862
1257
|
UserRoleChip: UserRoleChipComponent,
|
|
863
|
-
UserStatusChip: UserStatusChipComponent
|
|
864
|
-
|
|
1258
|
+
UserStatusChip: UserStatusChipComponent,
|
|
1259
|
+
MyAvatar: MyAvatarComponent
|
|
1260
|
+
},
|
|
865
1261
|
/*Layout: {
|
|
866
1262
|
Row: FormRow,
|
|
867
1263
|
},*/
|
|
1264
|
+
Widgets: {
|
|
1265
|
+
ProtectedLanguageSelector: LanguageSelector,
|
|
1266
|
+
PublicLanguageSelector
|
|
1267
|
+
}
|
|
868
1268
|
};
|
|
869
1269
|
export {
|
|
870
1270
|
AIProvider,
|