@serhii.olishevskyi/docs 1.0.6 → 1.0.8
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-MG2V632M.mjs → UserPopoverComponent-YKVTSRTJ.mjs} +1 -1
- package/dist/{chunk-UYCEKHKQ.mjs → chunk-ABYNAO4A.mjs} +223 -0
- package/dist/index.d.mts +67 -2
- package/dist/index.d.ts +67 -2
- package/dist/index.js +228 -2
- package/dist/index.mjs +6 -2
- package/package.json +1 -1
|
@@ -189,7 +189,54 @@ var config_default = i18n;
|
|
|
189
189
|
// src/context/AuthProvider.tsx
|
|
190
190
|
import { createContext as createContext3, useContext as useContext3, useEffect, useState, useCallback, useRef } from "react";
|
|
191
191
|
|
|
192
|
+
// src/utils/deviceId.ts
|
|
193
|
+
var getDeviceId = () => {
|
|
194
|
+
let deviceId = localStorage.getItem("app_device_id");
|
|
195
|
+
if (!deviceId) {
|
|
196
|
+
deviceId = crypto.randomUUID();
|
|
197
|
+
localStorage.setItem("app_device_id", deviceId);
|
|
198
|
+
}
|
|
199
|
+
return deviceId;
|
|
200
|
+
};
|
|
201
|
+
|
|
192
202
|
// src/services/session.service.ts
|
|
203
|
+
var trackUserSession = async (supabase, userId) => {
|
|
204
|
+
const deviceId = getDeviceId();
|
|
205
|
+
let ip = "";
|
|
206
|
+
try {
|
|
207
|
+
const ipRes = await fetch("https://api.ipify.org?format=json");
|
|
208
|
+
const ipData = await ipRes.json();
|
|
209
|
+
ip = ipData.ip;
|
|
210
|
+
} catch (e) {
|
|
211
|
+
console.warn("Failed to fetch IP address", e);
|
|
212
|
+
}
|
|
213
|
+
await supabase.from("user_sessions").upsert(
|
|
214
|
+
{
|
|
215
|
+
user_id: userId,
|
|
216
|
+
device_id: deviceId,
|
|
217
|
+
user_agent: navigator.userAgent,
|
|
218
|
+
ip_address: ip,
|
|
219
|
+
url: window.location.href,
|
|
220
|
+
last_seen_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
221
|
+
},
|
|
222
|
+
{ onConflict: "user_id, device_id" }
|
|
223
|
+
);
|
|
224
|
+
};
|
|
225
|
+
var isCurrentSessionValid = async (supabase, userId) => {
|
|
226
|
+
try {
|
|
227
|
+
const currentDeviceId = getDeviceId();
|
|
228
|
+
const { data, error } = await supabase.from("user_sessions").select("id").eq("user_id", userId).eq("device_id", currentDeviceId).maybeSingle();
|
|
229
|
+
if (error) {
|
|
230
|
+
console.warn("\u041F\u043E\u043C\u0438\u043B\u043A\u0430 \u043F\u0435\u0440\u0435\u0432\u0456\u0440\u043A\u0438 \u0441\u0435\u0441\u0456\u0457:", error.message);
|
|
231
|
+
return true;
|
|
232
|
+
}
|
|
233
|
+
if (!data) return false;
|
|
234
|
+
return true;
|
|
235
|
+
} catch (err) {
|
|
236
|
+
console.error("\u041D\u0435\u0441\u043F\u043E\u0434\u0456\u0432\u0430\u043D\u0430 \u043F\u043E\u043C\u0438\u043B\u043A\u0430 \u043F\u0440\u0438 \u043F\u0435\u0440\u0435\u0432\u0456\u0440\u0446\u0456 \u0441\u0435\u0441\u0456\u0457:", err);
|
|
237
|
+
return true;
|
|
238
|
+
}
|
|
239
|
+
};
|
|
193
240
|
var getUserLastSeenAt = async (supabase, userId) => {
|
|
194
241
|
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();
|
|
195
242
|
if (error || !data) return null;
|
|
@@ -199,6 +246,179 @@ var getUserLastSeenAt = async (supabase, userId) => {
|
|
|
199
246
|
// src/context/AuthProvider.tsx
|
|
200
247
|
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
201
248
|
var AuthContext = createContext3(void 0);
|
|
249
|
+
var AuthProvider = ({ children }) => {
|
|
250
|
+
const supabase = useSupabase();
|
|
251
|
+
const [user, setUser] = useState(null);
|
|
252
|
+
const [profile, setProfile] = useState(null);
|
|
253
|
+
const [membership, setMembership] = useState(null);
|
|
254
|
+
const [session, setSession] = useState(null);
|
|
255
|
+
const [loading, setLoading] = useState(true);
|
|
256
|
+
const currentUserIdRef = useRef(null);
|
|
257
|
+
const fetchProfileAndMembership = useCallback(async (userId) => {
|
|
258
|
+
try {
|
|
259
|
+
const { data, error } = await supabase.rpc("get_user_avatar_and_profile", {
|
|
260
|
+
p_user_id: userId
|
|
261
|
+
});
|
|
262
|
+
if (error || !data) {
|
|
263
|
+
console.error("Error fetching user context via RPC:", error?.message);
|
|
264
|
+
setProfile(null);
|
|
265
|
+
setMembership(null);
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
const response = data;
|
|
269
|
+
if (response?.profile) {
|
|
270
|
+
const profileData = response.profile;
|
|
271
|
+
if (profileData.avatar_path && !profileData.avatar_path.startsWith("http")) {
|
|
272
|
+
const cleanPath = profileData.avatar_path.replace(/^user-media\//, "");
|
|
273
|
+
const { data: avatarSignedData } = await supabase.storage.from("user-media").createSignedUrl(cleanPath, 3600);
|
|
274
|
+
if (avatarSignedData?.signedUrl) {
|
|
275
|
+
profileData.avatar_url = avatarSignedData.signedUrl;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
if (profileData.cover_image_path && !profileData.cover_image_path.startsWith("http")) {
|
|
279
|
+
const cleanPath = profileData.cover_image_path.replace(/^user-media\//, "");
|
|
280
|
+
const { data: coverSignedData } = await supabase.storage.from("user-media").createSignedUrl(cleanPath, 3600);
|
|
281
|
+
if (coverSignedData?.signedUrl) {
|
|
282
|
+
profileData.cover_image_url = coverSignedData.signedUrl;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
let updatedMembership = response.membership;
|
|
286
|
+
if (updatedMembership) {
|
|
287
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
288
|
+
const isFirstLogin = !updatedMembership.first_login_at;
|
|
289
|
+
const updateData = {
|
|
290
|
+
last_login_at: now,
|
|
291
|
+
...isFirstLogin && { first_login_at: now }
|
|
292
|
+
};
|
|
293
|
+
const { error: updateError } = await supabase.from("memberships").update(updateData).eq("id", updatedMembership.id);
|
|
294
|
+
if (updateError) {
|
|
295
|
+
console.error("Error updating membership login timestamps:", updateError.message);
|
|
296
|
+
} else {
|
|
297
|
+
updatedMembership = {
|
|
298
|
+
...updatedMembership,
|
|
299
|
+
...updateData
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
setProfile(profileData);
|
|
304
|
+
setMembership(updatedMembership);
|
|
305
|
+
}
|
|
306
|
+
} catch (err) {
|
|
307
|
+
console.error("Unexpected error fetching user context:", err);
|
|
308
|
+
setProfile(null);
|
|
309
|
+
setMembership(null);
|
|
310
|
+
}
|
|
311
|
+
}, []);
|
|
312
|
+
const refreshProfile = async () => {
|
|
313
|
+
if (currentUserIdRef.current) {
|
|
314
|
+
await fetchProfileAndMembership(currentUserIdRef.current);
|
|
315
|
+
}
|
|
316
|
+
};
|
|
317
|
+
const signOut = useCallback(async () => {
|
|
318
|
+
await supabase.auth.signOut();
|
|
319
|
+
currentUserIdRef.current = null;
|
|
320
|
+
setUser(null);
|
|
321
|
+
setProfile(null);
|
|
322
|
+
setMembership(null);
|
|
323
|
+
setSession(null);
|
|
324
|
+
}, []);
|
|
325
|
+
const setActiveCompany = async (companyId) => {
|
|
326
|
+
if (!user) {
|
|
327
|
+
throw new Error("\u041F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044C \u043D\u0435 \u0430\u0432\u0442\u043E\u0440\u0438\u0437\u043E\u0432\u0430\u043D");
|
|
328
|
+
}
|
|
329
|
+
const { error: profileError } = await supabase.from("profiles").update({ active_company_id: companyId }).eq("id", user.id);
|
|
330
|
+
if (profileError) {
|
|
331
|
+
console.error("Error updating active company:", profileError);
|
|
332
|
+
throw new Error(profileError.message);
|
|
333
|
+
}
|
|
334
|
+
await refreshProfile();
|
|
335
|
+
};
|
|
336
|
+
const updateProfile = (newProfileData) => {
|
|
337
|
+
setProfile((prev) => prev ? { ...prev, ...newProfileData } : null);
|
|
338
|
+
};
|
|
339
|
+
useEffect(() => {
|
|
340
|
+
const { data: { subscription } } = supabase.auth.onAuthStateChange(async (event, currentSession) => {
|
|
341
|
+
if (event === "TOKEN_REFRESHED" && currentUserIdRef.current === currentSession?.user?.id) {
|
|
342
|
+
setSession(currentSession);
|
|
343
|
+
return;
|
|
344
|
+
}
|
|
345
|
+
const currentUser = currentSession?.user ?? null;
|
|
346
|
+
const newUserId = currentUser?.id ?? null;
|
|
347
|
+
if (newUserId !== currentUserIdRef.current) {
|
|
348
|
+
currentUserIdRef.current = newUserId;
|
|
349
|
+
setUser(currentUser);
|
|
350
|
+
if (newUserId) {
|
|
351
|
+
await trackUserSession(supabase, newUserId).catch(console.error);
|
|
352
|
+
const isAuthLinkEvent = event === "SIGNED_IN" || event === "INITIAL_SESSION" || event === "PASSWORD_RECOVERY";
|
|
353
|
+
if (!isAuthLinkEvent) {
|
|
354
|
+
const isValid = await isCurrentSessionValid(supabase, newUserId);
|
|
355
|
+
if (!isValid) {
|
|
356
|
+
await supabase.auth.signOut();
|
|
357
|
+
currentUserIdRef.current = null;
|
|
358
|
+
setUser(null);
|
|
359
|
+
setProfile(null);
|
|
360
|
+
setMembership(null);
|
|
361
|
+
setLoading(false);
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
await fetchProfileAndMembership(newUserId);
|
|
366
|
+
setSession(currentSession);
|
|
367
|
+
} else {
|
|
368
|
+
setProfile(null);
|
|
369
|
+
setMembership(null);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
setLoading(false);
|
|
373
|
+
});
|
|
374
|
+
return () => {
|
|
375
|
+
subscription.unsubscribe();
|
|
376
|
+
};
|
|
377
|
+
}, [fetchProfileAndMembership]);
|
|
378
|
+
useEffect(() => {
|
|
379
|
+
if (!user) return;
|
|
380
|
+
const checkSession = async () => {
|
|
381
|
+
try {
|
|
382
|
+
const valid = await isCurrentSessionValid(supabase, user.id);
|
|
383
|
+
if (!valid) {
|
|
384
|
+
console.warn("\u0421\u0435\u0441\u0456\u044E \u0432\u0456\u0434\u043A\u043B\u0438\u043A\u0430\u043D\u043E \u0437 \u0456\u043D\u0448\u043E\u0433\u043E \u043F\u0440\u0438\u0441\u0442\u0440\u043E\u044E.");
|
|
385
|
+
await signOut();
|
|
386
|
+
}
|
|
387
|
+
} catch (err) {
|
|
388
|
+
console.error("\u041F\u043E\u043C\u0438\u043B\u043A\u0430 \u043F\u0440\u0438 \u043F\u0435\u0440\u0435\u0432\u0456\u0440\u0446\u0456 \u0441\u0435\u0441\u0456\u0457:", err);
|
|
389
|
+
}
|
|
390
|
+
};
|
|
391
|
+
const interval = setInterval(checkSession, 6e4);
|
|
392
|
+
const handleFocus = () => checkSession();
|
|
393
|
+
window.addEventListener("focus", handleFocus);
|
|
394
|
+
return () => {
|
|
395
|
+
clearInterval(interval);
|
|
396
|
+
window.removeEventListener("focus", handleFocus);
|
|
397
|
+
};
|
|
398
|
+
}, [user, signOut]);
|
|
399
|
+
const activeCompanyId = profile?.active_company_id ?? null;
|
|
400
|
+
const userRole = membership?.role ?? null;
|
|
401
|
+
return /* @__PURE__ */ jsx3(
|
|
402
|
+
AuthContext.Provider,
|
|
403
|
+
{
|
|
404
|
+
value: {
|
|
405
|
+
user,
|
|
406
|
+
profile,
|
|
407
|
+
membership,
|
|
408
|
+
userRole,
|
|
409
|
+
activeCompanyId,
|
|
410
|
+
session,
|
|
411
|
+
isAuthenticated: !!user,
|
|
412
|
+
loading,
|
|
413
|
+
signOut,
|
|
414
|
+
updateProfile,
|
|
415
|
+
refreshProfile,
|
|
416
|
+
setActiveCompany
|
|
417
|
+
},
|
|
418
|
+
children
|
|
419
|
+
}
|
|
420
|
+
);
|
|
421
|
+
};
|
|
202
422
|
var useAuth = () => {
|
|
203
423
|
const context = useContext3(AuthContext);
|
|
204
424
|
if (!context) {
|
|
@@ -1456,6 +1676,7 @@ var useAppSettings = () => {
|
|
|
1456
1676
|
var Providers = {
|
|
1457
1677
|
Supabase: SupabaseProvider,
|
|
1458
1678
|
AppSettings: AppSettingsProvider,
|
|
1679
|
+
Auth: AuthProvider,
|
|
1459
1680
|
Translate: TranslateProvider,
|
|
1460
1681
|
TranslationEdit: TranslationEditProvider,
|
|
1461
1682
|
Localization: LocalizationProvider,
|
|
@@ -2015,6 +2236,8 @@ var UserPopoverComponent_default = UserPopoverComponent;
|
|
|
2015
2236
|
export {
|
|
2016
2237
|
SupabaseProvider,
|
|
2017
2238
|
useSupabase,
|
|
2239
|
+
AuthProvider,
|
|
2240
|
+
useAuth,
|
|
2018
2241
|
TranslationEditProvider,
|
|
2019
2242
|
useTranslationEdit,
|
|
2020
2243
|
translationService,
|
package/dist/index.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as React$1 from 'react';
|
|
2
2
|
import React__default, { ReactNode } from 'react';
|
|
3
3
|
import { TextFieldProps, IconButtonProps, TooltipProps, SxProps, Theme } from '@mui/material';
|
|
4
|
-
import { SupabaseClient } from '@supabase/supabase-js';
|
|
4
|
+
import { SupabaseClient, User, Session } from '@supabase/supabase-js';
|
|
5
5
|
|
|
6
6
|
interface UrlValue {
|
|
7
7
|
url: string;
|
|
@@ -112,7 +112,50 @@ interface UserPopoverComponentProps {
|
|
|
112
112
|
onClose: () => void;
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
+
interface UserProfile {
|
|
116
|
+
id: string;
|
|
117
|
+
email: string;
|
|
118
|
+
system_role: 'superadmin' | 'admin' | 'support' | null;
|
|
119
|
+
updated_at: string;
|
|
120
|
+
avatar_url: string | null;
|
|
121
|
+
avatar_path?: string | null;
|
|
122
|
+
first_name: string | null;
|
|
123
|
+
middle_name: string | null;
|
|
124
|
+
last_name: string | null;
|
|
125
|
+
display_name: string | null;
|
|
126
|
+
locked: boolean;
|
|
127
|
+
archived: boolean;
|
|
128
|
+
birthday: string | null;
|
|
129
|
+
phone: string | null;
|
|
130
|
+
description: string | null;
|
|
131
|
+
created_at: string;
|
|
132
|
+
cover_image_url: string | null;
|
|
133
|
+
cover_image_path?: string | null;
|
|
134
|
+
active_company_id: string | null;
|
|
135
|
+
name_order: 'first_last' | 'last_first' | null;
|
|
136
|
+
include_middle_name: boolean | null;
|
|
137
|
+
name_genitive: string | null;
|
|
138
|
+
name_dative: string | null;
|
|
139
|
+
name_instrumental: string | null;
|
|
140
|
+
name_vocative: string | null;
|
|
141
|
+
}
|
|
142
|
+
|
|
115
143
|
type MembershipRole = 'superadmin' | 'admin' | 'user';
|
|
144
|
+
interface Membership {
|
|
145
|
+
id: string;
|
|
146
|
+
user_id: string;
|
|
147
|
+
company_id: string;
|
|
148
|
+
role: 'superadmin' | 'admin' | 'user';
|
|
149
|
+
created_at: string;
|
|
150
|
+
last_updated_at: string | null;
|
|
151
|
+
first_login_at?: string | null;
|
|
152
|
+
last_login_at?: string | null;
|
|
153
|
+
employee_post: string | null;
|
|
154
|
+
work_schedule_id: string | null;
|
|
155
|
+
locked: boolean;
|
|
156
|
+
locked_reason: string | null;
|
|
157
|
+
excluded: boolean;
|
|
158
|
+
}
|
|
116
159
|
|
|
117
160
|
interface UserRoleChipComponentProps {
|
|
118
161
|
overrideNamespace?: string;
|
|
@@ -233,6 +276,25 @@ declare const AppSettingsProvider: React__default.FC<{
|
|
|
233
276
|
}>;
|
|
234
277
|
declare const useAppSettings: () => AppSettingsContextType;
|
|
235
278
|
|
|
279
|
+
interface AuthContextType {
|
|
280
|
+
user: User | null;
|
|
281
|
+
profile: UserProfile | null;
|
|
282
|
+
membership: Membership | null;
|
|
283
|
+
userRole: MembershipRole | null;
|
|
284
|
+
activeCompanyId: string | null;
|
|
285
|
+
session: Session | null;
|
|
286
|
+
isAuthenticated: boolean;
|
|
287
|
+
loading: boolean;
|
|
288
|
+
signOut: () => Promise<void>;
|
|
289
|
+
updateProfile: (newProfileData: Partial<UserProfile>) => void;
|
|
290
|
+
refreshProfile: () => Promise<void>;
|
|
291
|
+
setActiveCompany: (companyId: string) => Promise<void>;
|
|
292
|
+
}
|
|
293
|
+
declare const AuthProvider: React__default.FC<{
|
|
294
|
+
children: React__default.ReactNode;
|
|
295
|
+
}>;
|
|
296
|
+
declare const useAuth: () => AuthContextType;
|
|
297
|
+
|
|
236
298
|
interface TranslateTextProps {
|
|
237
299
|
overrideNamespace?: string;
|
|
238
300
|
children: string;
|
|
@@ -356,6 +418,9 @@ declare const Providers: {
|
|
|
356
418
|
readonly AppSettings: React$1.FC<{
|
|
357
419
|
children: React.ReactNode;
|
|
358
420
|
}>;
|
|
421
|
+
readonly Auth: React$1.FC<{
|
|
422
|
+
children: React.ReactNode;
|
|
423
|
+
}>;
|
|
359
424
|
readonly Translate: React$1.FC<TranslateProviderProps>;
|
|
360
425
|
readonly TranslationEdit: React$1.FC<{
|
|
361
426
|
children: React.ReactNode;
|
|
@@ -376,4 +441,4 @@ declare const Providers: {
|
|
|
376
441
|
readonly AI: React$1.FC<AIProviderProps>;
|
|
377
442
|
};
|
|
378
443
|
|
|
379
|
-
export { type AIConfig, type AIGenerateOptions, AIProvider, type AIProviderProps, type AIProviderType, AppSettingsProvider, 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, type UserStatusChipComponentProps as UserStatusChipProps, useAI, useAppSettings, useAppTheme, useBreadcrumb, useConfirmation, useLocalization, useSupabase, useToast, useTranslationEdit, useTranslationNamespace };
|
|
444
|
+
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, type UserStatusChipComponentProps as UserStatusChipProps, useAI, useAppSettings, useAppTheme, useAuth, useBreadcrumb, useConfirmation, useLocalization, useSupabase, useToast, useTranslationEdit, useTranslationNamespace };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as React$1 from 'react';
|
|
2
2
|
import React__default, { ReactNode } from 'react';
|
|
3
3
|
import { TextFieldProps, IconButtonProps, TooltipProps, SxProps, Theme } from '@mui/material';
|
|
4
|
-
import { SupabaseClient } from '@supabase/supabase-js';
|
|
4
|
+
import { SupabaseClient, User, Session } from '@supabase/supabase-js';
|
|
5
5
|
|
|
6
6
|
interface UrlValue {
|
|
7
7
|
url: string;
|
|
@@ -112,7 +112,50 @@ interface UserPopoverComponentProps {
|
|
|
112
112
|
onClose: () => void;
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
+
interface UserProfile {
|
|
116
|
+
id: string;
|
|
117
|
+
email: string;
|
|
118
|
+
system_role: 'superadmin' | 'admin' | 'support' | null;
|
|
119
|
+
updated_at: string;
|
|
120
|
+
avatar_url: string | null;
|
|
121
|
+
avatar_path?: string | null;
|
|
122
|
+
first_name: string | null;
|
|
123
|
+
middle_name: string | null;
|
|
124
|
+
last_name: string | null;
|
|
125
|
+
display_name: string | null;
|
|
126
|
+
locked: boolean;
|
|
127
|
+
archived: boolean;
|
|
128
|
+
birthday: string | null;
|
|
129
|
+
phone: string | null;
|
|
130
|
+
description: string | null;
|
|
131
|
+
created_at: string;
|
|
132
|
+
cover_image_url: string | null;
|
|
133
|
+
cover_image_path?: string | null;
|
|
134
|
+
active_company_id: string | null;
|
|
135
|
+
name_order: 'first_last' | 'last_first' | null;
|
|
136
|
+
include_middle_name: boolean | null;
|
|
137
|
+
name_genitive: string | null;
|
|
138
|
+
name_dative: string | null;
|
|
139
|
+
name_instrumental: string | null;
|
|
140
|
+
name_vocative: string | null;
|
|
141
|
+
}
|
|
142
|
+
|
|
115
143
|
type MembershipRole = 'superadmin' | 'admin' | 'user';
|
|
144
|
+
interface Membership {
|
|
145
|
+
id: string;
|
|
146
|
+
user_id: string;
|
|
147
|
+
company_id: string;
|
|
148
|
+
role: 'superadmin' | 'admin' | 'user';
|
|
149
|
+
created_at: string;
|
|
150
|
+
last_updated_at: string | null;
|
|
151
|
+
first_login_at?: string | null;
|
|
152
|
+
last_login_at?: string | null;
|
|
153
|
+
employee_post: string | null;
|
|
154
|
+
work_schedule_id: string | null;
|
|
155
|
+
locked: boolean;
|
|
156
|
+
locked_reason: string | null;
|
|
157
|
+
excluded: boolean;
|
|
158
|
+
}
|
|
116
159
|
|
|
117
160
|
interface UserRoleChipComponentProps {
|
|
118
161
|
overrideNamespace?: string;
|
|
@@ -233,6 +276,25 @@ declare const AppSettingsProvider: React__default.FC<{
|
|
|
233
276
|
}>;
|
|
234
277
|
declare const useAppSettings: () => AppSettingsContextType;
|
|
235
278
|
|
|
279
|
+
interface AuthContextType {
|
|
280
|
+
user: User | null;
|
|
281
|
+
profile: UserProfile | null;
|
|
282
|
+
membership: Membership | null;
|
|
283
|
+
userRole: MembershipRole | null;
|
|
284
|
+
activeCompanyId: string | null;
|
|
285
|
+
session: Session | null;
|
|
286
|
+
isAuthenticated: boolean;
|
|
287
|
+
loading: boolean;
|
|
288
|
+
signOut: () => Promise<void>;
|
|
289
|
+
updateProfile: (newProfileData: Partial<UserProfile>) => void;
|
|
290
|
+
refreshProfile: () => Promise<void>;
|
|
291
|
+
setActiveCompany: (companyId: string) => Promise<void>;
|
|
292
|
+
}
|
|
293
|
+
declare const AuthProvider: React__default.FC<{
|
|
294
|
+
children: React__default.ReactNode;
|
|
295
|
+
}>;
|
|
296
|
+
declare const useAuth: () => AuthContextType;
|
|
297
|
+
|
|
236
298
|
interface TranslateTextProps {
|
|
237
299
|
overrideNamespace?: string;
|
|
238
300
|
children: string;
|
|
@@ -356,6 +418,9 @@ declare const Providers: {
|
|
|
356
418
|
readonly AppSettings: React$1.FC<{
|
|
357
419
|
children: React.ReactNode;
|
|
358
420
|
}>;
|
|
421
|
+
readonly Auth: React$1.FC<{
|
|
422
|
+
children: React.ReactNode;
|
|
423
|
+
}>;
|
|
359
424
|
readonly Translate: React$1.FC<TranslateProviderProps>;
|
|
360
425
|
readonly TranslationEdit: React$1.FC<{
|
|
361
426
|
children: React.ReactNode;
|
|
@@ -376,4 +441,4 @@ declare const Providers: {
|
|
|
376
441
|
readonly AI: React$1.FC<AIProviderProps>;
|
|
377
442
|
};
|
|
378
443
|
|
|
379
|
-
export { type AIConfig, type AIGenerateOptions, AIProvider, type AIProviderProps, type AIProviderType, AppSettingsProvider, 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, type UserStatusChipComponentProps as UserStatusChipProps, useAI, useAppSettings, useAppTheme, useBreadcrumb, useConfirmation, useLocalization, useSupabase, useToast, useTranslationEdit, useTranslationNamespace };
|
|
444
|
+
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, type UserStatusChipComponentProps as UserStatusChipProps, useAI, useAppSettings, useAppTheme, useAuth, useBreadcrumb, useConfirmation, useLocalization, useSupabase, useToast, useTranslationEdit, useTranslationNamespace };
|
package/dist/index.js
CHANGED
|
@@ -153,18 +153,64 @@ var init_config = __esm({
|
|
|
153
153
|
});
|
|
154
154
|
|
|
155
155
|
// src/utils/deviceId.ts
|
|
156
|
+
var getDeviceId;
|
|
156
157
|
var init_deviceId = __esm({
|
|
157
158
|
"src/utils/deviceId.ts"() {
|
|
158
159
|
"use strict";
|
|
160
|
+
getDeviceId = () => {
|
|
161
|
+
let deviceId = localStorage.getItem("app_device_id");
|
|
162
|
+
if (!deviceId) {
|
|
163
|
+
deviceId = crypto.randomUUID();
|
|
164
|
+
localStorage.setItem("app_device_id", deviceId);
|
|
165
|
+
}
|
|
166
|
+
return deviceId;
|
|
167
|
+
};
|
|
159
168
|
}
|
|
160
169
|
});
|
|
161
170
|
|
|
162
171
|
// src/services/session.service.ts
|
|
163
|
-
var getUserLastSeenAt;
|
|
172
|
+
var trackUserSession, isCurrentSessionValid, getUserLastSeenAt;
|
|
164
173
|
var init_session_service = __esm({
|
|
165
174
|
"src/services/session.service.ts"() {
|
|
166
175
|
"use strict";
|
|
167
176
|
init_deviceId();
|
|
177
|
+
trackUserSession = async (supabase, userId) => {
|
|
178
|
+
const deviceId = getDeviceId();
|
|
179
|
+
let ip = "";
|
|
180
|
+
try {
|
|
181
|
+
const ipRes = await fetch("https://api.ipify.org?format=json");
|
|
182
|
+
const ipData = await ipRes.json();
|
|
183
|
+
ip = ipData.ip;
|
|
184
|
+
} catch (e) {
|
|
185
|
+
console.warn("Failed to fetch IP address", e);
|
|
186
|
+
}
|
|
187
|
+
await supabase.from("user_sessions").upsert(
|
|
188
|
+
{
|
|
189
|
+
user_id: userId,
|
|
190
|
+
device_id: deviceId,
|
|
191
|
+
user_agent: navigator.userAgent,
|
|
192
|
+
ip_address: ip,
|
|
193
|
+
url: window.location.href,
|
|
194
|
+
last_seen_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
195
|
+
},
|
|
196
|
+
{ onConflict: "user_id, device_id" }
|
|
197
|
+
);
|
|
198
|
+
};
|
|
199
|
+
isCurrentSessionValid = async (supabase, userId) => {
|
|
200
|
+
try {
|
|
201
|
+
const currentDeviceId = getDeviceId();
|
|
202
|
+
const { data, error } = await supabase.from("user_sessions").select("id").eq("user_id", userId).eq("device_id", currentDeviceId).maybeSingle();
|
|
203
|
+
if (error) {
|
|
204
|
+
console.warn("\u041F\u043E\u043C\u0438\u043B\u043A\u0430 \u043F\u0435\u0440\u0435\u0432\u0456\u0440\u043A\u0438 \u0441\u0435\u0441\u0456\u0457:", error.message);
|
|
205
|
+
return true;
|
|
206
|
+
}
|
|
207
|
+
if (!data) return false;
|
|
208
|
+
return true;
|
|
209
|
+
} catch (err) {
|
|
210
|
+
console.error("\u041D\u0435\u0441\u043F\u043E\u0434\u0456\u0432\u0430\u043D\u0430 \u043F\u043E\u043C\u0438\u043B\u043A\u0430 \u043F\u0440\u0438 \u043F\u0435\u0440\u0435\u0432\u0456\u0440\u0446\u0456 \u0441\u0435\u0441\u0456\u0457:", err);
|
|
211
|
+
return true;
|
|
212
|
+
}
|
|
213
|
+
};
|
|
168
214
|
getUserLastSeenAt = async (supabase, userId) => {
|
|
169
215
|
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();
|
|
170
216
|
if (error || !data) return null;
|
|
@@ -209,7 +255,7 @@ var init_SupabaseProvider = __esm({
|
|
|
209
255
|
});
|
|
210
256
|
|
|
211
257
|
// src/context/AuthProvider.tsx
|
|
212
|
-
var import_react2, import_jsx_runtime2, AuthContext, useAuth;
|
|
258
|
+
var import_react2, import_jsx_runtime2, AuthContext, AuthProvider, useAuth;
|
|
213
259
|
var init_AuthProvider = __esm({
|
|
214
260
|
"src/context/AuthProvider.tsx"() {
|
|
215
261
|
"use strict";
|
|
@@ -218,6 +264,179 @@ var init_AuthProvider = __esm({
|
|
|
218
264
|
init_SupabaseProvider();
|
|
219
265
|
import_jsx_runtime2 = require("react/jsx-runtime");
|
|
220
266
|
AuthContext = (0, import_react2.createContext)(void 0);
|
|
267
|
+
AuthProvider = ({ children }) => {
|
|
268
|
+
const supabase = useSupabase();
|
|
269
|
+
const [user, setUser] = (0, import_react2.useState)(null);
|
|
270
|
+
const [profile, setProfile] = (0, import_react2.useState)(null);
|
|
271
|
+
const [membership, setMembership] = (0, import_react2.useState)(null);
|
|
272
|
+
const [session, setSession] = (0, import_react2.useState)(null);
|
|
273
|
+
const [loading, setLoading] = (0, import_react2.useState)(true);
|
|
274
|
+
const currentUserIdRef = (0, import_react2.useRef)(null);
|
|
275
|
+
const fetchProfileAndMembership = (0, import_react2.useCallback)(async (userId) => {
|
|
276
|
+
try {
|
|
277
|
+
const { data, error } = await supabase.rpc("get_user_avatar_and_profile", {
|
|
278
|
+
p_user_id: userId
|
|
279
|
+
});
|
|
280
|
+
if (error || !data) {
|
|
281
|
+
console.error("Error fetching user context via RPC:", error?.message);
|
|
282
|
+
setProfile(null);
|
|
283
|
+
setMembership(null);
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
const response = data;
|
|
287
|
+
if (response?.profile) {
|
|
288
|
+
const profileData = response.profile;
|
|
289
|
+
if (profileData.avatar_path && !profileData.avatar_path.startsWith("http")) {
|
|
290
|
+
const cleanPath = profileData.avatar_path.replace(/^user-media\//, "");
|
|
291
|
+
const { data: avatarSignedData } = await supabase.storage.from("user-media").createSignedUrl(cleanPath, 3600);
|
|
292
|
+
if (avatarSignedData?.signedUrl) {
|
|
293
|
+
profileData.avatar_url = avatarSignedData.signedUrl;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
if (profileData.cover_image_path && !profileData.cover_image_path.startsWith("http")) {
|
|
297
|
+
const cleanPath = profileData.cover_image_path.replace(/^user-media\//, "");
|
|
298
|
+
const { data: coverSignedData } = await supabase.storage.from("user-media").createSignedUrl(cleanPath, 3600);
|
|
299
|
+
if (coverSignedData?.signedUrl) {
|
|
300
|
+
profileData.cover_image_url = coverSignedData.signedUrl;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
let updatedMembership = response.membership;
|
|
304
|
+
if (updatedMembership) {
|
|
305
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
306
|
+
const isFirstLogin = !updatedMembership.first_login_at;
|
|
307
|
+
const updateData = {
|
|
308
|
+
last_login_at: now,
|
|
309
|
+
...isFirstLogin && { first_login_at: now }
|
|
310
|
+
};
|
|
311
|
+
const { error: updateError } = await supabase.from("memberships").update(updateData).eq("id", updatedMembership.id);
|
|
312
|
+
if (updateError) {
|
|
313
|
+
console.error("Error updating membership login timestamps:", updateError.message);
|
|
314
|
+
} else {
|
|
315
|
+
updatedMembership = {
|
|
316
|
+
...updatedMembership,
|
|
317
|
+
...updateData
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
setProfile(profileData);
|
|
322
|
+
setMembership(updatedMembership);
|
|
323
|
+
}
|
|
324
|
+
} catch (err) {
|
|
325
|
+
console.error("Unexpected error fetching user context:", err);
|
|
326
|
+
setProfile(null);
|
|
327
|
+
setMembership(null);
|
|
328
|
+
}
|
|
329
|
+
}, []);
|
|
330
|
+
const refreshProfile = async () => {
|
|
331
|
+
if (currentUserIdRef.current) {
|
|
332
|
+
await fetchProfileAndMembership(currentUserIdRef.current);
|
|
333
|
+
}
|
|
334
|
+
};
|
|
335
|
+
const signOut = (0, import_react2.useCallback)(async () => {
|
|
336
|
+
await supabase.auth.signOut();
|
|
337
|
+
currentUserIdRef.current = null;
|
|
338
|
+
setUser(null);
|
|
339
|
+
setProfile(null);
|
|
340
|
+
setMembership(null);
|
|
341
|
+
setSession(null);
|
|
342
|
+
}, []);
|
|
343
|
+
const setActiveCompany = async (companyId) => {
|
|
344
|
+
if (!user) {
|
|
345
|
+
throw new Error("\u041F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044C \u043D\u0435 \u0430\u0432\u0442\u043E\u0440\u0438\u0437\u043E\u0432\u0430\u043D");
|
|
346
|
+
}
|
|
347
|
+
const { error: profileError } = await supabase.from("profiles").update({ active_company_id: companyId }).eq("id", user.id);
|
|
348
|
+
if (profileError) {
|
|
349
|
+
console.error("Error updating active company:", profileError);
|
|
350
|
+
throw new Error(profileError.message);
|
|
351
|
+
}
|
|
352
|
+
await refreshProfile();
|
|
353
|
+
};
|
|
354
|
+
const updateProfile = (newProfileData) => {
|
|
355
|
+
setProfile((prev) => prev ? { ...prev, ...newProfileData } : null);
|
|
356
|
+
};
|
|
357
|
+
(0, import_react2.useEffect)(() => {
|
|
358
|
+
const { data: { subscription } } = supabase.auth.onAuthStateChange(async (event, currentSession) => {
|
|
359
|
+
if (event === "TOKEN_REFRESHED" && currentUserIdRef.current === currentSession?.user?.id) {
|
|
360
|
+
setSession(currentSession);
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
const currentUser = currentSession?.user ?? null;
|
|
364
|
+
const newUserId = currentUser?.id ?? null;
|
|
365
|
+
if (newUserId !== currentUserIdRef.current) {
|
|
366
|
+
currentUserIdRef.current = newUserId;
|
|
367
|
+
setUser(currentUser);
|
|
368
|
+
if (newUserId) {
|
|
369
|
+
await trackUserSession(supabase, newUserId).catch(console.error);
|
|
370
|
+
const isAuthLinkEvent = event === "SIGNED_IN" || event === "INITIAL_SESSION" || event === "PASSWORD_RECOVERY";
|
|
371
|
+
if (!isAuthLinkEvent) {
|
|
372
|
+
const isValid = await isCurrentSessionValid(supabase, newUserId);
|
|
373
|
+
if (!isValid) {
|
|
374
|
+
await supabase.auth.signOut();
|
|
375
|
+
currentUserIdRef.current = null;
|
|
376
|
+
setUser(null);
|
|
377
|
+
setProfile(null);
|
|
378
|
+
setMembership(null);
|
|
379
|
+
setLoading(false);
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
await fetchProfileAndMembership(newUserId);
|
|
384
|
+
setSession(currentSession);
|
|
385
|
+
} else {
|
|
386
|
+
setProfile(null);
|
|
387
|
+
setMembership(null);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
setLoading(false);
|
|
391
|
+
});
|
|
392
|
+
return () => {
|
|
393
|
+
subscription.unsubscribe();
|
|
394
|
+
};
|
|
395
|
+
}, [fetchProfileAndMembership]);
|
|
396
|
+
(0, import_react2.useEffect)(() => {
|
|
397
|
+
if (!user) return;
|
|
398
|
+
const checkSession = async () => {
|
|
399
|
+
try {
|
|
400
|
+
const valid = await isCurrentSessionValid(supabase, user.id);
|
|
401
|
+
if (!valid) {
|
|
402
|
+
console.warn("\u0421\u0435\u0441\u0456\u044E \u0432\u0456\u0434\u043A\u043B\u0438\u043A\u0430\u043D\u043E \u0437 \u0456\u043D\u0448\u043E\u0433\u043E \u043F\u0440\u0438\u0441\u0442\u0440\u043E\u044E.");
|
|
403
|
+
await signOut();
|
|
404
|
+
}
|
|
405
|
+
} catch (err) {
|
|
406
|
+
console.error("\u041F\u043E\u043C\u0438\u043B\u043A\u0430 \u043F\u0440\u0438 \u043F\u0435\u0440\u0435\u0432\u0456\u0440\u0446\u0456 \u0441\u0435\u0441\u0456\u0457:", err);
|
|
407
|
+
}
|
|
408
|
+
};
|
|
409
|
+
const interval = setInterval(checkSession, 6e4);
|
|
410
|
+
const handleFocus = () => checkSession();
|
|
411
|
+
window.addEventListener("focus", handleFocus);
|
|
412
|
+
return () => {
|
|
413
|
+
clearInterval(interval);
|
|
414
|
+
window.removeEventListener("focus", handleFocus);
|
|
415
|
+
};
|
|
416
|
+
}, [user, signOut]);
|
|
417
|
+
const activeCompanyId = profile?.active_company_id ?? null;
|
|
418
|
+
const userRole = membership?.role ?? null;
|
|
419
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
420
|
+
AuthContext.Provider,
|
|
421
|
+
{
|
|
422
|
+
value: {
|
|
423
|
+
user,
|
|
424
|
+
profile,
|
|
425
|
+
membership,
|
|
426
|
+
userRole,
|
|
427
|
+
activeCompanyId,
|
|
428
|
+
session,
|
|
429
|
+
isAuthenticated: !!user,
|
|
430
|
+
loading,
|
|
431
|
+
signOut,
|
|
432
|
+
updateProfile,
|
|
433
|
+
refreshProfile,
|
|
434
|
+
setActiveCompany
|
|
435
|
+
},
|
|
436
|
+
children
|
|
437
|
+
}
|
|
438
|
+
);
|
|
439
|
+
};
|
|
221
440
|
useAuth = () => {
|
|
222
441
|
const context = (0, import_react2.useContext)(AuthContext);
|
|
223
442
|
if (!context) {
|
|
@@ -1600,8 +1819,10 @@ var init_context = __esm({
|
|
|
1600
1819
|
init_ConfirmationProvider();
|
|
1601
1820
|
init_AIProvider();
|
|
1602
1821
|
init_AppSettingsProvider();
|
|
1822
|
+
init_AuthProvider();
|
|
1603
1823
|
init_SupabaseProvider();
|
|
1604
1824
|
init_AppSettingsProvider();
|
|
1825
|
+
init_AuthProvider();
|
|
1605
1826
|
init_TranslateProvider();
|
|
1606
1827
|
init_TranslateText();
|
|
1607
1828
|
init_TranslationEditProvider();
|
|
@@ -1614,6 +1835,7 @@ var init_context = __esm({
|
|
|
1614
1835
|
Providers = {
|
|
1615
1836
|
Supabase: SupabaseProvider,
|
|
1616
1837
|
AppSettings: AppSettingsProvider,
|
|
1838
|
+
Auth: AuthProvider,
|
|
1617
1839
|
Translate: TranslateProvider,
|
|
1618
1840
|
TranslationEdit: TranslationEditProvider,
|
|
1619
1841
|
Localization: LocalizationProvider,
|
|
@@ -2204,6 +2426,7 @@ var index_exports = {};
|
|
|
2204
2426
|
__export(index_exports, {
|
|
2205
2427
|
AIProvider: () => AIProvider,
|
|
2206
2428
|
AppSettingsProvider: () => AppSettingsProvider,
|
|
2429
|
+
AuthProvider: () => AuthProvider,
|
|
2207
2430
|
BreadcrumbProvider: () => BreadcrumbProvider,
|
|
2208
2431
|
ConfirmationProvider: () => ConfirmationProvider,
|
|
2209
2432
|
LocalizationProvider: () => LocalizationProvider,
|
|
@@ -2218,6 +2441,7 @@ __export(index_exports, {
|
|
|
2218
2441
|
useAI: () => useAI,
|
|
2219
2442
|
useAppSettings: () => useAppSettings,
|
|
2220
2443
|
useAppTheme: () => useAppTheme,
|
|
2444
|
+
useAuth: () => useAuth,
|
|
2221
2445
|
useBreadcrumb: () => useBreadcrumb,
|
|
2222
2446
|
useConfirmation: () => useConfirmation,
|
|
2223
2447
|
useLocalization: () => useLocalization,
|
|
@@ -3069,6 +3293,7 @@ init_context();
|
|
|
3069
3293
|
0 && (module.exports = {
|
|
3070
3294
|
AIProvider,
|
|
3071
3295
|
AppSettingsProvider,
|
|
3296
|
+
AuthProvider,
|
|
3072
3297
|
BreadcrumbProvider,
|
|
3073
3298
|
ConfirmationProvider,
|
|
3074
3299
|
LocalizationProvider,
|
|
@@ -3083,6 +3308,7 @@ init_context();
|
|
|
3083
3308
|
useAI,
|
|
3084
3309
|
useAppSettings,
|
|
3085
3310
|
useAppTheme,
|
|
3311
|
+
useAuth,
|
|
3086
3312
|
useBreadcrumb,
|
|
3087
3313
|
useConfirmation,
|
|
3088
3314
|
useLocalization,
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
AIProvider,
|
|
3
3
|
AppSettingsProvider,
|
|
4
|
+
AuthProvider,
|
|
4
5
|
BreadcrumbProvider,
|
|
5
6
|
ConfirmationProvider,
|
|
6
7
|
CopyClipboardButtonComponent,
|
|
@@ -21,6 +22,7 @@ import {
|
|
|
21
22
|
useAI,
|
|
22
23
|
useAppSettings,
|
|
23
24
|
useAppTheme,
|
|
25
|
+
useAuth,
|
|
24
26
|
useBreadcrumb,
|
|
25
27
|
useConfirmation,
|
|
26
28
|
useLocalization,
|
|
@@ -28,7 +30,7 @@ import {
|
|
|
28
30
|
useToast,
|
|
29
31
|
useTranslationEdit,
|
|
30
32
|
useTranslationNamespace
|
|
31
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-ABYNAO4A.mjs";
|
|
32
34
|
|
|
33
35
|
// src/UI/components/inputs/TextFieldComponent.tsx
|
|
34
36
|
import { useState } from "react";
|
|
@@ -726,7 +728,7 @@ var EmailInputComponent = ({
|
|
|
726
728
|
import { useState as useState5, useEffect as useEffect2, lazy, Suspense } from "react";
|
|
727
729
|
import { Avatar, Tooltip as Tooltip3, Typography as Typography2 } from "@mui/material";
|
|
728
730
|
import { Fragment as Fragment4, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
729
|
-
var LazyUserPopover = lazy(() => import("./UserPopoverComponent-
|
|
731
|
+
var LazyUserPopover = lazy(() => import("./UserPopoverComponent-YKVTSRTJ.mjs"));
|
|
730
732
|
var getInitials = (name) => {
|
|
731
733
|
if (!name) return "?";
|
|
732
734
|
const parts = name.trim().split(" ");
|
|
@@ -865,6 +867,7 @@ var UI = {
|
|
|
865
867
|
export {
|
|
866
868
|
AIProvider,
|
|
867
869
|
AppSettingsProvider,
|
|
870
|
+
AuthProvider,
|
|
868
871
|
BreadcrumbProvider,
|
|
869
872
|
ConfirmationProvider,
|
|
870
873
|
LocalizationProvider,
|
|
@@ -879,6 +882,7 @@ export {
|
|
|
879
882
|
useAI,
|
|
880
883
|
useAppSettings,
|
|
881
884
|
useAppTheme,
|
|
885
|
+
useAuth,
|
|
882
886
|
useBreadcrumb,
|
|
883
887
|
useConfirmation,
|
|
884
888
|
useLocalization,
|