@oondemand/oon-core-front 0.4.2 → 0.4.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/index.d.ts +1 -1
- package/dist/index.js +192 -89
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1095,7 +1095,7 @@ interface AuthContextValue {
|
|
|
1095
1095
|
status: AuthStatus;
|
|
1096
1096
|
isAuthenticated: boolean;
|
|
1097
1097
|
hasPermission: (permission?: string | string[]) => boolean;
|
|
1098
|
-
login: (email: string, password: string) => Promise<void>;
|
|
1098
|
+
login: (email: string, password: string, tenantId?: string) => Promise<void>;
|
|
1099
1099
|
completeFirstAccess: (password: string) => Promise<void>;
|
|
1100
1100
|
retry: () => Promise<void>;
|
|
1101
1101
|
logout: () => void;
|
package/dist/index.js
CHANGED
|
@@ -539,11 +539,11 @@ var oonSystem = createOonSystem();
|
|
|
539
539
|
|
|
540
540
|
// src/security/AuthProvider.tsx
|
|
541
541
|
import {
|
|
542
|
-
createContext as
|
|
543
|
-
useCallback as
|
|
544
|
-
useContext as
|
|
542
|
+
createContext as createContext4,
|
|
543
|
+
useCallback as useCallback3,
|
|
544
|
+
useContext as useContext4,
|
|
545
545
|
useEffect as useEffect4,
|
|
546
|
-
useState as
|
|
546
|
+
useState as useState5
|
|
547
547
|
} from "react";
|
|
548
548
|
|
|
549
549
|
// src/security/ActivationProvider.tsx
|
|
@@ -598,9 +598,65 @@ function useActivation() {
|
|
|
598
598
|
return context;
|
|
599
599
|
}
|
|
600
600
|
|
|
601
|
-
// src/security/
|
|
601
|
+
// src/security/TenantProvider.tsx
|
|
602
|
+
import {
|
|
603
|
+
createContext as createContext3,
|
|
604
|
+
useCallback as useCallback2,
|
|
605
|
+
useContext as useContext3,
|
|
606
|
+
useMemo as useMemo2,
|
|
607
|
+
useState as useState4
|
|
608
|
+
} from "react";
|
|
609
|
+
import { useQueryClient } from "@tanstack/react-query";
|
|
602
610
|
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
603
|
-
var
|
|
611
|
+
var TenantContext = createContext3(null);
|
|
612
|
+
function applyHeader(http, tenantId) {
|
|
613
|
+
if (tenantId) {
|
|
614
|
+
http.defaults.headers.common["x-oon-tenant-id"] = tenantId;
|
|
615
|
+
return;
|
|
616
|
+
}
|
|
617
|
+
delete http.defaults.headers.common["x-oon-tenant-id"];
|
|
618
|
+
}
|
|
619
|
+
function TenantProvider({ http, storage, children }) {
|
|
620
|
+
const queryClient = useQueryClient();
|
|
621
|
+
const [activeTenantId, setActiveTenantId] = useState4(() => storage.get());
|
|
622
|
+
const replaceTenant = useCallback2(
|
|
623
|
+
(tenantId) => {
|
|
624
|
+
const normalized2 = String(tenantId ?? "").trim() || null;
|
|
625
|
+
if (normalized2) storage.set(normalized2);
|
|
626
|
+
else storage.clear();
|
|
627
|
+
applyHeader(http, normalized2);
|
|
628
|
+
setActiveTenantId(normalized2);
|
|
629
|
+
queryClient.clear();
|
|
630
|
+
},
|
|
631
|
+
[http, queryClient, storage]
|
|
632
|
+
);
|
|
633
|
+
const value2 = useMemo2(
|
|
634
|
+
() => ({
|
|
635
|
+
activeTenantId,
|
|
636
|
+
switchTenant(tenantId) {
|
|
637
|
+
if (!tenantId?.trim()) throw new Error("tenantId \xE9 obrigat\xF3rio.");
|
|
638
|
+
replaceTenant(tenantId);
|
|
639
|
+
},
|
|
640
|
+
clearTenant() {
|
|
641
|
+
replaceTenant(null);
|
|
642
|
+
}
|
|
643
|
+
}),
|
|
644
|
+
[activeTenantId, replaceTenant]
|
|
645
|
+
);
|
|
646
|
+
return /* @__PURE__ */ jsx5(TenantContext.Provider, { value: value2, children });
|
|
647
|
+
}
|
|
648
|
+
function useOptionalOonTenant() {
|
|
649
|
+
return useContext3(TenantContext);
|
|
650
|
+
}
|
|
651
|
+
function useOonTenant() {
|
|
652
|
+
const value2 = useOptionalOonTenant();
|
|
653
|
+
if (!value2) throw new Error("useOonTenant deve ser usado dentro de TenantProvider.");
|
|
654
|
+
return value2;
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
// src/security/AuthProvider.tsx
|
|
658
|
+
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
659
|
+
var AuthContext = createContext4(null);
|
|
604
660
|
function errorStatus(error) {
|
|
605
661
|
return error?.status;
|
|
606
662
|
}
|
|
@@ -648,20 +704,26 @@ function can(user, permission) {
|
|
|
648
704
|
function AuthProvider({ http, storage, auth, loginUrl, children }) {
|
|
649
705
|
const tokenParam = auth?.tokenParam ?? "code";
|
|
650
706
|
const devToken = auth?.devToken?.trim() || null;
|
|
651
|
-
const [user, setUser] =
|
|
652
|
-
const [status, setStatus] =
|
|
707
|
+
const [user, setUser] = useState5(null);
|
|
708
|
+
const [status, setStatus] = useState5("loading");
|
|
653
709
|
const activation = useOptionalActivation();
|
|
654
|
-
const
|
|
710
|
+
const tenantContext = useOptionalOonTenant();
|
|
711
|
+
const redirectToExternalLogin = useCallback3(() => {
|
|
655
712
|
if (loginUrl) window.location.href = loginUrl;
|
|
656
713
|
}, [loginUrl]);
|
|
657
|
-
const applyUser =
|
|
714
|
+
const applyUser = useCallback3((next) => {
|
|
658
715
|
setUser(next);
|
|
716
|
+
const tenant = next.tenant;
|
|
717
|
+
const resolvedTenantId = String(next.tenantId || tenant?.id || "").trim();
|
|
718
|
+
if (resolvedTenantId && tenantContext?.activeTenantId !== resolvedTenantId) {
|
|
719
|
+
tenantContext?.switchTenant(resolvedTenantId);
|
|
720
|
+
}
|
|
659
721
|
const firstAccess = Boolean(
|
|
660
722
|
next.mustChangePassword || next.firstAccessPending
|
|
661
723
|
);
|
|
662
724
|
setStatus(firstAccess ? "first-access" : "authenticated");
|
|
663
|
-
}, []);
|
|
664
|
-
const applyValidationError =
|
|
725
|
+
}, [tenantContext]);
|
|
726
|
+
const applyValidationError = useCallback3(
|
|
665
727
|
(error) => {
|
|
666
728
|
const currentStatus = errorStatus(error);
|
|
667
729
|
setUser(null);
|
|
@@ -679,11 +741,11 @@ function AuthProvider({ http, storage, auth, loginUrl, children }) {
|
|
|
679
741
|
},
|
|
680
742
|
[storage, redirectToExternalLogin]
|
|
681
743
|
);
|
|
682
|
-
const validateSession =
|
|
744
|
+
const validateSession = useCallback3(async () => {
|
|
683
745
|
const response = await http.get("/auth/validar-token");
|
|
684
746
|
applyUser(response.data.usuario);
|
|
685
747
|
}, [http, applyUser]);
|
|
686
|
-
const retry =
|
|
748
|
+
const retry = useCallback3(async () => {
|
|
687
749
|
setStatus("loading");
|
|
688
750
|
try {
|
|
689
751
|
await validateSession();
|
|
@@ -692,15 +754,23 @@ function AuthProvider({ http, storage, auth, loginUrl, children }) {
|
|
|
692
754
|
throw error;
|
|
693
755
|
}
|
|
694
756
|
}, [validateSession, applyValidationError]);
|
|
695
|
-
const login =
|
|
696
|
-
async (email, password) => {
|
|
757
|
+
const login = useCallback3(
|
|
758
|
+
async (email, password, tenantId) => {
|
|
697
759
|
setStatus("loading");
|
|
698
760
|
setUser(null);
|
|
699
761
|
try {
|
|
762
|
+
const normalizedTenantId = String(tenantId || "").trim();
|
|
763
|
+
if (normalizedTenantId) tenantContext?.switchTenant(normalizedTenantId);
|
|
764
|
+
else tenantContext?.clearTenant();
|
|
700
765
|
const response = await http.post(
|
|
701
766
|
"/auth/autenticar",
|
|
702
767
|
{},
|
|
703
|
-
{
|
|
768
|
+
{
|
|
769
|
+
headers: {
|
|
770
|
+
Authorization: `Basic ${encodeBasicCredentials(email, password)}`,
|
|
771
|
+
...normalizedTenantId ? { "x-oon-tenant-id": normalizedTenantId } : {}
|
|
772
|
+
}
|
|
773
|
+
}
|
|
704
774
|
);
|
|
705
775
|
if (!response.data.token) {
|
|
706
776
|
const error = { code: "AUTH_TOKEN_MISSING", message: "Token n\xE3o retornado pelo backend.", status: 502 };
|
|
@@ -709,22 +779,27 @@ function AuthProvider({ http, storage, auth, loginUrl, children }) {
|
|
|
709
779
|
storage.set(response.data.token);
|
|
710
780
|
await validateSession();
|
|
711
781
|
} catch (error) {
|
|
712
|
-
|
|
782
|
+
if (error?.code === "TENANT_SELECTION_REQUIRED") {
|
|
783
|
+
setStatus("unauthenticated");
|
|
784
|
+
} else {
|
|
785
|
+
applyValidationError(error);
|
|
786
|
+
}
|
|
713
787
|
throw error;
|
|
714
788
|
}
|
|
715
789
|
},
|
|
716
|
-
[http, storage, validateSession, applyValidationError]
|
|
790
|
+
[http, storage, validateSession, applyValidationError, tenantContext]
|
|
717
791
|
);
|
|
718
|
-
const completeFirstAccess =
|
|
792
|
+
const completeFirstAccess = useCallback3(async (password) => {
|
|
719
793
|
await http.post("/auth/first-access/password", { password });
|
|
720
794
|
await validateSession();
|
|
721
795
|
}, [http, validateSession]);
|
|
722
|
-
const logout =
|
|
796
|
+
const logout = useCallback3(() => {
|
|
723
797
|
storage.clear();
|
|
798
|
+
tenantContext?.clearTenant();
|
|
724
799
|
setUser(null);
|
|
725
800
|
setStatus("unauthenticated");
|
|
726
801
|
redirectToExternalLogin();
|
|
727
|
-
}, [storage, redirectToExternalLogin]);
|
|
802
|
+
}, [storage, redirectToExternalLogin, tenantContext]);
|
|
728
803
|
useEffect4(() => {
|
|
729
804
|
let active = true;
|
|
730
805
|
if (activation && !["active", "error"].includes(activation.status)) {
|
|
@@ -758,7 +833,7 @@ function AuthProvider({ http, storage, auth, loginUrl, children }) {
|
|
|
758
833
|
const roles = roleCode ? [roleCode] : [];
|
|
759
834
|
const capabilities = extractCapabilities(user);
|
|
760
835
|
const permissions = explicitPermissions(user) ?? capabilities;
|
|
761
|
-
const hasPermission =
|
|
836
|
+
const hasPermission = useCallback3(
|
|
762
837
|
(permission) => can(user, permission),
|
|
763
838
|
[user]
|
|
764
839
|
);
|
|
@@ -775,67 +850,14 @@ function AuthProvider({ http, storage, auth, loginUrl, children }) {
|
|
|
775
850
|
retry,
|
|
776
851
|
logout
|
|
777
852
|
};
|
|
778
|
-
return /* @__PURE__ */
|
|
853
|
+
return /* @__PURE__ */ jsx6(AuthContext.Provider, { value: value2, children });
|
|
779
854
|
}
|
|
780
855
|
function useOonAuth() {
|
|
781
|
-
const context =
|
|
856
|
+
const context = useContext4(AuthContext);
|
|
782
857
|
if (!context) throw new Error("useOonAuth deve ser usado dentro de <AuthProvider> (oonCoreFront.start).");
|
|
783
858
|
return context;
|
|
784
859
|
}
|
|
785
860
|
|
|
786
|
-
// src/security/TenantProvider.tsx
|
|
787
|
-
import {
|
|
788
|
-
createContext as createContext4,
|
|
789
|
-
useCallback as useCallback3,
|
|
790
|
-
useContext as useContext4,
|
|
791
|
-
useMemo as useMemo2,
|
|
792
|
-
useState as useState5
|
|
793
|
-
} from "react";
|
|
794
|
-
import { useQueryClient } from "@tanstack/react-query";
|
|
795
|
-
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
796
|
-
var TenantContext = createContext4(null);
|
|
797
|
-
function applyHeader(http, tenantId) {
|
|
798
|
-
if (tenantId) {
|
|
799
|
-
http.defaults.headers.common["x-oon-tenant-id"] = tenantId;
|
|
800
|
-
return;
|
|
801
|
-
}
|
|
802
|
-
delete http.defaults.headers.common["x-oon-tenant-id"];
|
|
803
|
-
}
|
|
804
|
-
function TenantProvider({ http, storage, children }) {
|
|
805
|
-
const queryClient = useQueryClient();
|
|
806
|
-
const [activeTenantId, setActiveTenantId] = useState5(() => storage.get());
|
|
807
|
-
const replaceTenant = useCallback3(
|
|
808
|
-
(tenantId) => {
|
|
809
|
-
const normalized2 = String(tenantId ?? "").trim() || null;
|
|
810
|
-
if (normalized2) storage.set(normalized2);
|
|
811
|
-
else storage.clear();
|
|
812
|
-
applyHeader(http, normalized2);
|
|
813
|
-
setActiveTenantId(normalized2);
|
|
814
|
-
queryClient.clear();
|
|
815
|
-
},
|
|
816
|
-
[http, queryClient, storage]
|
|
817
|
-
);
|
|
818
|
-
const value2 = useMemo2(
|
|
819
|
-
() => ({
|
|
820
|
-
activeTenantId,
|
|
821
|
-
switchTenant(tenantId) {
|
|
822
|
-
if (!tenantId?.trim()) throw new Error("tenantId \xE9 obrigat\xF3rio.");
|
|
823
|
-
replaceTenant(tenantId);
|
|
824
|
-
},
|
|
825
|
-
clearTenant() {
|
|
826
|
-
replaceTenant(null);
|
|
827
|
-
}
|
|
828
|
-
}),
|
|
829
|
-
[activeTenantId, replaceTenant]
|
|
830
|
-
);
|
|
831
|
-
return /* @__PURE__ */ jsx6(TenantContext.Provider, { value: value2, children });
|
|
832
|
-
}
|
|
833
|
-
function useOonTenant() {
|
|
834
|
-
const value2 = useContext4(TenantContext);
|
|
835
|
-
if (!value2) throw new Error("useOonTenant deve ser usado dentro de TenantProvider.");
|
|
836
|
-
return value2;
|
|
837
|
-
}
|
|
838
|
-
|
|
839
861
|
// src/app/OonProviders.tsx
|
|
840
862
|
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
841
863
|
function OonProviders({
|
|
@@ -2799,6 +2821,7 @@ function CoreRelatedGrid({
|
|
|
2799
2821
|
onRefresh
|
|
2800
2822
|
}) {
|
|
2801
2823
|
const tab = rawTab;
|
|
2824
|
+
const { http } = useOonApi();
|
|
2802
2825
|
const relation = relationFrom(tab.relation, relations);
|
|
2803
2826
|
const schemaQuery = useModelSchema(relation?.model ?? "");
|
|
2804
2827
|
const schema = schemaQuery.data;
|
|
@@ -2852,11 +2875,21 @@ function CoreRelatedGrid({
|
|
|
2852
2875
|
onError: setEditError
|
|
2853
2876
|
});
|
|
2854
2877
|
const createMutation = useMutation({
|
|
2855
|
-
mutationFn: (values) =>
|
|
2856
|
-
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
|
|
2878
|
+
mutationFn: (values) => {
|
|
2879
|
+
const payload = {
|
|
2880
|
+
...createInitialValues,
|
|
2881
|
+
...values,
|
|
2882
|
+
...relation && parentValue != null ? { [relation.foreignKey]: parentValue } : {}
|
|
2883
|
+
};
|
|
2884
|
+
if (tab.create?.endpoint) {
|
|
2885
|
+
return http.request({
|
|
2886
|
+
url: interpolateEndpoint(tab.create.endpoint, payload, parent),
|
|
2887
|
+
method: tab.create.method ?? "POST",
|
|
2888
|
+
data: payload
|
|
2889
|
+
}).then((response) => response.data);
|
|
2890
|
+
}
|
|
2891
|
+
return resource.create(payload);
|
|
2892
|
+
},
|
|
2860
2893
|
onSuccess: async () => {
|
|
2861
2894
|
await invalidate();
|
|
2862
2895
|
setCreating(false);
|
|
@@ -4918,7 +4951,7 @@ function Sidebar({ app, menu, registry }) {
|
|
|
4918
4951
|
// package.json
|
|
4919
4952
|
var package_default = {
|
|
4920
4953
|
name: "@oondemand/oon-core-front",
|
|
4921
|
-
version: "0.4.
|
|
4954
|
+
version: "0.4.4",
|
|
4922
4955
|
repository: {
|
|
4923
4956
|
type: "git",
|
|
4924
4957
|
url: "git+https://github.com/oondemand/oon-platform.git",
|
|
@@ -5105,6 +5138,8 @@ function CoreTopbar({ app, menu }) {
|
|
|
5105
5138
|
const settingsHref = resolveSettingsHref(
|
|
5106
5139
|
menu.filter((item) => hasPermission(item.permissions))
|
|
5107
5140
|
);
|
|
5141
|
+
const tenant = user?.tenant;
|
|
5142
|
+
const tenantLabel = String(tenant?.nome || tenant?.slug || "").trim();
|
|
5108
5143
|
return /* @__PURE__ */ jsxs22(
|
|
5109
5144
|
Flex14,
|
|
5110
5145
|
{
|
|
@@ -5134,6 +5169,10 @@ function CoreTopbar({ app, menu }) {
|
|
|
5134
5169
|
}
|
|
5135
5170
|
),
|
|
5136
5171
|
/* @__PURE__ */ jsx31(Text22, { fontSize: "sm", fontWeight: "600", color: "#24323A", children: app.title ?? app.name }),
|
|
5172
|
+
tenantLabel ? /* @__PURE__ */ jsxs22(Text22, { fontSize: "xs", fontWeight: "600", color: "brand.600", lineHeight: "1.4", children: [
|
|
5173
|
+
"Tenant: ",
|
|
5174
|
+
tenantLabel
|
|
5175
|
+
] }) : null,
|
|
5137
5176
|
/* @__PURE__ */ jsxs22(Text22, { fontSize: "10px", color: "gray.600", lineHeight: "1.35", children: [
|
|
5138
5177
|
"Central ",
|
|
5139
5178
|
centralVersion,
|
|
@@ -5374,11 +5413,23 @@ import {
|
|
|
5374
5413
|
Flex as Flex16,
|
|
5375
5414
|
Heading as Heading12,
|
|
5376
5415
|
Input as Input8,
|
|
5416
|
+
SimpleGrid as SimpleGrid5,
|
|
5377
5417
|
Text as Text24,
|
|
5378
5418
|
VStack as VStack4
|
|
5379
5419
|
} from "@chakra-ui/react";
|
|
5380
5420
|
import { Navigate as Navigate2, useLocation as useLocation3 } from "react-router-dom";
|
|
5381
5421
|
import { jsx as jsx35, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
5422
|
+
function tenantOptions(error) {
|
|
5423
|
+
const details = error.details;
|
|
5424
|
+
if (!details || typeof details !== "object" || Array.isArray(details)) return [];
|
|
5425
|
+
const tenants = details.tenants;
|
|
5426
|
+
if (!Array.isArray(tenants)) return [];
|
|
5427
|
+
return tenants.filter((tenant) => Boolean(tenant) && typeof tenant === "object").map((tenant) => ({
|
|
5428
|
+
id: String(tenant.id || ""),
|
|
5429
|
+
nome: String(tenant.nome || tenant.slug || tenant.id || ""),
|
|
5430
|
+
slug: tenant.slug ? String(tenant.slug) : void 0
|
|
5431
|
+
})).filter((tenant) => tenant.id && tenant.nome);
|
|
5432
|
+
}
|
|
5382
5433
|
function safeRedirect(search) {
|
|
5383
5434
|
const value2 = new URLSearchParams(search).get("redirect") || "/";
|
|
5384
5435
|
if (!value2.startsWith("/") || value2.startsWith("//")) return "/";
|
|
@@ -5394,6 +5445,8 @@ function LoginPage({ app }) {
|
|
|
5394
5445
|
const [password, setPassword] = useState16("");
|
|
5395
5446
|
const [submitting, setSubmitting] = useState16(false);
|
|
5396
5447
|
const [message, setMessage] = useState16(null);
|
|
5448
|
+
const [tenants, setTenants] = useState16([]);
|
|
5449
|
+
const [tenantId, setTenantId] = useState16("");
|
|
5397
5450
|
const redirect = safeRedirect(location.search);
|
|
5398
5451
|
if (status === "authenticated") {
|
|
5399
5452
|
return /* @__PURE__ */ jsx35(Navigate2, { to: redirect, replace: true });
|
|
@@ -5406,9 +5459,22 @@ function LoginPage({ app }) {
|
|
|
5406
5459
|
setSubmitting(true);
|
|
5407
5460
|
setMessage(null);
|
|
5408
5461
|
try {
|
|
5409
|
-
|
|
5462
|
+
if (tenants.length > 1 && !tenantId) {
|
|
5463
|
+
setMessage("Selecione a organiza\xE7\xE3o para continuar.");
|
|
5464
|
+
return;
|
|
5465
|
+
}
|
|
5466
|
+
await login(email.trim(), password, tenantId || void 0);
|
|
5410
5467
|
} catch (error) {
|
|
5411
5468
|
const authError = error;
|
|
5469
|
+
if (authError.code === "TENANT_SELECTION_REQUIRED") {
|
|
5470
|
+
const options = tenantOptions(authError);
|
|
5471
|
+
if (options.length > 1) {
|
|
5472
|
+
setTenants(options);
|
|
5473
|
+
setTenantId("");
|
|
5474
|
+
setMessage("Seu usu\xE1rio possui acesso a mais de uma organiza\xE7\xE3o. Selecione uma para continuar.");
|
|
5475
|
+
return;
|
|
5476
|
+
}
|
|
5477
|
+
}
|
|
5412
5478
|
if (authError.status === 403) return;
|
|
5413
5479
|
setMessage(
|
|
5414
5480
|
authError.status === 401 ? "E-mail ou senha inv\xE1lidos." : authError.message || "N\xE3o foi poss\xEDvel entrar. Tente novamente."
|
|
@@ -5421,7 +5487,7 @@ function LoginPage({ app }) {
|
|
|
5421
5487
|
Box23,
|
|
5422
5488
|
{
|
|
5423
5489
|
width: "100%",
|
|
5424
|
-
maxW: "440px",
|
|
5490
|
+
maxW: tenants.length > 1 ? "680px" : "440px",
|
|
5425
5491
|
bg: "white",
|
|
5426
5492
|
borderWidth: "1px",
|
|
5427
5493
|
borderColor: "#E4EBEF",
|
|
@@ -5452,7 +5518,11 @@ function LoginPage({ app }) {
|
|
|
5452
5518
|
{
|
|
5453
5519
|
type: "email",
|
|
5454
5520
|
value: email,
|
|
5455
|
-
onChange: (event) =>
|
|
5521
|
+
onChange: (event) => {
|
|
5522
|
+
setEmail(event.target.value);
|
|
5523
|
+
setTenants([]);
|
|
5524
|
+
setTenantId("");
|
|
5525
|
+
},
|
|
5456
5526
|
autoComplete: "email",
|
|
5457
5527
|
placeholder: "voce@empresa.com.br",
|
|
5458
5528
|
required: true
|
|
@@ -5472,7 +5542,40 @@ function LoginPage({ app }) {
|
|
|
5472
5542
|
required: true
|
|
5473
5543
|
}
|
|
5474
5544
|
)
|
|
5475
|
-
] })
|
|
5545
|
+
] }),
|
|
5546
|
+
tenants.length > 1 ? /* @__PURE__ */ jsxs24(Box23, { children: [
|
|
5547
|
+
/* @__PURE__ */ jsx35(Text24, { mb: 3, fontSize: "sm", fontWeight: "600", color: "#24323A", children: "Escolha o tenant para acessar" }),
|
|
5548
|
+
/* @__PURE__ */ jsx35(SimpleGrid5, { columns: { base: 1, md: 2 }, gap: 3, children: tenants.map((tenant) => {
|
|
5549
|
+
const selected = tenantId === tenant.id;
|
|
5550
|
+
return /* @__PURE__ */ jsx35(
|
|
5551
|
+
Button16,
|
|
5552
|
+
{
|
|
5553
|
+
type: "button",
|
|
5554
|
+
variant: "outline",
|
|
5555
|
+
height: "auto",
|
|
5556
|
+
minH: "88px",
|
|
5557
|
+
justifyContent: "flex-start",
|
|
5558
|
+
whiteSpace: "normal",
|
|
5559
|
+
textAlign: "left",
|
|
5560
|
+
borderWidth: "2px",
|
|
5561
|
+
borderColor: selected ? "#39BFED" : "#D9E2E7",
|
|
5562
|
+
bg: selected ? "#EFFAFF" : "white",
|
|
5563
|
+
color: "#24323A",
|
|
5564
|
+
"aria-pressed": selected,
|
|
5565
|
+
onClick: () => {
|
|
5566
|
+
setTenantId(tenant.id);
|
|
5567
|
+
setMessage(null);
|
|
5568
|
+
},
|
|
5569
|
+
_hover: { borderColor: "#39BFED", bg: "#F6FCFE" },
|
|
5570
|
+
children: /* @__PURE__ */ jsxs24(VStack4, { align: "start", gap: 1, py: 3, children: [
|
|
5571
|
+
/* @__PURE__ */ jsx35(Text24, { fontWeight: "700", children: tenant.nome }),
|
|
5572
|
+
tenant.slug ? /* @__PURE__ */ jsx35(Text24, { fontSize: "xs", color: "gray.500", children: tenant.slug }) : null
|
|
5573
|
+
] })
|
|
5574
|
+
},
|
|
5575
|
+
tenant.id
|
|
5576
|
+
);
|
|
5577
|
+
}) })
|
|
5578
|
+
] }) : null
|
|
5476
5579
|
] }),
|
|
5477
5580
|
message ? /* @__PURE__ */ jsx35(
|
|
5478
5581
|
Box23,
|
|
@@ -5494,7 +5597,7 @@ function LoginPage({ app }) {
|
|
|
5494
5597
|
bg: "#07262E",
|
|
5495
5598
|
color: "white",
|
|
5496
5599
|
_hover: { bg: "#0B3843" },
|
|
5497
|
-
disabled: submitting || !email.trim() || !password,
|
|
5600
|
+
disabled: submitting || !email.trim() || !password || tenants.length > 1 && !tenantId,
|
|
5498
5601
|
children: submitting ? "Validando acesso..." : "Entrar"
|
|
5499
5602
|
}
|
|
5500
5603
|
)
|