@serhii.olishevskyi/docs 1.1.2 → 1.1.4
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/{UserPopoverComponent-64KAMDBO.mjs → UserPopoverComponent-ZG4UFBGJ.mjs} +1 -1
- package/dist/{chunk-BAFKGCJJ.mjs → chunk-ERXHWCQ5.mjs} +127 -0
- package/dist/index.d.mts +53 -1
- package/dist/index.d.ts +53 -1
- package/dist/index.js +537 -3
- package/dist/index.mjs +425 -4
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -169,11 +169,89 @@ var init_deviceId = __esm({
|
|
|
169
169
|
});
|
|
170
170
|
|
|
171
171
|
// src/services/session.service.ts
|
|
172
|
-
var trackUserSession, isCurrentSessionValid, getUserLastSeenAt;
|
|
172
|
+
var fetchCompanySessions, trackUserSession, fetchUserSessions, isCurrentSessionValid, groupSessionsByUser, getUserLastSeenAt, getUsersLastSeenMap;
|
|
173
173
|
var init_session_service = __esm({
|
|
174
174
|
"src/services/session.service.ts"() {
|
|
175
175
|
"use strict";
|
|
176
176
|
init_deviceId();
|
|
177
|
+
fetchCompanySessions = async (supabase, companyId, page = 1, pageSize = 5, searchQuery = "") => {
|
|
178
|
+
const currentDeviceId = getDeviceId();
|
|
179
|
+
let query = supabase.from("memberships").select(`
|
|
180
|
+
user_id,
|
|
181
|
+
role,
|
|
182
|
+
employee_post,
|
|
183
|
+
profiles (
|
|
184
|
+
id,
|
|
185
|
+
display_name,
|
|
186
|
+
first_name,
|
|
187
|
+
last_name
|
|
188
|
+
)
|
|
189
|
+
`, { count: "exact" }).eq("company_id", companyId);
|
|
190
|
+
if (searchQuery.trim()) {
|
|
191
|
+
const q = `%${searchQuery.trim()}%`;
|
|
192
|
+
const { data: matchedProfiles } = await supabase.from("profiles").select("id").or(`display_name.ilike.${q},first_name.ilike.${q},last_name.ilike.${q}`);
|
|
193
|
+
const matchedUserIds = (matchedProfiles || []).map((p) => p.id);
|
|
194
|
+
if (matchedUserIds.length > 0) {
|
|
195
|
+
query = query.or(`employee_post.ilike.${q},user_id.in.(${matchedUserIds.join(",")})`);
|
|
196
|
+
} else {
|
|
197
|
+
query = query.ilike("employee_post", q);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
const { data: members, error: membersError } = await query;
|
|
201
|
+
if (membersError) throw membersError;
|
|
202
|
+
if (!members || members.length === 0) {
|
|
203
|
+
return { data: [], totalCount: 0 };
|
|
204
|
+
}
|
|
205
|
+
const userMap = /* @__PURE__ */ new Map();
|
|
206
|
+
members.forEach((m) => {
|
|
207
|
+
const profile = Array.isArray(m.profiles) ? m.profiles[0] : m.profiles;
|
|
208
|
+
const name = profile?.display_name || [profile?.first_name, profile?.last_name].filter(Boolean).join(" ") || "\u041D\u0435\u0432\u0456\u0434\u043E\u043C\u0438\u0439 \u043A\u043E\u0440\u0438\u0441\u0442\u0443\u0432\u0430\u0447";
|
|
209
|
+
userMap.set(m.user_id, {
|
|
210
|
+
name,
|
|
211
|
+
post: m.employee_post || "\u041F\u043E\u0441\u0430\u0434\u0430 \u043D\u0435 \u0432\u043A\u0430\u0437\u0430\u043D\u0430",
|
|
212
|
+
role: m.role || "user"
|
|
213
|
+
});
|
|
214
|
+
});
|
|
215
|
+
const userIds = Array.from(userMap.keys());
|
|
216
|
+
const { data: sessions, error: sessionsError } = await supabase.from("user_sessions").select("*").in("user_id", userIds).order("last_seen_at", { ascending: false });
|
|
217
|
+
if (sessionsError) throw sessionsError;
|
|
218
|
+
const groupsMap = /* @__PURE__ */ new Map();
|
|
219
|
+
(sessions || []).forEach((s) => {
|
|
220
|
+
const userInfo = userMap.get(s.user_id);
|
|
221
|
+
if (!userInfo) return;
|
|
222
|
+
if (!groupsMap.has(s.user_id)) {
|
|
223
|
+
groupsMap.set(s.user_id, {
|
|
224
|
+
userId: s.user_id,
|
|
225
|
+
userName: userInfo.name,
|
|
226
|
+
employeePost: userInfo.post,
|
|
227
|
+
role: userInfo.role,
|
|
228
|
+
sessions: []
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
groupsMap.get(s.user_id).sessions.push({
|
|
232
|
+
id: s.id,
|
|
233
|
+
user_id: s.user_id,
|
|
234
|
+
user_agent: s.user_agent,
|
|
235
|
+
ip_address: s.ip_address,
|
|
236
|
+
created_at: s.created_at,
|
|
237
|
+
last_seen_at: s.last_seen_at,
|
|
238
|
+
device_id: s.device_id,
|
|
239
|
+
is_current: s.device_id === currentDeviceId,
|
|
240
|
+
user_name: userInfo.name,
|
|
241
|
+
employee_post: userInfo.post,
|
|
242
|
+
role: userInfo.role,
|
|
243
|
+
url: s.url
|
|
244
|
+
});
|
|
245
|
+
});
|
|
246
|
+
const allGroupedWithSessions = Array.from(groupsMap.values()).filter((group) => group.sessions.length > 0).sort((a, b) => a.userName.localeCompare(b.userName, "uk"));
|
|
247
|
+
const totalCount = allGroupedWithSessions.length;
|
|
248
|
+
const from = (page - 1) * pageSize;
|
|
249
|
+
const paginatedData = allGroupedWithSessions.slice(from, from + pageSize);
|
|
250
|
+
return {
|
|
251
|
+
data: paginatedData,
|
|
252
|
+
totalCount
|
|
253
|
+
};
|
|
254
|
+
};
|
|
177
255
|
trackUserSession = async (supabase, userId) => {
|
|
178
256
|
const deviceId = getDeviceId();
|
|
179
257
|
let ip = "";
|
|
@@ -196,6 +274,17 @@ var init_session_service = __esm({
|
|
|
196
274
|
{ onConflict: "user_id, device_id" }
|
|
197
275
|
);
|
|
198
276
|
};
|
|
277
|
+
fetchUserSessions = async (supabase) => {
|
|
278
|
+
const currentDeviceId = getDeviceId();
|
|
279
|
+
const { data: { user } } = await supabase.auth.getUser();
|
|
280
|
+
if (!user) return [];
|
|
281
|
+
const { data, error } = await supabase.from("user_sessions").select("*").eq("user_id", user.id).order("last_seen_at", { ascending: false });
|
|
282
|
+
if (error) throw error;
|
|
283
|
+
return (data || []).map((s) => ({
|
|
284
|
+
...s,
|
|
285
|
+
is_current: s.device_id === currentDeviceId
|
|
286
|
+
}));
|
|
287
|
+
};
|
|
199
288
|
isCurrentSessionValid = async (supabase, userId) => {
|
|
200
289
|
try {
|
|
201
290
|
const currentDeviceId = getDeviceId();
|
|
@@ -211,11 +300,42 @@ var init_session_service = __esm({
|
|
|
211
300
|
return true;
|
|
212
301
|
}
|
|
213
302
|
};
|
|
303
|
+
groupSessionsByUser = (sessions) => {
|
|
304
|
+
const groupsMap = /* @__PURE__ */ new Map();
|
|
305
|
+
sessions.forEach((session) => {
|
|
306
|
+
const userId = session.user_id;
|
|
307
|
+
if (!groupsMap.has(userId)) {
|
|
308
|
+
groupsMap.set(userId, {
|
|
309
|
+
userId,
|
|
310
|
+
userName: session.user_name || "\u041D\u0435\u0432\u0456\u0434\u043E\u043C\u0438\u0439 \u043A\u043E\u0440\u0438\u0441\u0442\u0443\u0432\u0430\u0447",
|
|
311
|
+
employeePost: session.employee_post || "\u041F\u043E\u0441\u0430\u0434\u0430 \u043D\u0435 \u0432\u043A\u0430\u0437\u0430\u043D\u0430",
|
|
312
|
+
role: session.role || "user",
|
|
313
|
+
sessions: []
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
groupsMap.get(userId).sessions.push(session);
|
|
317
|
+
});
|
|
318
|
+
return Array.from(groupsMap.values()).sort(
|
|
319
|
+
(a, b) => a.userName.localeCompare(b.userName, "uk")
|
|
320
|
+
);
|
|
321
|
+
};
|
|
214
322
|
getUserLastSeenAt = async (supabase, userId) => {
|
|
215
323
|
const { data, error } = await supabase.from("user_sessions").select("last_seen_at").eq("user_id", userId).order("last_seen_at", { ascending: false }).limit(1).maybeSingle();
|
|
216
324
|
if (error || !data) return null;
|
|
217
325
|
return data.last_seen_at;
|
|
218
326
|
};
|
|
327
|
+
getUsersLastSeenMap = async (supabase, userIds) => {
|
|
328
|
+
if (!userIds.length) return {};
|
|
329
|
+
const { data, error } = await supabase.from("user_sessions").select("user_id, last_seen_at").in("user_id", userIds).order("last_seen_at", { ascending: false });
|
|
330
|
+
if (error || !data) return {};
|
|
331
|
+
const resultMap = {};
|
|
332
|
+
for (const session of data) {
|
|
333
|
+
if (!resultMap[session.user_id]) {
|
|
334
|
+
resultMap[session.user_id] = session.last_seen_at;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
return resultMap;
|
|
338
|
+
};
|
|
219
339
|
}
|
|
220
340
|
});
|
|
221
341
|
|
|
@@ -2617,6 +2737,7 @@ __export(index_exports, {
|
|
|
2617
2737
|
ConfirmationProvider: () => ConfirmationProvider,
|
|
2618
2738
|
LocalizationProvider: () => LocalizationProvider,
|
|
2619
2739
|
Providers: () => Providers,
|
|
2740
|
+
Services: () => Services,
|
|
2620
2741
|
SupabaseProvider: () => SupabaseProvider,
|
|
2621
2742
|
ThemeProvider: () => ThemeProvider,
|
|
2622
2743
|
ToastProvider: () => ToastProvider,
|
|
@@ -3452,6 +3573,399 @@ init_CopyClipboardButtonComponent();
|
|
|
3452
3573
|
init_UserRoleChipComponent();
|
|
3453
3574
|
init_UserStatusChipComponent();
|
|
3454
3575
|
init_UserPopoverComponent();
|
|
3576
|
+
|
|
3577
|
+
// src/UI/components/data.display/MyAvatarComponent.tsx
|
|
3578
|
+
var import_react23 = require("react");
|
|
3579
|
+
var import_material16 = require("@mui/material");
|
|
3580
|
+
init_context();
|
|
3581
|
+
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
3582
|
+
var getInitials2 = (name) => {
|
|
3583
|
+
if (!name) return "?";
|
|
3584
|
+
const parts = name.trim().split(" ");
|
|
3585
|
+
if (parts.length >= 2) {
|
|
3586
|
+
return `${parts[0][0]}${parts[1][0]}`.toUpperCase();
|
|
3587
|
+
}
|
|
3588
|
+
return name[0].toUpperCase();
|
|
3589
|
+
};
|
|
3590
|
+
var MyAvatarComponent = ({
|
|
3591
|
+
size = 40,
|
|
3592
|
+
disableBorder = false,
|
|
3593
|
+
disableShadow = false,
|
|
3594
|
+
disablePopover = false,
|
|
3595
|
+
sx = {}
|
|
3596
|
+
}) => {
|
|
3597
|
+
const { profile: userProfile, loading: isLoading } = useAuth();
|
|
3598
|
+
const [anchorEl, setAnchorEl] = (0, import_react23.useState)(null);
|
|
3599
|
+
const handlePopoverOpen = (event) => {
|
|
3600
|
+
if (!disablePopover) {
|
|
3601
|
+
setAnchorEl(event.currentTarget);
|
|
3602
|
+
}
|
|
3603
|
+
};
|
|
3604
|
+
const handlePopoverClose = () => {
|
|
3605
|
+
setAnchorEl(null);
|
|
3606
|
+
};
|
|
3607
|
+
const isPopoverOpen = Boolean(anchorEl);
|
|
3608
|
+
if (isLoading) {
|
|
3609
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
3610
|
+
import_material16.Skeleton,
|
|
3611
|
+
{
|
|
3612
|
+
variant: "circular",
|
|
3613
|
+
width: size,
|
|
3614
|
+
height: size,
|
|
3615
|
+
sx: { display: "inline-block", flexShrink: 0, ...sx }
|
|
3616
|
+
}
|
|
3617
|
+
);
|
|
3618
|
+
}
|
|
3619
|
+
const initials = getInitials2(userProfile?.display_name || "");
|
|
3620
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
|
|
3621
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
3622
|
+
import_material16.Avatar,
|
|
3623
|
+
{
|
|
3624
|
+
src: userProfile?.avatar_url || void 0,
|
|
3625
|
+
alt: userProfile?.display_name || "User Avatar",
|
|
3626
|
+
onMouseEnter: handlePopoverOpen,
|
|
3627
|
+
onMouseLeave: handlePopoverClose,
|
|
3628
|
+
sx: {
|
|
3629
|
+
width: size,
|
|
3630
|
+
height: size,
|
|
3631
|
+
fontSize: size * 0.4,
|
|
3632
|
+
fontWeight: 600,
|
|
3633
|
+
bgcolor: "primary.main",
|
|
3634
|
+
color: "primary.contrastText",
|
|
3635
|
+
cursor: disablePopover ? void 0 : "pointer",
|
|
3636
|
+
transition: "transform 0.2s ease, box-shadow 0.2s ease",
|
|
3637
|
+
border: disableBorder ? "none" : "2px solid",
|
|
3638
|
+
borderColor: "background.paper",
|
|
3639
|
+
boxShadow: disableShadow ? "none" : 2,
|
|
3640
|
+
"&:hover": {
|
|
3641
|
+
transform: disablePopover ? "none" : "scale(1.05)"
|
|
3642
|
+
},
|
|
3643
|
+
...sx
|
|
3644
|
+
},
|
|
3645
|
+
children: !userProfile?.avatar_url && initials
|
|
3646
|
+
}
|
|
3647
|
+
),
|
|
3648
|
+
!disablePopover && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
3649
|
+
import_material16.Popover,
|
|
3650
|
+
{
|
|
3651
|
+
id: `avatar-popover-${userProfile?.id}`,
|
|
3652
|
+
open: isPopoverOpen,
|
|
3653
|
+
anchorEl,
|
|
3654
|
+
anchorOrigin: {
|
|
3655
|
+
vertical: "bottom",
|
|
3656
|
+
horizontal: "center"
|
|
3657
|
+
},
|
|
3658
|
+
transformOrigin: {
|
|
3659
|
+
vertical: "top",
|
|
3660
|
+
horizontal: "center"
|
|
3661
|
+
},
|
|
3662
|
+
onClose: handlePopoverClose,
|
|
3663
|
+
disableRestoreFocus: true,
|
|
3664
|
+
disableAutoFocus: true,
|
|
3665
|
+
disableEnforceFocus: true,
|
|
3666
|
+
sx: {
|
|
3667
|
+
pointerEvents: "none",
|
|
3668
|
+
mt: 1
|
|
3669
|
+
},
|
|
3670
|
+
slotProps: {
|
|
3671
|
+
paper: {
|
|
3672
|
+
sx: {
|
|
3673
|
+
p: 1.5,
|
|
3674
|
+
borderRadius: 2,
|
|
3675
|
+
boxShadow: 3
|
|
3676
|
+
}
|
|
3677
|
+
}
|
|
3678
|
+
},
|
|
3679
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_material16.Box, { sx: { display: "flex", flexDirection: "column", alignItems: "center", gap: 0.5 }, children: [
|
|
3680
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_material16.Typography, { variant: "subtitle2", sx: { fontWeight: 600 }, children: userProfile?.display_name }),
|
|
3681
|
+
userProfile?.email && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_material16.Typography, { variant: "caption", color: "text.secondary", children: userProfile.email })
|
|
3682
|
+
] })
|
|
3683
|
+
}
|
|
3684
|
+
)
|
|
3685
|
+
] });
|
|
3686
|
+
};
|
|
3687
|
+
|
|
3688
|
+
// src/i18n/LanguageSelector.tsx
|
|
3689
|
+
var import_react24 = require("react");
|
|
3690
|
+
var import_react_i18next5 = require("react-i18next");
|
|
3691
|
+
var import_material17 = require("@mui/material");
|
|
3692
|
+
init_LocalizationProvider();
|
|
3693
|
+
init_UserSettingsProvider();
|
|
3694
|
+
init_SupabaseProvider();
|
|
3695
|
+
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
3696
|
+
var LanguageSelector = () => {
|
|
3697
|
+
const supabase = useSupabase();
|
|
3698
|
+
const { i18n: i18n2 } = (0, import_react_i18next5.useTranslation)();
|
|
3699
|
+
const [languages, setLanguages] = (0, import_react24.useState)([]);
|
|
3700
|
+
const [loading, setLoading] = (0, import_react24.useState)(true);
|
|
3701
|
+
const { changeLanguage } = useLocalization();
|
|
3702
|
+
const { settings: userSettings, setLanguage } = useUserSettings();
|
|
3703
|
+
const [anchorEl, setAnchorEl] = (0, import_react24.useState)(null);
|
|
3704
|
+
const open = Boolean(anchorEl);
|
|
3705
|
+
(0, import_react24.useEffect)(() => {
|
|
3706
|
+
const fetchLanguages = async () => {
|
|
3707
|
+
try {
|
|
3708
|
+
const { data, error } = await supabase.from("languages").select("code, name, svg_flag").eq("enabled", true);
|
|
3709
|
+
if (error) throw error;
|
|
3710
|
+
setLanguages(data || []);
|
|
3711
|
+
if (userSettings.language) changeLanguage(userSettings.language);
|
|
3712
|
+
} catch (err) {
|
|
3713
|
+
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);
|
|
3714
|
+
} finally {
|
|
3715
|
+
setLoading(false);
|
|
3716
|
+
}
|
|
3717
|
+
};
|
|
3718
|
+
fetchLanguages();
|
|
3719
|
+
}, []);
|
|
3720
|
+
const handleClick = (event) => {
|
|
3721
|
+
setAnchorEl(event.currentTarget);
|
|
3722
|
+
};
|
|
3723
|
+
const handleClose = () => {
|
|
3724
|
+
setAnchorEl(null);
|
|
3725
|
+
};
|
|
3726
|
+
const handleSelectLanguage = (langCode) => {
|
|
3727
|
+
changeLanguage(langCode);
|
|
3728
|
+
setLanguage(langCode);
|
|
3729
|
+
handleClose();
|
|
3730
|
+
};
|
|
3731
|
+
if (loading) {
|
|
3732
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_material17.CircularProgress, { size: 20, color: "inherit", sx: { mx: 1 } });
|
|
3733
|
+
}
|
|
3734
|
+
const rawCurrentLang = i18n2.language || "uk";
|
|
3735
|
+
const currentLangCode = rawCurrentLang.split("-")[0];
|
|
3736
|
+
const currentLang = languages.find((l) => l.code === currentLangCode) || languages[0];
|
|
3737
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_jsx_runtime27.Fragment, { children: [
|
|
3738
|
+
/* @__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)(
|
|
3739
|
+
import_material17.IconButton,
|
|
3740
|
+
{
|
|
3741
|
+
onClick: handleClick,
|
|
3742
|
+
size: "small",
|
|
3743
|
+
"aria-controls": open ? "language-menu" : void 0,
|
|
3744
|
+
"aria-haspopup": "true",
|
|
3745
|
+
"aria-expanded": open ? "true" : void 0,
|
|
3746
|
+
sx: {
|
|
3747
|
+
p: 1,
|
|
3748
|
+
borderRadius: 2,
|
|
3749
|
+
transition: "background-color 0.2s",
|
|
3750
|
+
"&:hover": {
|
|
3751
|
+
backgroundColor: "action.hover"
|
|
3752
|
+
}
|
|
3753
|
+
},
|
|
3754
|
+
children: currentLang?.svg_flag && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
3755
|
+
import_material17.Box,
|
|
3756
|
+
{
|
|
3757
|
+
sx: {
|
|
3758
|
+
width: 24,
|
|
3759
|
+
height: 16,
|
|
3760
|
+
borderRadius: "3px",
|
|
3761
|
+
overflow: "hidden",
|
|
3762
|
+
flexShrink: 0,
|
|
3763
|
+
boxShadow: "0 0 2px rgba(0,0,0,0.3)",
|
|
3764
|
+
display: "flex",
|
|
3765
|
+
alignItems: "center",
|
|
3766
|
+
justifyContent: "center",
|
|
3767
|
+
"& svg": { width: "100%", height: "100%", display: "block", objectFit: "cover" }
|
|
3768
|
+
},
|
|
3769
|
+
dangerouslySetInnerHTML: { __html: currentLang.svg_flag }
|
|
3770
|
+
}
|
|
3771
|
+
)
|
|
3772
|
+
}
|
|
3773
|
+
) }),
|
|
3774
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
3775
|
+
import_material17.Menu,
|
|
3776
|
+
{
|
|
3777
|
+
id: "language-menu",
|
|
3778
|
+
anchorEl,
|
|
3779
|
+
open,
|
|
3780
|
+
onClose: handleClose,
|
|
3781
|
+
slotProps: {
|
|
3782
|
+
paper: {
|
|
3783
|
+
elevation: 3,
|
|
3784
|
+
sx: {
|
|
3785
|
+
mt: 1,
|
|
3786
|
+
minWidth: 150,
|
|
3787
|
+
borderRadius: 2
|
|
3788
|
+
}
|
|
3789
|
+
}
|
|
3790
|
+
},
|
|
3791
|
+
transformOrigin: { horizontal: "right", vertical: "top" },
|
|
3792
|
+
anchorOrigin: { horizontal: "right", vertical: "bottom" },
|
|
3793
|
+
children: languages.map((lang) => {
|
|
3794
|
+
const isSelected = lang.code === currentLangCode;
|
|
3795
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
|
|
3796
|
+
import_material17.MenuItem,
|
|
3797
|
+
{
|
|
3798
|
+
selected: isSelected,
|
|
3799
|
+
onClick: () => handleSelectLanguage(lang.code),
|
|
3800
|
+
sx: {
|
|
3801
|
+
display: "flex",
|
|
3802
|
+
alignItems: "center",
|
|
3803
|
+
gap: 1.5,
|
|
3804
|
+
py: 1,
|
|
3805
|
+
px: 2
|
|
3806
|
+
},
|
|
3807
|
+
children: [
|
|
3808
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
3809
|
+
import_material17.Box,
|
|
3810
|
+
{
|
|
3811
|
+
sx: {
|
|
3812
|
+
width: 22,
|
|
3813
|
+
height: 15,
|
|
3814
|
+
borderRadius: "2px",
|
|
3815
|
+
overflow: "hidden",
|
|
3816
|
+
flexShrink: 0,
|
|
3817
|
+
boxShadow: "0 0 1px rgba(0,0,0,0.4)",
|
|
3818
|
+
"& svg": { width: "100%", height: "100%", display: "block" }
|
|
3819
|
+
},
|
|
3820
|
+
dangerouslySetInnerHTML: { __html: lang.svg_flag }
|
|
3821
|
+
}
|
|
3822
|
+
),
|
|
3823
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_material17.Typography, { variant: "body2", sx: { fontWeight: isSelected ? 600 : 400 }, children: lang.name })
|
|
3824
|
+
]
|
|
3825
|
+
},
|
|
3826
|
+
lang.code
|
|
3827
|
+
);
|
|
3828
|
+
})
|
|
3829
|
+
}
|
|
3830
|
+
)
|
|
3831
|
+
] });
|
|
3832
|
+
};
|
|
3833
|
+
var PublicLanguageSelector = () => {
|
|
3834
|
+
const supabase = useSupabase();
|
|
3835
|
+
const { i18n: i18n2 } = (0, import_react_i18next5.useTranslation)();
|
|
3836
|
+
const { changeLanguage } = useLocalization();
|
|
3837
|
+
const [languages, setLanguages] = (0, import_react24.useState)([]);
|
|
3838
|
+
const [loading, setLoading] = (0, import_react24.useState)(true);
|
|
3839
|
+
const [anchorEl, setAnchorEl] = (0, import_react24.useState)(null);
|
|
3840
|
+
const open = Boolean(anchorEl);
|
|
3841
|
+
(0, import_react24.useEffect)(() => {
|
|
3842
|
+
const fetchLanguages = async () => {
|
|
3843
|
+
try {
|
|
3844
|
+
const { data, error } = await supabase.from("languages").select("code, name, svg_flag").eq("enabled", true);
|
|
3845
|
+
if (error) throw error;
|
|
3846
|
+
setLanguages(data || []);
|
|
3847
|
+
} catch (err) {
|
|
3848
|
+
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);
|
|
3849
|
+
} finally {
|
|
3850
|
+
setLoading(false);
|
|
3851
|
+
}
|
|
3852
|
+
};
|
|
3853
|
+
fetchLanguages();
|
|
3854
|
+
}, []);
|
|
3855
|
+
const handleClick = (event) => {
|
|
3856
|
+
setAnchorEl(event.currentTarget);
|
|
3857
|
+
};
|
|
3858
|
+
const handleClose = () => {
|
|
3859
|
+
setAnchorEl(null);
|
|
3860
|
+
};
|
|
3861
|
+
const handleSelectLanguage = (langCode) => {
|
|
3862
|
+
changeLanguage(langCode);
|
|
3863
|
+
handleClose();
|
|
3864
|
+
};
|
|
3865
|
+
if (loading) {
|
|
3866
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_material17.CircularProgress, { size: 20, color: "inherit", sx: { mx: 1 } });
|
|
3867
|
+
}
|
|
3868
|
+
const rawCurrentLang = i18n2.language || "uk";
|
|
3869
|
+
const currentLangCode = rawCurrentLang.split("-")[0];
|
|
3870
|
+
const currentLang = languages.find((l) => l.code === currentLangCode) || languages[0];
|
|
3871
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_jsx_runtime27.Fragment, { children: [
|
|
3872
|
+
/* @__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)(
|
|
3873
|
+
import_material17.IconButton,
|
|
3874
|
+
{
|
|
3875
|
+
onClick: handleClick,
|
|
3876
|
+
size: "small",
|
|
3877
|
+
"aria-controls": open ? "language-menu" : void 0,
|
|
3878
|
+
"aria-haspopup": "true",
|
|
3879
|
+
"aria-expanded": open ? "true" : void 0,
|
|
3880
|
+
sx: {
|
|
3881
|
+
p: 1,
|
|
3882
|
+
borderRadius: 2,
|
|
3883
|
+
transition: "background-color 0.2s",
|
|
3884
|
+
"&:hover": {
|
|
3885
|
+
backgroundColor: "action.hover"
|
|
3886
|
+
}
|
|
3887
|
+
},
|
|
3888
|
+
children: currentLang?.svg_flag && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
3889
|
+
import_material17.Box,
|
|
3890
|
+
{
|
|
3891
|
+
sx: {
|
|
3892
|
+
width: 24,
|
|
3893
|
+
height: 16,
|
|
3894
|
+
borderRadius: "3px",
|
|
3895
|
+
overflow: "hidden",
|
|
3896
|
+
flexShrink: 0,
|
|
3897
|
+
boxShadow: "0 0 2px rgba(0,0,0,0.3)",
|
|
3898
|
+
display: "flex",
|
|
3899
|
+
alignItems: "center",
|
|
3900
|
+
justifyContent: "center",
|
|
3901
|
+
"& svg": { width: "100%", height: "100%", display: "block", objectFit: "cover" }
|
|
3902
|
+
},
|
|
3903
|
+
dangerouslySetInnerHTML: { __html: currentLang.svg_flag }
|
|
3904
|
+
}
|
|
3905
|
+
)
|
|
3906
|
+
}
|
|
3907
|
+
) }),
|
|
3908
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
3909
|
+
import_material17.Menu,
|
|
3910
|
+
{
|
|
3911
|
+
id: "language-menu",
|
|
3912
|
+
anchorEl,
|
|
3913
|
+
open,
|
|
3914
|
+
onClose: handleClose,
|
|
3915
|
+
slotProps: {
|
|
3916
|
+
paper: {
|
|
3917
|
+
elevation: 3,
|
|
3918
|
+
sx: {
|
|
3919
|
+
mt: 1,
|
|
3920
|
+
minWidth: 150,
|
|
3921
|
+
borderRadius: 2
|
|
3922
|
+
}
|
|
3923
|
+
}
|
|
3924
|
+
},
|
|
3925
|
+
transformOrigin: { horizontal: "right", vertical: "top" },
|
|
3926
|
+
anchorOrigin: { horizontal: "right", vertical: "bottom" },
|
|
3927
|
+
children: languages.map((lang) => {
|
|
3928
|
+
const isSelected = lang.code === currentLangCode;
|
|
3929
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
|
|
3930
|
+
import_material17.MenuItem,
|
|
3931
|
+
{
|
|
3932
|
+
selected: isSelected,
|
|
3933
|
+
onClick: () => handleSelectLanguage(lang.code),
|
|
3934
|
+
sx: {
|
|
3935
|
+
display: "flex",
|
|
3936
|
+
alignItems: "center",
|
|
3937
|
+
gap: 1.5,
|
|
3938
|
+
py: 1,
|
|
3939
|
+
px: 2
|
|
3940
|
+
},
|
|
3941
|
+
children: [
|
|
3942
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
3943
|
+
import_material17.Box,
|
|
3944
|
+
{
|
|
3945
|
+
sx: {
|
|
3946
|
+
width: 22,
|
|
3947
|
+
height: 15,
|
|
3948
|
+
borderRadius: "2px",
|
|
3949
|
+
overflow: "hidden",
|
|
3950
|
+
flexShrink: 0,
|
|
3951
|
+
boxShadow: "0 0 1px rgba(0,0,0,0.4)",
|
|
3952
|
+
"& svg": { width: "100%", height: "100%", display: "block" }
|
|
3953
|
+
},
|
|
3954
|
+
dangerouslySetInnerHTML: { __html: lang.svg_flag }
|
|
3955
|
+
}
|
|
3956
|
+
),
|
|
3957
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_material17.Typography, { variant: "body2", sx: { fontWeight: isSelected ? 600 : 400 }, children: lang.name })
|
|
3958
|
+
]
|
|
3959
|
+
},
|
|
3960
|
+
lang.code
|
|
3961
|
+
);
|
|
3962
|
+
})
|
|
3963
|
+
}
|
|
3964
|
+
)
|
|
3965
|
+
] });
|
|
3966
|
+
};
|
|
3967
|
+
|
|
3968
|
+
// src/UI/index.ts
|
|
3455
3969
|
var UI = {
|
|
3456
3970
|
Inputs: {
|
|
3457
3971
|
TextField: TextFieldComponent,
|
|
@@ -3467,16 +3981,35 @@ var UI = {
|
|
|
3467
3981
|
UserAvatar: UserAvatarComponent,
|
|
3468
3982
|
UserPopover: UserPopoverComponent_default,
|
|
3469
3983
|
UserRoleChip: UserRoleChipComponent,
|
|
3470
|
-
UserStatusChip: UserStatusChipComponent
|
|
3471
|
-
|
|
3984
|
+
UserStatusChip: UserStatusChipComponent,
|
|
3985
|
+
MyAvatar: MyAvatarComponent
|
|
3986
|
+
},
|
|
3472
3987
|
/*Layout: {
|
|
3473
3988
|
Row: FormRow,
|
|
3474
3989
|
},*/
|
|
3990
|
+
Widgets: {
|
|
3991
|
+
ProtectedLanguageSelector: LanguageSelector,
|
|
3992
|
+
PublicLanguageSelector
|
|
3993
|
+
}
|
|
3475
3994
|
};
|
|
3476
3995
|
|
|
3477
3996
|
// src/index.ts
|
|
3478
3997
|
init_context();
|
|
3479
3998
|
init_context();
|
|
3999
|
+
|
|
4000
|
+
// src/services/index.ts
|
|
4001
|
+
init_session_service();
|
|
4002
|
+
var Services = {
|
|
4003
|
+
SessionService: {
|
|
4004
|
+
fetchCompanySessions,
|
|
4005
|
+
trackUserSession,
|
|
4006
|
+
fetchUserSessions,
|
|
4007
|
+
isCurrentSessionValid,
|
|
4008
|
+
groupSessionsByUser,
|
|
4009
|
+
getUserLastSeenAt,
|
|
4010
|
+
getUsersLastSeenMap
|
|
4011
|
+
}
|
|
4012
|
+
};
|
|
3480
4013
|
// Annotate the CommonJS export names for ESM import in node:
|
|
3481
4014
|
0 && (module.exports = {
|
|
3482
4015
|
AIProvider,
|
|
@@ -3486,6 +4019,7 @@ init_context();
|
|
|
3486
4019
|
ConfirmationProvider,
|
|
3487
4020
|
LocalizationProvider,
|
|
3488
4021
|
Providers,
|
|
4022
|
+
Services,
|
|
3489
4023
|
SupabaseProvider,
|
|
3490
4024
|
ThemeProvider,
|
|
3491
4025
|
ToastProvider,
|