@geekapps/auth-elements-nextjs 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +58 -12
- package/dist/index.d.ts +29 -2
- package/dist/index.js +96 -2
- package/dist/index.js.map +1 -1
- package/package.json +11 -4
package/README.md
CHANGED
|
@@ -1,17 +1,63 @@
|
|
|
1
1
|
# @geekapps/auth-elements-nextjs
|
|
2
2
|
|
|
3
|
-
Componentes
|
|
3
|
+
Componentes visuais simples para usar com `@geekapps/auth-nextjs`. Módulo separado: **não importa** o auth-nextjs em runtime, recebe o hook por `createAuthElements({ useAuth })`. Tem build, estilos (Tailwind) e versionamento próprios.
|
|
4
4
|
|
|
5
|
-
Não usa shadcn/ui, Radix, GSAP ou bibliotecas de UI.
|
|
5
|
+
Não usa shadcn/ui, Radix, GSAP ou bibliotecas de UI. Apenas React + classes Tailwind.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
## Instalação
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
9
|
+
```bash
|
|
10
|
+
bun add @geekapps/auth-nextjs @geekapps/auth-elements-nextjs
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Uso (Next.js)
|
|
14
|
+
|
|
15
|
+
Crie um módulo client, por exemplo `components/auth-elements.ts`:
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
"use client";
|
|
19
|
+
|
|
20
|
+
import { useAuth } from "@geekapps/auth-nextjs/client";
|
|
21
|
+
import { createAuthElements } from "@geekapps/auth-elements-nextjs";
|
|
22
|
+
|
|
23
|
+
export const {
|
|
24
|
+
SignInButton,
|
|
25
|
+
SignOutButton,
|
|
26
|
+
UserButton,
|
|
27
|
+
OrganizationButton,
|
|
28
|
+
OrgSwitcher,
|
|
29
|
+
AccountSwitcher,
|
|
30
|
+
ProfileModal,
|
|
31
|
+
ManageOrganizationModal,
|
|
32
|
+
CreateOrganizationForm,
|
|
33
|
+
WaitlistForm,
|
|
34
|
+
} = createAuthElements({ useAuth });
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
No layout, importe os estilos uma vez:
|
|
38
|
+
|
|
39
|
+
```tsx
|
|
40
|
+
import "@geekapps/auth-elements-nextjs/styles.css";
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Os componentes devem ficar dentro do `GeekappsAuthProvider` do auth-nextjs.
|
|
44
|
+
|
|
45
|
+
## Elementos
|
|
46
|
+
|
|
47
|
+
- `Avatar`, `Modal` (exports diretos)
|
|
48
|
+
- `SignInButton`, `SignOutButton`
|
|
49
|
+
- `AccountSwitcher`, `OrgSwitcher`
|
|
50
|
+
- `UserButton`, `OrganizationButton`
|
|
51
|
+
- `ProfileModal`, `ManageOrganizationModal`
|
|
52
|
+
- `CreateOrganizationForm`
|
|
53
|
+
- `WaitlistForm` — nome + e-mail, usa `useAuth().joinWaitlist`; props `clientId` (obrigatória), `defaultEmail`, `onJoined`, `submitLabel`. Após entrar mostra a posição na fila.
|
|
54
|
+
|
|
55
|
+
Erros do auth-nextjs são traduzidos pelo `code` (`waitlist_required`, `waitlist_disabled`, `password_reset_required`, `account_locked` com `retryAfter`); sem código conhecido, usa o `error` original. O helper `authErrorMessage(result, fallback)` é exportado.
|
|
56
|
+
|
|
57
|
+
## Compatibilidade
|
|
58
|
+
|
|
59
|
+
Testado contra `@geekapps/auth-nextjs` 0.26.x. Funciona com versões anteriores (>=0.20): membros novos do contrato são opcionais (`lookupTaxId?`, `joinWaitlist?`); sem `joinWaitlist` o `WaitlistForm` mostra um aviso para atualizar.
|
|
60
|
+
|
|
61
|
+
## Guarda de contrato
|
|
62
|
+
|
|
63
|
+
`bun run check:contract` compila `tests/contract.ts`, que verifica (só tipos) que `typeof useAuth` de `@geekapps/auth-nextjs/client` é atribuível ao contrato do elements. O auth-nextjs é resolvido pelo workspace (`../auth-nextjs/dist`; rode o build dele antes). Falha de compilação = o contrato divergiu.
|
package/dist/index.d.ts
CHANGED
|
@@ -53,7 +53,7 @@ type OrganizationCreateInput = {
|
|
|
53
53
|
slug: string;
|
|
54
54
|
type?: OrganizationType;
|
|
55
55
|
taxId?: string | null;
|
|
56
|
-
taxIdType?:
|
|
56
|
+
taxIdType?: TaxIdType | null;
|
|
57
57
|
taxIdCountry?: string | null;
|
|
58
58
|
legalName?: string | null;
|
|
59
59
|
tradeName?: string | null;
|
|
@@ -103,15 +103,34 @@ type User = {
|
|
|
103
103
|
imageUrl: string | null;
|
|
104
104
|
phone?: string | null;
|
|
105
105
|
};
|
|
106
|
+
/** Espelha `AuthResult` do auth-nextjs >=0.26 (campos extras são opcionais). */
|
|
106
107
|
type AuthResult<T> = {
|
|
107
108
|
success: true;
|
|
108
109
|
data: T;
|
|
109
110
|
} | {
|
|
110
111
|
success: false;
|
|
111
112
|
error?: string;
|
|
113
|
+
status?: number;
|
|
112
114
|
code?: string;
|
|
115
|
+
retryAfter?: number;
|
|
113
116
|
missingFields?: string[];
|
|
114
117
|
};
|
|
118
|
+
type JoinWaitlistParams = {
|
|
119
|
+
clientId: string;
|
|
120
|
+
email: string;
|
|
121
|
+
name?: string;
|
|
122
|
+
};
|
|
123
|
+
type JoinWaitlistResponse = {
|
|
124
|
+
ok: true;
|
|
125
|
+
status: "waiting" | "approved" | "joined";
|
|
126
|
+
position: number | null;
|
|
127
|
+
};
|
|
128
|
+
/** Mensagem em português para um resultado de erro; `fallback` se o código for desconhecido. */
|
|
129
|
+
declare function authErrorMessage(result: {
|
|
130
|
+
error?: string;
|
|
131
|
+
code?: string;
|
|
132
|
+
retryAfter?: number;
|
|
133
|
+
}, fallback: string): string;
|
|
115
134
|
type UseAuthHook = () => {
|
|
116
135
|
user: User | null;
|
|
117
136
|
signIn: (opts?: {
|
|
@@ -137,6 +156,8 @@ type UseAuthHook = () => {
|
|
|
137
156
|
createOrganization: (input: OrganizationCreateInput) => Promise<AuthResult<Organization>>;
|
|
138
157
|
/** Opcional: SDKs antigos não têm — sem ele, o formulário só não busca os dados do CNPJ. */
|
|
139
158
|
lookupTaxId?: (value: string, type?: TaxIdType) => Promise<AuthResult<TaxIdLookupResult>>;
|
|
159
|
+
/** Opcional (auth-nextjs >=0.26): sem ele o WaitlistForm mostra um aviso. */
|
|
160
|
+
joinWaitlist?: (params: JoinWaitlistParams) => Promise<AuthResult<JoinWaitlistResponse>>;
|
|
140
161
|
updateOrganization: (id: string, input: Partial<{
|
|
141
162
|
name: string;
|
|
142
163
|
slug: string;
|
|
@@ -195,6 +216,12 @@ declare function Modal({ open, onOpenChange, title, description, children, foote
|
|
|
195
216
|
declare function createAuthElements(hooks: {
|
|
196
217
|
useAuth: UseAuthHook;
|
|
197
218
|
}): {
|
|
219
|
+
WaitlistForm: ({ clientId, defaultEmail, onJoined, submitLabel, }: {
|
|
220
|
+
clientId: string;
|
|
221
|
+
defaultEmail?: string;
|
|
222
|
+
onJoined?: (response: JoinWaitlistResponse) => void;
|
|
223
|
+
submitLabel?: string;
|
|
224
|
+
}) => react.JSX.Element;
|
|
198
225
|
SignInButton: ({ children, redirectTo, }: {
|
|
199
226
|
children?: ReactNode;
|
|
200
227
|
redirectTo?: string;
|
|
@@ -221,4 +248,4 @@ declare function createAuthElements(hooks: {
|
|
|
221
248
|
}) => react.JSX.Element;
|
|
222
249
|
};
|
|
223
250
|
|
|
224
|
-
export { Avatar, type ConnectedAccount, type ElementSize, type ElementTone, Modal, type Organization, type OrganizationCreateInput, type OrganizationType, type Permission, type Role, type TaxIdLookupResult, type TaxIdType, type UserSession, createAuthElements };
|
|
251
|
+
export { type AuthResult, Avatar, type ConnectedAccount, type ElementSize, type ElementTone, type JoinWaitlistParams, type JoinWaitlistResponse, Modal, type Organization, type OrganizationCreateInput, type OrganizationType, type Permission, type Role, type TaxIdLookupResult, type TaxIdType, type UserSession, authErrorMessage, createAuthElements };
|
package/dist/index.js
CHANGED
|
@@ -34,6 +34,28 @@ var EMPTY_ORG_FORM = {
|
|
|
34
34
|
function slugify(value) {
|
|
35
35
|
return value.normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 60);
|
|
36
36
|
}
|
|
37
|
+
function authErrorMessage(result, fallback) {
|
|
38
|
+
switch (result.code) {
|
|
39
|
+
case "waitlist_required":
|
|
40
|
+
return "Esta aplica\xE7\xE3o est\xE1 com lista de espera. Entre na lista para receber acesso.";
|
|
41
|
+
case "waitlist_disabled":
|
|
42
|
+
return "A lista de espera n\xE3o est\xE1 ativa para esta aplica\xE7\xE3o.";
|
|
43
|
+
case "password_reset_required":
|
|
44
|
+
return "Sua senha precisa ser redefinida antes de continuar. Use a op\xE7\xE3o de recuperar senha.";
|
|
45
|
+
case "account_locked": {
|
|
46
|
+
const s = result.retryAfter;
|
|
47
|
+
if (typeof s === "number" && s > 0) {
|
|
48
|
+
const wait = s >= 60 ? `${Math.ceil(s / 60)} min` : `${s} s`;
|
|
49
|
+
return `Conta temporariamente bloqueada por tentativas excessivas. Tente novamente em ${wait}.`;
|
|
50
|
+
}
|
|
51
|
+
return "Conta temporariamente bloqueada. Tente novamente mais tarde.";
|
|
52
|
+
}
|
|
53
|
+
case "invalid_credentials":
|
|
54
|
+
return result.error ?? "E-mail ou senha incorretos.";
|
|
55
|
+
default:
|
|
56
|
+
return result.error ?? fallback;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
37
59
|
function cx(...classes) {
|
|
38
60
|
return classes.filter(Boolean).join(" ");
|
|
39
61
|
}
|
|
@@ -305,7 +327,7 @@ function createAuthElements(hooks) {
|
|
|
305
327
|
const result = await lookupTaxId(values.taxId, values.taxIdType);
|
|
306
328
|
setBusy(null);
|
|
307
329
|
if (!result.success) {
|
|
308
|
-
setError(result
|
|
330
|
+
setError(authErrorMessage(result, "Tax ID inv\xE1lido."));
|
|
309
331
|
return;
|
|
310
332
|
}
|
|
311
333
|
const { data } = result.data;
|
|
@@ -370,7 +392,7 @@ function createAuthElements(hooks) {
|
|
|
370
392
|
setBusy(null);
|
|
371
393
|
if (!result.success) {
|
|
372
394
|
if (result.missingFields?.length) setMissing(result.missingFields);
|
|
373
|
-
setError(result
|
|
395
|
+
setError(authErrorMessage(result, "Erro ao criar organiza\xE7\xE3o."));
|
|
374
396
|
return;
|
|
375
397
|
}
|
|
376
398
|
setValues({ ...EMPTY_ORG_FORM });
|
|
@@ -1127,7 +1149,78 @@ function createAuthElements(hooks) {
|
|
|
1127
1149
|
] })
|
|
1128
1150
|
] }) });
|
|
1129
1151
|
}
|
|
1152
|
+
function WaitlistForm({
|
|
1153
|
+
clientId,
|
|
1154
|
+
defaultEmail = "",
|
|
1155
|
+
onJoined,
|
|
1156
|
+
submitLabel = "Entrar na lista de espera"
|
|
1157
|
+
}) {
|
|
1158
|
+
const { joinWaitlist } = useAuth();
|
|
1159
|
+
const [name, setName] = useState("");
|
|
1160
|
+
const [email, setEmail] = useState(defaultEmail);
|
|
1161
|
+
const [busy, setBusy] = useState(false);
|
|
1162
|
+
const [error, setError] = useState(null);
|
|
1163
|
+
const [done, setDone] = useState(null);
|
|
1164
|
+
async function submit(event) {
|
|
1165
|
+
event.preventDefault();
|
|
1166
|
+
if (!joinWaitlist) {
|
|
1167
|
+
setError("Lista de espera indispon\xEDvel: atualize @geekapps/auth-nextjs para 0.26 ou superior.");
|
|
1168
|
+
return;
|
|
1169
|
+
}
|
|
1170
|
+
setBusy(true);
|
|
1171
|
+
setError(null);
|
|
1172
|
+
const result = await joinWaitlist({
|
|
1173
|
+
clientId,
|
|
1174
|
+
email: email.trim(),
|
|
1175
|
+
name: name.trim() || void 0
|
|
1176
|
+
});
|
|
1177
|
+
setBusy(false);
|
|
1178
|
+
if (!result.success) {
|
|
1179
|
+
setError(authErrorMessage(result, "N\xE3o foi poss\xEDvel entrar na lista de espera."));
|
|
1180
|
+
return;
|
|
1181
|
+
}
|
|
1182
|
+
setDone(result.data);
|
|
1183
|
+
onJoined?.(result.data);
|
|
1184
|
+
}
|
|
1185
|
+
if (done) {
|
|
1186
|
+
return /* @__PURE__ */ jsxs("div", { className: "grid gap-1 rounded-xl border border-emerald-200 bg-emerald-50 p-4 text-center", children: [
|
|
1187
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm font-semibold text-emerald-800", children: done.status === "approved" ? "Seu acesso foi liberado!" : done.status === "joined" ? "Voc\xEA j\xE1 tem acesso." : "Voc\xEA est\xE1 na lista de espera." }),
|
|
1188
|
+
done.status === "waiting" && done.position != null && /* @__PURE__ */ jsxs("p", { className: "text-sm text-emerald-700", children: [
|
|
1189
|
+
"Sua posi\xE7\xE3o na fila: ",
|
|
1190
|
+
/* @__PURE__ */ jsxs("span", { className: "font-semibold", children: [
|
|
1191
|
+
"#",
|
|
1192
|
+
done.position
|
|
1193
|
+
] })
|
|
1194
|
+
] })
|
|
1195
|
+
] });
|
|
1196
|
+
}
|
|
1197
|
+
return /* @__PURE__ */ jsxs("form", { className: "grid gap-3", onSubmit: (event) => void submit(event), children: [
|
|
1198
|
+
/* @__PURE__ */ jsx(Field, { label: "Nome", children: /* @__PURE__ */ jsx(
|
|
1199
|
+
Input,
|
|
1200
|
+
{
|
|
1201
|
+
autoComplete: "name",
|
|
1202
|
+
onChange: (event) => setName(event.target.value),
|
|
1203
|
+
placeholder: "Seu nome",
|
|
1204
|
+
value: name
|
|
1205
|
+
}
|
|
1206
|
+
) }),
|
|
1207
|
+
/* @__PURE__ */ jsx(Field, { label: "E-mail", children: /* @__PURE__ */ jsx(
|
|
1208
|
+
Input,
|
|
1209
|
+
{
|
|
1210
|
+
autoComplete: "email",
|
|
1211
|
+
onChange: (event) => setEmail(event.target.value),
|
|
1212
|
+
placeholder: "voce@exemplo.com",
|
|
1213
|
+
required: true,
|
|
1214
|
+
type: "email",
|
|
1215
|
+
value: email
|
|
1216
|
+
}
|
|
1217
|
+
) }),
|
|
1218
|
+
error && /* @__PURE__ */ jsx("p", { className: "text-xs text-red-600", children: error }),
|
|
1219
|
+
/* @__PURE__ */ jsx(Button, { disabled: busy || !email.trim(), tone: "primary", type: "submit", children: busy ? "Enviando..." : submitLabel })
|
|
1220
|
+
] });
|
|
1221
|
+
}
|
|
1130
1222
|
return {
|
|
1223
|
+
WaitlistForm,
|
|
1131
1224
|
SignInButton,
|
|
1132
1225
|
SignOutButton,
|
|
1133
1226
|
AccountSwitcher,
|
|
@@ -1142,6 +1235,7 @@ function createAuthElements(hooks) {
|
|
|
1142
1235
|
export {
|
|
1143
1236
|
Avatar,
|
|
1144
1237
|
Modal,
|
|
1238
|
+
authErrorMessage,
|
|
1145
1239
|
createAuthElements
|
|
1146
1240
|
};
|
|
1147
1241
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n type ButtonHTMLAttributes,\n type FormEvent,\n type ReactNode,\n useEffect,\n useState,\n} from \"react\";\n\n// ── Local type definitions ────────────────────────────────────────────────────\n\nexport type ElementSize = \"sm\" | \"md\" | \"lg\";\nexport type ElementTone = \"default\" | \"primary\" | \"danger\" | \"ghost\";\n\nexport type ConnectedAccount = {\n id: string;\n sessionId?: string;\n isActive: boolean;\n user: {\n id?: string;\n name: string | null;\n email: string | null;\n imageUrl: string | null;\n phone?: string | null;\n };\n};\n\nexport type Organization = {\n id: string;\n name: string;\n description: string | null;\n slug: string;\n domain: string | null;\n imageUrl: string | null;\n faviconUrl: string | null;\n type?: OrganizationType;\n taxId?: string | null;\n taxIdType?: TaxIdType | null;\n legalName?: string | null;\n members?: Array<{\n id: string;\n user: { name: string | null; email: string | null; imageUrl: string | null };\n roleAssignments?: Array<{\n id: string;\n roleDefinition?: { name: string } | null;\n customRole?: { name: string } | null;\n }>;\n }>;\n};\n\nexport type OrganizationType = \"standard\" | \"legal\";\nexport type TaxIdType = \"br_cnpj\" | \"generic\";\n\ntype OrganizationLegalAddress = Partial<\n Record<\"street\" | \"number\" | \"complement\" | \"district\" | \"city\" | \"state\" | \"postalCode\" | \"country\", string | null>\n>;\n\nexport type OrganizationCreateInput = {\n name: string;\n slug: string;\n type?: OrganizationType;\n taxId?: string | null;\n taxIdType?: string | null;\n taxIdCountry?: string | null;\n legalName?: string | null;\n tradeName?: string | null;\n legalEmail?: string | null;\n legalPhone?: string | null;\n legalAddress?: OrganizationLegalAddress | null;\n};\n\nexport type TaxIdLookupResult = {\n taxId: string;\n taxIdType: TaxIdType;\n taxIdCountry: string | null;\n alreadyRegistered: boolean;\n lookupAvailable: boolean;\n found: boolean;\n registrationStatus: string | null;\n suggestedName: string | null;\n data: {\n legalName: string | null;\n tradeName: string | null;\n legalEmail: string | null;\n legalPhone: string | null;\n legalAddress: OrganizationLegalAddress | null;\n };\n missingFields: string[];\n};\n\nconst ADDRESS_KEYS = [\n \"street\",\n \"number\",\n \"complement\",\n \"district\",\n \"city\",\n \"state\",\n \"postalCode\",\n \"country\",\n] as const;\n\nconst REQUIRED_LEGAL = new Set([\n \"taxIdCountry\",\n \"legalName\",\n \"legalAddress.street\",\n \"legalAddress.city\",\n \"legalAddress.postalCode\",\n \"legalAddress.country\",\n]);\n\nconst EMPTY_ORG_FORM: Record<string, string> = {\n type: \"standard\",\n taxIdType: \"br_cnpj\",\n taxId: \"\",\n name: \"\",\n slug: \"\",\n};\n\nfunction slugify(value: string) {\n return value\n .normalize(\"NFD\")\n .replace(/[\\u0300-\\u036f]/g, \"\")\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\")\n .slice(0, 60);\n}\n\nexport type Permission = {\n id: string;\n key: string;\n category: string | null;\n};\n\nexport type Role = {\n id: string;\n key: string;\n name: string;\n permissions: unknown[];\n};\n\nexport type UserSession = {\n id: string;\n deviceName: string | null;\n ip: string | null;\n expiresAt: string | Date;\n};\n\ntype User = {\n id: string;\n name: string | null;\n email: string | null;\n imageUrl: string | null;\n phone?: string | null;\n};\n\ntype AuthResult<T> =\n | { success: true; data: T }\n | { success: false; error?: string; code?: string; missingFields?: string[] };\n\n// ── Hook contract (structural — no import from auth-nextjs) ───────────────────\n\ntype UseAuthHook = () => {\n user: User | null;\n signIn: (opts?: { redirectTo?: string }) => Promise<void> | void;\n signOut: () => Promise<void> | void;\n signOutAll: () => Promise<void> | void;\n accounts: ConnectedAccount[];\n addAccount: (opts?: { redirectTo?: string }) => Promise<void> | void;\n isLoadingAccounts: boolean;\n refreshAccounts: () => Promise<void>;\n switchAccount: (id: string, opts?: { redirectTo?: string }) => Promise<void>;\n organizations: Organization[];\n currentOrg: Organization | null;\n currentOrgId?: string | null;\n isLoadingOrganizations: boolean;\n refreshOrganizations: () => Promise<void>;\n setCurrentOrg: (id: string) => Promise<void>;\n createOrganization: (input: OrganizationCreateInput) => Promise<AuthResult<Organization>>;\n /** Opcional: SDKs antigos não têm — sem ele, o formulário só não busca os dados do CNPJ. */\n lookupTaxId?: (value: string, type?: TaxIdType) => Promise<AuthResult<TaxIdLookupResult>>;\n updateOrganization: (\n id: string,\n input: Partial<{\n name: string;\n slug: string;\n description: string | null;\n domain: string | null;\n imageUrl: string | null;\n faviconUrl: string | null;\n }>,\n ) => Promise<AuthResult<Organization>>;\n updateUser: (\n id: string,\n input: { name?: string | null; phone?: string | null; imageUrl?: string | null },\n ) => Promise<AuthResult<User>>;\n listUserSessions: (params: { userId?: string; organizationId?: string }) => Promise<UserSession[]>;\n revokeUserSession: (sessionId: string) => Promise<AuthResult<null>>;\n listPermissions: (params: {\n applicationId?: string;\n roleId?: string | null;\n }) => Promise<Permission[]>;\n listRoles: (params?: {\n organizationId?: string;\n applicationId?: string;\n type?: \"system\" | \"custom\" | \"all\";\n }) => Promise<{ systemRoles: Role[]; customRoles: Role[] }>;\n};\n\n// ── Primitive UI helpers ──────────────────────────────────────────────────────\n\ntype ButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & {\n tone?: ElementTone;\n size?: ElementSize;\n};\n\nfunction cx(...classes: Array<string | false | null | undefined>) {\n return classes.filter(Boolean).join(\" \");\n}\n\nfunction initials(value?: string | null) {\n const normalized = value?.trim();\n if (!normalized) return \"?\";\n const parts = normalized.split(/\\s+/).slice(0, 2);\n return parts.map((part) => part[0]?.toUpperCase()).join(\"\") || \"?\";\n}\n\nfunction formatDate(value?: string | Date | null) {\n if (!value) return \"-\";\n return new Intl.DateTimeFormat(undefined, {\n dateStyle: \"medium\",\n timeStyle: \"short\",\n }).format(new Date(value));\n}\n\nfunction isExpired(value: string | Date) {\n return new Date(value).getTime() <= Date.now();\n}\n\nfunction Button({\n className,\n tone = \"default\",\n size = \"md\",\n ...props\n}: ButtonProps) {\n return (\n <button\n {...props}\n className={cx(\n \"inline-flex items-center justify-center gap-2 rounded-lg font-medium transition disabled:cursor-not-allowed disabled:opacity-50\",\n size === \"sm\" && \"h-8 px-3 text-xs\",\n size === \"md\" && \"h-10 px-4 text-sm\",\n size === \"lg\" && \"h-11 px-5 text-sm\",\n tone === \"default\" &&\n \"border border-slate-200 bg-white text-slate-800 hover:bg-slate-50\",\n tone === \"primary\" && \"bg-slate-950 text-white hover:bg-slate-800\",\n tone === \"danger\" && \"bg-red-600 text-white hover:bg-red-700\",\n tone === \"ghost\" &&\n \"bg-transparent text-slate-600 hover:bg-slate-100 hover:text-slate-950\",\n className,\n )}\n />\n );\n}\n\nfunction Input(props: React.InputHTMLAttributes<HTMLInputElement>) {\n return (\n <input\n {...props}\n className={cx(\n \"h-10 w-full rounded-lg border border-slate-200 bg-white px-3 text-sm text-slate-900 outline-none placeholder:text-slate-400 focus:border-slate-400\",\n props.className,\n )}\n />\n );\n}\n\nfunction Textarea(props: React.TextareaHTMLAttributes<HTMLTextAreaElement>) {\n return (\n <textarea\n {...props}\n className={cx(\n \"min-h-[86px] w-full resize-none rounded-lg border border-slate-200 bg-white px-3 py-2 text-sm text-slate-900 outline-none placeholder:text-slate-400 focus:border-slate-400\",\n props.className,\n )}\n />\n );\n}\n\nfunction Field({ label, children }: { label: string; children: ReactNode }) {\n return (\n <label className=\"grid gap-1.5\">\n <span className=\"text-xs font-medium text-slate-600\">{label}</span>\n {children}\n </label>\n );\n}\n\n// ── Standalone components (no hooks) ─────────────────────────────────────────\n\nexport function Avatar({\n src,\n name,\n size = \"md\",\n className,\n}: {\n src?: string | null;\n name?: string | null;\n size?: ElementSize;\n className?: string;\n}) {\n return (\n <span\n className={cx(\n \"inline-flex shrink-0 items-center justify-center overflow-hidden rounded-full bg-slate-100 font-semibold text-slate-700\",\n size === \"sm\" && \"h-8 w-8 text-xs\",\n size === \"md\" && \"h-10 w-10 text-sm\",\n size === \"lg\" && \"h-12 w-12 text-base\",\n className,\n )}\n >\n {src ? (\n <img\n alt={name ?? \"Avatar\"}\n className=\"h-full w-full object-cover\"\n src={src}\n />\n ) : (\n initials(name)\n )}\n </span>\n );\n}\n\nexport function Modal({\n open,\n onOpenChange,\n title,\n description,\n children,\n footer,\n}: {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n title: string;\n description?: string;\n children: ReactNode;\n footer?: ReactNode;\n}) {\n if (!open) return null;\n\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4\">\n <div className=\"max-h-[90vh] w-full max-w-3xl overflow-hidden rounded-2xl bg-white shadow-xl\">\n <div className=\"flex items-start justify-between gap-4 border-b border-slate-200 p-5\">\n <div>\n <h2 className=\"text-lg font-semibold text-slate-950\">{title}</h2>\n {description && (\n <p className=\"mt-1 text-sm text-slate-500\">{description}</p>\n )}\n </div>\n <Button\n aria-label=\"Close\"\n onClick={() => onOpenChange(false)}\n size=\"sm\"\n tone=\"ghost\"\n type=\"button\"\n >\n ✕\n </Button>\n </div>\n <div className=\"max-h-[68vh] overflow-y-auto p-5\">{children}</div>\n {footer && (\n <div className=\"border-t border-slate-200 p-5\">{footer}</div>\n )}\n </div>\n </div>\n );\n}\n\n// ── Factory ───────────────────────────────────────────────────────────────────\n\n/**\n * Creates auth UI components bound to the provided `useAuth` hook instance.\n * This lets consumers supply their own auth-nextjs instance without requiring\n * a separate installed copy inside auth-elements-nextjs.\n *\n * @example\n * import { createAuthElements } from '@geekapps/auth-elements-nextjs'\n * import { useAuth } from '@geekapps/auth-nextjs/client'\n * export const { SignInButton, ProfileModal } = createAuthElements({ useAuth })\n */\nexport function createAuthElements(hooks: { useAuth: UseAuthHook }) {\n const { useAuth } = hooks;\n\n function SignInButton({\n children = \"Entrar\",\n redirectTo,\n }: {\n children?: ReactNode;\n redirectTo?: string;\n }) {\n const { signIn } = useAuth();\n return (\n <Button\n onClick={() => void signIn({ redirectTo })}\n tone=\"primary\"\n type=\"button\"\n >\n {children}\n </Button>\n );\n }\n\n function SignOutButton({ children = \"Sair\" }: { children?: ReactNode }) {\n const { signOut } = useAuth();\n return (\n <Button onClick={() => void signOut()} tone=\"ghost\" type=\"button\">\n {children}\n </Button>\n );\n }\n\n function AccountSwitcher() {\n const {\n accounts,\n addAccount,\n isLoadingAccounts,\n refreshAccounts,\n switchAccount,\n } = useAuth();\n const activeAccount =\n accounts.find((account) => account.isActive) ?? accounts[0] ?? null;\n const [open, setOpen] = useState(false);\n\n return (\n <div className=\"relative\">\n <button\n className=\"flex h-10 w-10 items-center justify-center rounded-xl transition hover:opacity-80\"\n onClick={() => setOpen((value) => !value)}\n title={activeAccount?.user.name ?? activeAccount?.user.email ?? \"Conta\"}\n type=\"button\"\n >\n <Avatar\n name={activeAccount?.user.name ?? activeAccount?.user.email}\n size=\"sm\"\n src={activeAccount?.user.imageUrl}\n />\n </button>\n\n {open && (\n <>\n <div className=\"fixed inset-0 z-20\" onClick={() => setOpen(false)} />\n <div className=\"absolute bottom-0 left-14 z-30 w-72 overflow-hidden rounded-xl border border-slate-200 bg-white shadow-lg\">\n <div className=\"border-b border-slate-100 px-3 py-2.5\">\n <p className=\"text-[11px] font-medium uppercase tracking-wider text-slate-400\">\n Contas\n </p>\n </div>\n <div className=\"p-1.5\">\n {isLoadingAccounts && (\n <p className=\"px-2 py-3 text-xs text-slate-400\">\n Carregando...\n </p>\n )}\n {accounts.map((account) => (\n <button\n className={cx(\n \"flex w-full items-center gap-2.5 rounded-lg px-2 py-2 text-left transition hover:bg-slate-50\",\n account.isActive && \"bg-slate-50\",\n )}\n key={account.sessionId ?? account.id}\n onClick={() => {\n void switchAccount(account.sessionId ?? account.id);\n setOpen(false);\n }}\n type=\"button\"\n >\n <Avatar\n name={account.user.name ?? account.user.email}\n size=\"sm\"\n src={account.user.imageUrl}\n />\n <span className=\"min-w-0 flex-1\">\n <span className=\"block truncate text-sm font-medium text-slate-900\">\n {account.user.name ?? account.user.email}\n </span>\n <span className=\"block truncate text-xs text-slate-500\">\n {account.user.email}\n </span>\n </span>\n {account.isActive && (\n <span className=\"shrink-0 text-xs font-medium text-emerald-600\">\n ✓\n </span>\n )}\n </button>\n ))}\n </div>\n <div className=\"flex gap-1.5 border-t border-slate-100 p-1.5\">\n <Button\n className=\"flex-1\"\n onClick={() => void addAccount()}\n size=\"sm\"\n type=\"button\"\n >\n + Conta\n </Button>\n <Button\n className=\"flex-1\"\n onClick={() => void refreshAccounts()}\n size=\"sm\"\n tone=\"ghost\"\n type=\"button\"\n >\n Atualizar\n </Button>\n </div>\n </div>\n </>\n )}\n </div>\n );\n }\n\n // Formulário de criação compartilhado: organização padrão (sem documento)\n // ou legal (associada a CNPJ / Tax ID, com os dados da empresa buscados\n // automaticamente e os obrigatórios que faltarem pedidos ao usuário).\n function CreateOrganizationForm({\n onCreated,\n onCancel,\n compact = false,\n }: {\n onCreated?: (organization: Organization) => void;\n onCancel?: () => void;\n compact?: boolean;\n }) {\n const { createOrganization, lookupTaxId, setCurrentOrg } = useAuth();\n const [values, setValues] = useState<Record<string, string>>({ ...EMPTY_ORG_FORM });\n const [missing, setMissing] = useState<string[]>([]);\n const [lookupInfo, setLookupInfo] = useState<string | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [busy, setBusy] = useState<\"lookup\" | \"create\" | null>(null);\n const isLegal = values.type === \"legal\";\n const isCnpj = values.taxIdType === \"br_cnpj\";\n\n const set = (key: string, value: string) =>\n setValues((current) => {\n const next = { ...current, [key]: value };\n if (key === \"name\" && !current.slugTouched) next.slug = slugify(value);\n if (key === \"slug\") next.slugTouched = \"1\";\n return next;\n });\n\n async function runLookup() {\n if (!lookupTaxId || !values.taxId) return;\n setBusy(\"lookup\");\n setError(null);\n setLookupInfo(null);\n const result = await lookupTaxId(values.taxId, values.taxIdType as TaxIdType);\n setBusy(null);\n if (!result.success) {\n setError(result.error ?? \"Tax ID inválido.\");\n return;\n }\n const { data } = result.data;\n setValues((current) => {\n const next: Record<string, string> = { ...current, taxId: result.data.taxId };\n const fill = (key: string, value: string | null | undefined) => {\n if (value && !current[key]) next[key] = value;\n };\n fill(\"legalName\", data.legalName);\n fill(\"tradeName\", data.tradeName);\n fill(\"legalEmail\", data.legalEmail);\n fill(\"legalPhone\", data.legalPhone);\n for (const key of ADDRESS_KEYS) fill(`legalAddress.${key}`, data.legalAddress?.[key]);\n if (result.data.taxIdCountry) next.taxIdCountry = result.data.taxIdCountry;\n if (!current.name && result.data.suggestedName) {\n next.name = result.data.suggestedName;\n if (!current.slugTouched) next.slug = slugify(result.data.suggestedName);\n }\n return next;\n });\n setMissing(result.data.missingFields);\n if (result.data.alreadyRegistered) {\n setError(\"Já existe uma organização com este documento neste app.\");\n } else if (result.data.found) {\n setLookupInfo(\n `Dados encontrados${result.data.registrationStatus ? ` · situação ${result.data.registrationStatus}` : \"\"}. Revise e complete o que faltar.`,\n );\n } else {\n setLookupInfo(\n result.data.lookupAvailable\n ? \"Documento válido, mas sem dados públicos. Preencha os campos obrigatórios.\"\n : \"Consulta indisponível no momento. Preencha os campos obrigatórios.\",\n );\n }\n }\n\n async function onSubmit(event: FormEvent<HTMLFormElement>) {\n event.preventDefault();\n setBusy(\"create\");\n setError(null);\n const blank = (key: string) => values[key]?.trim() || null;\n const input: OrganizationCreateInput = {\n name: values.name.trim(),\n slug: values.slug.trim(),\n type: isLegal ? \"legal\" : \"standard\",\n };\n if (isLegal) {\n Object.assign(input, {\n taxId: blank(\"taxId\"),\n taxIdType: values.taxIdType,\n taxIdCountry: isCnpj ? \"BR\" : blank(\"taxIdCountry\"),\n legalName: blank(\"legalName\"),\n tradeName: blank(\"tradeName\"),\n legalEmail: blank(\"legalEmail\"),\n legalPhone: blank(\"legalPhone\"),\n legalAddress: Object.fromEntries(\n ADDRESS_KEYS.map((key) => [key, blank(`legalAddress.${key}`)]),\n ),\n });\n if (!isCnpj && !input.legalAddress?.country) {\n (input.legalAddress as Record<string, string | null>).country = blank(\"taxIdCountry\");\n }\n }\n const result = await createOrganization(input);\n setBusy(null);\n if (!result.success) {\n if (result.missingFields?.length) setMissing(result.missingFields);\n setError(result.error ?? \"Erro ao criar organização.\");\n return;\n }\n setValues({ ...EMPTY_ORG_FORM });\n setMissing([]);\n setLookupInfo(null);\n if (result.data?.id) void setCurrentOrg(result.data.id);\n onCreated?.(result.data);\n }\n\n const field = (key: string, label: string, props: React.InputHTMLAttributes<HTMLInputElement> = {}) => {\n const required = REQUIRED_LEGAL.has(key);\n return (\n <Field label={`${label}${required ? \" *\" : \"\"}`}>\n <Input\n {...props}\n className={missing.includes(key) && !values[key] ? \"border-red-300\" : undefined}\n name={key}\n onChange={(event) => set(key, event.target.value)}\n required={required}\n value={values[key] ?? \"\"}\n />\n </Field>\n );\n };\n\n return (\n <form className={cx(\"grid\", compact ? \"gap-2\" : \"gap-4\")} onSubmit={onSubmit}>\n <div className=\"grid grid-cols-2 gap-1 rounded-lg bg-slate-100 p-1\">\n {(\n [\n [\"standard\", \"Padrão\"],\n [\"legal\", \"Empresa (CNPJ / Tax ID)\"],\n ] as const\n ).map(([type, label]) => (\n <button\n className={cx(\n \"rounded-md px-2 py-1.5 text-xs font-medium transition\",\n values.type === type ? \"bg-white text-slate-900 shadow-sm\" : \"text-slate-500\",\n )}\n key={type}\n onClick={() => set(\"type\", type)}\n type=\"button\"\n >\n {label}\n </button>\n ))}\n </div>\n\n {isLegal && (\n <>\n <div className=\"grid grid-cols-[auto_1fr] gap-2\">\n <select\n className=\"h-10 rounded-lg border border-slate-200 bg-white px-2 text-sm text-slate-900\"\n onChange={(event) => set(\"taxIdType\", event.target.value)}\n value={values.taxIdType}\n >\n <option value=\"br_cnpj\">CNPJ</option>\n <option value=\"generic\">Outro Tax ID</option>\n </select>\n <div className=\"flex gap-2\">\n <Input\n name=\"taxId\"\n onBlur={() => isCnpj && void runLookup()}\n onChange={(event) => set(\"taxId\", event.target.value)}\n placeholder={isCnpj ? \"00.000.000/0000-00\" : \"Tax ID\"}\n required\n value={values.taxId}\n />\n <Button disabled={busy !== null || !values.taxId} onClick={() => void runLookup()} size=\"sm\" type=\"button\">\n {busy === \"lookup\" ? \"Buscando…\" : isCnpj ? \"Buscar\" : \"Validar\"}\n </Button>\n </div>\n </div>\n {!isCnpj && field(\"taxIdCountry\", \"País do Tax ID (ISO, ex.: US)\", { maxLength: 2 })}\n {lookupInfo && (\n <p className=\"rounded-lg bg-slate-50 px-3 py-2 text-xs text-slate-600\">{lookupInfo}</p>\n )}\n </>\n )}\n\n {field(\"name\", \"Nome\", { placeholder: \"Minha organização\", required: true })}\n {field(\"slug\", \"Slug\", { placeholder: \"minha-org\", required: true })}\n\n {isLegal && (\n <>\n {field(\"legalName\", \"Razão social\")}\n {field(\"tradeName\", \"Nome fantasia\")}\n <div className=\"grid gap-2 sm:grid-cols-2\">\n {field(\"legalEmail\", \"E-mail\", { type: \"email\" })}\n {field(\"legalPhone\", \"Telefone\")}\n </div>\n {field(\"legalAddress.street\", \"Logradouro\")}\n <div className=\"grid gap-2 sm:grid-cols-2\">\n {field(\"legalAddress.number\", \"Número\")}\n {field(\"legalAddress.complement\", \"Complemento\")}\n {field(\"legalAddress.district\", \"Bairro\")}\n {field(\"legalAddress.city\", \"Cidade\")}\n {field(\"legalAddress.state\", \"Estado\")}\n {field(\"legalAddress.postalCode\", \"CEP / Código postal\")}\n </div>\n {!isCnpj && field(\"legalAddress.country\", \"País do endereço (ISO)\", { maxLength: 2 })}\n </>\n )}\n\n {error && <p className=\"rounded-lg bg-red-50 px-3 py-2 text-xs text-red-600\">{error}</p>}\n\n <div className=\"flex justify-end gap-2\">\n {onCancel && (\n <Button onClick={onCancel} size=\"sm\" tone=\"ghost\" type=\"button\">\n Cancelar\n </Button>\n )}\n <Button disabled={busy !== null} size=\"sm\" tone=\"primary\" type=\"submit\">\n {busy === \"create\" ? \"Criando…\" : \"Criar organização\"}\n </Button>\n </div>\n </form>\n );\n }\n\n function OrgSwitcher() {\n const {\n currentOrg,\n isLoadingOrganizations,\n organizations,\n refreshOrganizations,\n setCurrentOrg,\n } = useAuth();\n const [open, setOpen] = useState(false);\n const [creating, setCreating] = useState(false);\n\n return (\n <div className=\"relative\">\n <button\n className=\"flex w-full items-center gap-3 rounded-xl border border-slate-200 bg-white p-2 text-left hover:bg-slate-50\"\n onClick={() => setOpen((value) => !value)}\n type=\"button\"\n >\n <Avatar name={currentOrg?.name} src={currentOrg?.imageUrl} />\n <span className=\"min-w-0 flex-1\">\n <span className=\"block truncate text-sm font-medium text-slate-950\">\n {currentOrg?.name ?? \"Selecionar organização\"}\n </span>\n <span className=\"block truncate text-xs text-slate-500\">\n {isLoadingOrganizations\n ? \"Carregando...\"\n : `${organizations.length} organizações`}\n </span>\n </span>\n <span className=\"text-slate-400\">⌄</span>\n </button>\n\n {open && (\n <div className=\"absolute right-0 z-30 mt-2 w-80 overflow-hidden rounded-xl border border-slate-200 bg-white shadow-lg\">\n <div className=\"max-h-72 overflow-y-auto p-2\">\n {organizations.map((organization) => (\n <button\n className=\"flex w-full items-center gap-3 rounded-lg p-2 text-left hover:bg-slate-50\"\n key={organization.id}\n onClick={() => {\n void setCurrentOrg(organization.id);\n setOpen(false);\n }}\n type=\"button\"\n >\n <Avatar\n name={organization.name}\n size=\"sm\"\n src={organization.imageUrl}\n />\n <span className=\"min-w-0 flex-1\">\n <span className=\"block truncate text-sm font-medium text-slate-900\">\n {organization.name}\n </span>\n <span className=\"block truncate text-xs text-slate-500\">\n {organization.slug}\n </span>\n </span>\n {organization.id === currentOrg?.id && (\n <span className=\"text-xs font-medium text-emerald-600\">\n Atual\n </span>\n )}\n </button>\n ))}\n </div>\n\n {creating ? (\n <div className=\"max-h-[70vh] overflow-y-auto border-t border-slate-200 p-3\">\n <CreateOrganizationForm\n compact\n onCancel={() => setCreating(false)}\n onCreated={() => {\n setCreating(false);\n setOpen(false);\n void refreshOrganizations();\n }}\n />\n </div>\n ) : (\n <div className=\"flex gap-2 border-t border-slate-200 p-2\">\n <Button\n className=\"flex-1\"\n onClick={() => setCreating(true)}\n size=\"sm\"\n type=\"button\"\n >\n Nova org\n </Button>\n <Button\n className=\"flex-1\"\n onClick={() => void refreshOrganizations()}\n size=\"sm\"\n tone=\"ghost\"\n type=\"button\"\n >\n Atualizar\n </Button>\n </div>\n )}\n </div>\n )}\n </div>\n );\n }\n\n function UserButton() {\n const { user } = useAuth();\n const [open, setOpen] = useState(false);\n return (\n <>\n <button onClick={() => setOpen(true)} type=\"button\">\n <Avatar name={user?.name ?? user?.email} src={user?.imageUrl} />\n </button>\n <ProfileModal open={open} onOpenChange={setOpen} />\n </>\n );\n }\n\n function OrganizationButton() {\n const { currentOrg } = useAuth();\n const [open, setOpen] = useState(false);\n return (\n <>\n <button\n className=\"flex h-10 w-10 items-center justify-center rounded-xl bg-white border border-slate-200 text-xs font-semibold text-slate-700 transition hover:bg-slate-50 hover:border-slate-300\"\n onClick={() => setOpen(true)}\n title={currentOrg?.name ?? \"Organização\"}\n type=\"button\"\n >\n {currentOrg?.imageUrl ? (\n <img\n alt={currentOrg.name}\n className=\"h-full w-full rounded-xl object-cover\"\n src={currentOrg.imageUrl}\n />\n ) : (\n (currentOrg?.name ?? \"O\")[0]?.toUpperCase()\n )}\n </button>\n <ManageOrganizationModal open={open} onOpenChange={setOpen} />\n </>\n );\n }\n\n function ProfileModal({\n open,\n onOpenChange,\n }: {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n }) {\n const {\n signOut,\n signOutAll,\n user,\n organizations,\n currentOrg,\n setCurrentOrg,\n updateUser,\n listUserSessions,\n revokeUserSession,\n } = useAuth();\n const [tab, setTab] = useState(\"profile\");\n const [sessions, setSessions] = useState<UserSession[]>([]);\n const [saving, setSaving] = useState(false);\n const [saveError, setSaveError] = useState<string | null>(null);\n const [saveSuccess, setSaveSuccess] = useState(false);\n\n useEffect(() => {\n if (!open) {\n setTab(\"profile\");\n setSaveError(null);\n setSaveSuccess(false);\n }\n }, [open]);\n\n useEffect(() => {\n if (open && user && tab === \"sessions\") {\n void listUserSessions({ userId: user.id })\n .then(setSessions)\n .catch(() => setSessions([]));\n }\n }, [listUserSessions, open, tab, user]);\n\n async function onProfileSubmit(event: FormEvent<HTMLFormElement>) {\n event.preventDefault();\n if (!user) return;\n const form = new FormData(event.currentTarget);\n setSaving(true);\n setSaveError(null);\n setSaveSuccess(false);\n try {\n await updateUser(user.id, {\n name: String(form.get(\"name\") ?? \"\") || null,\n phone: String(form.get(\"phone\") ?? \"\") || null,\n imageUrl: String(form.get(\"imageUrl\") ?? \"\") || null,\n });\n setSaveSuccess(true);\n setTimeout(() => setSaveSuccess(false), 2500);\n } catch (err) {\n setSaveError(err instanceof Error ? err.message : \"Erro ao salvar.\");\n } finally {\n setSaving(false);\n }\n }\n\n if (!open) return null;\n\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4\">\n <div className=\"flex max-h-[90vh] w-full max-w-lg flex-col overflow-hidden rounded-2xl bg-white shadow-2xl\">\n {/* Header */}\n <div className=\"flex shrink-0 items-center justify-between border-b border-slate-100 px-6 py-4\">\n <div className=\"flex items-center gap-3\">\n <Avatar\n name={user?.name ?? user?.email}\n size=\"sm\"\n src={user?.imageUrl}\n />\n <div>\n <p className=\"text-sm font-semibold text-slate-900\">\n {user?.name ?? user?.email ?? \"Minha conta\"}\n </p>\n <p className=\"text-xs text-slate-500\">{user?.email}</p>\n </div>\n </div>\n <button\n aria-label=\"Fechar\"\n className=\"rounded-lg p-1.5 text-slate-400 transition hover:bg-slate-100 hover:text-slate-700\"\n onClick={() => onOpenChange(false)}\n type=\"button\"\n >\n ✕\n </button>\n </div>\n\n {/* Tabs */}\n <div className=\"shrink-0 flex gap-1 border-b border-slate-100 px-6 pt-3\">\n {(\n [\n { id: \"profile\", label: \"Perfil\" },\n { id: \"sessions\", label: \"Sessões\" },\n { id: \"orgs\", label: \"Organizações\" },\n ] as const\n ).map((t) => (\n <button\n className={cx(\n \"mb-[-1px] border-b-2 px-3 pb-2.5 text-xs font-medium transition\",\n tab === t.id\n ? \"border-slate-900 text-slate-900\"\n : \"border-transparent text-slate-500 hover:text-slate-700\",\n )}\n key={t.id}\n onClick={() => setTab(t.id)}\n type=\"button\"\n >\n {t.label}\n </button>\n ))}\n </div>\n\n {/* Body */}\n <div className=\"flex-1 overflow-y-auto px-6 py-5\">\n {tab === \"profile\" && user && (\n <form className=\"grid gap-4\" onSubmit={onProfileSubmit}>\n <div className=\"flex items-center gap-4 rounded-xl bg-slate-50 p-4\">\n <Avatar\n name={user.name ?? user.email}\n size=\"lg\"\n src={user.imageUrl}\n />\n <div>\n <p className=\"text-sm font-semibold text-slate-900\">\n {user.name ?? \"Sem nome\"}\n </p>\n <p className=\"text-xs text-slate-500\">{user.email}</p>\n </div>\n </div>\n\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <Field label=\"Nome\">\n <Input\n defaultValue={user.name ?? \"\"}\n name=\"name\"\n placeholder=\"Seu nome\"\n />\n </Field>\n <Field label=\"Telefone\">\n <Input\n defaultValue={user.phone ?? \"\"}\n name=\"phone\"\n placeholder=\"+55 11 99999-9999\"\n />\n </Field>\n </div>\n <Field label=\"URL da imagem\">\n <Input\n defaultValue={user.imageUrl ?? \"\"}\n name=\"imageUrl\"\n placeholder=\"https://...\"\n />\n </Field>\n\n {saveError && (\n <p className=\"rounded-lg bg-red-50 px-3 py-2 text-xs text-red-600\">\n {saveError}\n </p>\n )}\n {saveSuccess && (\n <p className=\"rounded-lg bg-emerald-50 px-3 py-2 text-xs text-emerald-600\">\n Perfil salvo com sucesso.\n </p>\n )}\n\n <div className=\"flex items-center justify-between border-t border-slate-100 pt-2\">\n <div className=\"flex gap-2\">\n <Button\n onClick={() => void signOut()}\n size=\"sm\"\n tone=\"ghost\"\n type=\"button\"\n >\n Sair\n </Button>\n <Button\n onClick={() => void signOutAll()}\n size=\"sm\"\n tone=\"danger\"\n type=\"button\"\n >\n Sair de todas\n </Button>\n </div>\n <Button\n disabled={saving}\n size=\"sm\"\n tone=\"primary\"\n type=\"submit\"\n >\n {saving ? \"Salvando…\" : \"Salvar\"}\n </Button>\n </div>\n </form>\n )}\n\n {tab === \"sessions\" && (\n <div className=\"grid gap-2\">\n {sessions.length === 0 && (\n <p className=\"py-6 text-center text-sm text-slate-400\">\n Nenhuma sessão ativa.\n </p>\n )}\n {sessions.map((session) => {\n const expired = isExpired(session.expiresAt);\n return (\n <div\n className=\"flex items-center justify-between gap-4 rounded-xl border border-slate-200 p-4\"\n key={session.id}\n >\n <div className=\"min-w-0\">\n <p className=\"truncate text-sm font-medium text-slate-900\">\n {session.deviceName ?? \"Dispositivo\"}\n </p>\n <p className=\"mt-0.5 truncate text-xs text-slate-500\">\n {session.ip ?? \"IP desconhecido\"} ·{\" \"}\n <span className={expired ? \"text-amber-600\" : \"\"}>\n {expired\n ? \"Expirada\"\n : `Expira ${formatDate(session.expiresAt)}`}\n </span>\n </p>\n </div>\n <Button\n onClick={async () => {\n await revokeUserSession(session.id);\n setSessions((s) =>\n s.filter((x) => x.id !== session.id),\n );\n }}\n size=\"sm\"\n tone=\"danger\"\n type=\"button\"\n >\n Revogar\n </Button>\n </div>\n );\n })}\n </div>\n )}\n\n {tab === \"orgs\" && (\n <div className=\"grid gap-2\">\n {organizations.length === 0 && (\n <p className=\"py-6 text-center text-sm text-slate-400\">\n Nenhuma organização.\n </p>\n )}\n {organizations.map((org) => (\n <button\n className={cx(\n \"flex w-full items-center gap-3 rounded-xl border p-3 text-left transition\",\n org.id === currentOrg?.id\n ? \"border-slate-900 bg-slate-50\"\n : \"border-slate-200 hover:border-slate-300 hover:bg-slate-50\",\n )}\n key={org.id}\n onClick={() => void setCurrentOrg(org.id)}\n type=\"button\"\n >\n <Avatar name={org.name} size=\"sm\" src={org.imageUrl} />\n <div className=\"min-w-0 flex-1\">\n <p className=\"truncate text-sm font-medium text-slate-900\">\n {org.name}\n </p>\n <p className=\"truncate text-xs text-slate-500\">\n /{org.slug}\n </p>\n </div>\n {org.id === currentOrg?.id && (\n <span className=\"shrink-0 rounded-full bg-slate-900 px-2 py-0.5 text-[10px] font-medium text-white\">\n Ativa\n </span>\n )}\n </button>\n ))}\n </div>\n )}\n </div>\n </div>\n </div>\n );\n }\n\n function ManageOrganizationModal({\n open,\n onOpenChange,\n }: {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n }) {\n const {\n createOrganization,\n currentOrg,\n organizations,\n refreshOrganizations,\n setCurrentOrg,\n updateOrganization,\n listPermissions,\n listRoles,\n } = useAuth();\n const [tab, setTab] = useState(\"orgs\");\n const [roles, setRoles] = useState<{\n systemRoles: Role[];\n customRoles: Role[];\n }>({ systemRoles: [], customRoles: [] });\n const [permissions, setPermissions] = useState<Permission[]>([]);\n const [saving, setSaving] = useState(false);\n const [saveSuccess, setSaveSuccess] = useState(false);\n const [saveError, setSaveError] = useState<string | null>(null);\n\n useEffect(() => {\n if (!open) {\n setTab(\"orgs\");\n setSaveError(null);\n setSaveSuccess(false);\n }\n }, [open]);\n\n useEffect(() => {\n if (!open || !currentOrg) return;\n if (tab === \"members\" || tab === \"roles\") {\n void listRoles({ organizationId: currentOrg.id })\n .then(setRoles)\n .catch(() => setRoles({ systemRoles: [], customRoles: [] }));\n void listPermissions({})\n .then(setPermissions)\n .catch(() => setPermissions([]));\n }\n }, [currentOrg, listPermissions, listRoles, open, tab]);\n\n async function onOrgSubmit(event: FormEvent<HTMLFormElement>) {\n event.preventDefault();\n if (!currentOrg) return;\n const form = new FormData(event.currentTarget);\n setSaving(true);\n setSaveError(null);\n setSaveSuccess(false);\n try {\n await updateOrganization(currentOrg.id, {\n name: String(form.get(\"name\") ?? \"\"),\n description: String(form.get(\"description\") ?? \"\") || null,\n slug: String(form.get(\"slug\") ?? \"\"),\n domain: String(form.get(\"domain\") ?? \"\") || null,\n imageUrl: String(form.get(\"imageUrl\") ?? \"\") || null,\n faviconUrl: String(form.get(\"faviconUrl\") ?? \"\") || null,\n });\n setSaveSuccess(true);\n setTimeout(() => setSaveSuccess(false), 2500);\n } catch (err) {\n setSaveError(err instanceof Error ? err.message : \"Erro ao salvar.\");\n } finally {\n setSaving(false);\n }\n }\n\n if (!open) return null;\n\n const orgTabs = [\n { id: \"orgs\", label: \"Organizações\" },\n { id: \"info\", label: \"Geral\" },\n { id: \"members\", label: \"Membros\" },\n { id: \"roles\", label: \"Roles\" },\n { id: \"new\", label: \"+ Nova org\" },\n ] as const;\n\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4\">\n <div className=\"flex max-h-[90vh] w-full max-w-2xl flex-col overflow-hidden rounded-2xl bg-white shadow-2xl\">\n {/* Header */}\n <div className=\"flex shrink-0 items-center justify-between border-b border-slate-100 px-6 py-4\">\n <div className=\"flex items-center gap-3\">\n {currentOrg?.imageUrl ? (\n <img\n alt={currentOrg.name}\n className=\"h-8 w-8 rounded-lg object-cover\"\n src={currentOrg.imageUrl}\n />\n ) : (\n <span className=\"flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-slate-100 text-xs font-semibold text-slate-600\">\n {(currentOrg?.name ?? \"O\")[0]?.toUpperCase()}\n </span>\n )}\n <div>\n <p className=\"text-sm font-semibold text-slate-900\">\n {currentOrg?.name ?? \"Organização\"}\n </p>\n {currentOrg?.slug && (\n <p className=\"text-xs text-slate-500\">/{currentOrg.slug}</p>\n )}\n </div>\n </div>\n <button\n aria-label=\"Fechar\"\n className=\"rounded-lg p-1.5 text-slate-400 transition hover:bg-slate-100 hover:text-slate-700\"\n onClick={() => onOpenChange(false)}\n type=\"button\"\n >\n ✕\n </button>\n </div>\n\n {/* Tabs */}\n <div className=\"flex shrink-0 gap-1 border-b border-slate-100 px-6 pt-3\">\n {orgTabs.map((t) => (\n <button\n className={cx(\n \"mb-[-1px] border-b-2 px-3 pb-2.5 text-xs font-medium transition\",\n tab === t.id\n ? \"border-slate-900 text-slate-900\"\n : \"border-transparent text-slate-500 hover:text-slate-700\",\n )}\n key={t.id}\n onClick={() => setTab(t.id)}\n type=\"button\"\n >\n {t.label}\n </button>\n ))}\n </div>\n\n {/* Body */}\n <div className=\"flex-1 overflow-y-auto px-6 py-5\">\n {!currentOrg && (\n <p className=\"py-8 text-center text-sm text-slate-400\">\n Nenhuma organização selecionada.\n </p>\n )}\n\n {tab === \"orgs\" && (\n <div className=\"grid gap-2\">\n {organizations.length === 0 && (\n <p className=\"py-8 text-center text-sm text-slate-400\">\n Nenhuma organização disponível.\n </p>\n )}\n {organizations.map((org) => (\n <button\n className={cx(\n \"flex w-full items-center gap-3 rounded-xl border p-3 text-left transition\",\n org.id === currentOrg?.id\n ? \"border-slate-900 bg-slate-50\"\n : \"border-slate-200 hover:border-slate-300 hover:bg-slate-50\",\n )}\n key={org.id}\n onClick={() => {\n void setCurrentOrg(org.id);\n onOpenChange(false);\n }}\n type=\"button\"\n >\n <Avatar name={org.name} size=\"sm\" src={org.imageUrl} />\n <div className=\"min-w-0 flex-1\">\n <p className=\"truncate text-sm font-medium text-slate-900\">\n {org.name}\n </p>\n <p className=\"truncate text-xs text-slate-500\">\n /{org.slug}\n </p>\n </div>\n {org.id === currentOrg?.id && (\n <span className=\"shrink-0 rounded-full bg-slate-900 px-2 py-0.5 text-[10px] font-medium text-white\">\n Ativa\n </span>\n )}\n </button>\n ))}\n </div>\n )}\n\n {tab === \"info\" && currentOrg && (\n <form className=\"grid gap-4\" onSubmit={onOrgSubmit}>\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <Field label=\"Nome *\">\n <Input defaultValue={currentOrg.name} name=\"name\" required />\n </Field>\n <Field label=\"Slug *\">\n <Input defaultValue={currentOrg.slug} name=\"slug\" required />\n </Field>\n </div>\n <Field label=\"Descrição\">\n <Textarea\n defaultValue={currentOrg.description ?? \"\"}\n name=\"description\"\n placeholder=\"Descreva a organização…\"\n />\n </Field>\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <Field label=\"Domínio\">\n <Input\n defaultValue={currentOrg.domain ?? \"\"}\n name=\"domain\"\n placeholder=\"acme.com\"\n />\n </Field>\n <Field label=\"URL da imagem\">\n <Input\n defaultValue={currentOrg.imageUrl ?? \"\"}\n name=\"imageUrl\"\n placeholder=\"https://...\"\n />\n </Field>\n </div>\n <Field label=\"URL do favicon\">\n <Input\n defaultValue={currentOrg.faviconUrl ?? \"\"}\n name=\"faviconUrl\"\n placeholder=\"https://...\"\n />\n </Field>\n\n {saveError && (\n <p className=\"rounded-lg bg-red-50 px-3 py-2 text-xs text-red-600\">\n {saveError}\n </p>\n )}\n {saveSuccess && (\n <p className=\"rounded-lg bg-emerald-50 px-3 py-2 text-xs text-emerald-600\">\n Organização atualizada.\n </p>\n )}\n\n <div className=\"flex justify-end pt-1\">\n <Button\n disabled={saving}\n size=\"sm\"\n tone=\"primary\"\n type=\"submit\"\n >\n {saving ? \"Salvando…\" : \"Salvar organização\"}\n </Button>\n </div>\n </form>\n )}\n\n {tab === \"members\" && currentOrg && (\n <div className=\"grid gap-2\">\n {(currentOrg.members ?? []).length === 0 && (\n <p className=\"py-8 text-center text-sm text-slate-400\">\n Nenhum membro nesta organização.\n </p>\n )}\n {(currentOrg.members ?? []).map((member) => (\n <div\n className=\"flex items-center gap-3 rounded-xl border border-slate-200 p-4\"\n key={member.id}\n >\n <Avatar\n name={member.user.name ?? member.user.email}\n size=\"sm\"\n src={member.user.imageUrl}\n />\n <div className=\"min-w-0 flex-1\">\n <p className=\"truncate text-sm font-medium text-slate-900\">\n {member.user.name ?? member.user.email}\n </p>\n <p className=\"truncate text-xs text-slate-500\">\n {member.user.email}\n </p>\n </div>\n <div className=\"flex shrink-0 flex-wrap justify-end gap-1\">\n {(member.roleAssignments ?? []).map((a) => (\n <span\n className=\"rounded-full bg-slate-900 px-2 py-0.5 text-[11px] font-medium text-white\"\n key={a.id}\n >\n {a.roleDefinition?.name ?? a.customRole?.name ?? a.id}\n </span>\n ))}\n </div>\n </div>\n ))}\n </div>\n )}\n\n {tab === \"new\" && (\n <div className=\"grid gap-4\">\n <p className=\"text-sm text-slate-500\">\n Crie uma nova organização e alterne para ela automaticamente.\n </p>\n <CreateOrganizationForm\n onCancel={() => setTab(\"info\")}\n onCreated={() => {\n void refreshOrganizations();\n setTab(\"info\");\n }}\n />\n </div>\n )}\n\n {tab === \"roles\" && (\n <div className=\"grid gap-5 sm:grid-cols-2\">\n <div className=\"min-w-0\">\n <h3 className=\"mb-3 text-xs font-semibold uppercase tracking-wider text-slate-400\">\n Roles ({roles.systemRoles.length + roles.customRoles.length})\n </h3>\n <div className=\"max-h-[280px] space-y-2 overflow-y-auto pr-1\">\n {roles.systemRoles.length === 0 &&\n roles.customRoles.length === 0 && (\n <p className=\"text-sm text-slate-400\">Nenhuma role.</p>\n )}\n {[...roles.systemRoles, ...roles.customRoles].map((role) => (\n <div\n className=\"overflow-hidden rounded-xl border border-slate-200 p-3\"\n key={role.id}\n >\n <p className=\"truncate text-sm font-semibold text-slate-900\">\n {role.name}\n </p>\n <p className=\"truncate text-xs text-slate-400\">\n {role.key}\n </p>\n <p className=\"mt-1 text-xs text-slate-500\">\n {role.permissions.length} permission\n {role.permissions.length !== 1 ? \"s\" : \"\"}\n </p>\n </div>\n ))}\n </div>\n </div>\n <div className=\"min-w-0\">\n <h3 className=\"mb-3 text-xs font-semibold uppercase tracking-wider text-slate-400\">\n Permissions ({permissions.length})\n </h3>\n <div className=\"max-h-[280px] space-y-2 overflow-y-auto pr-1\">\n {permissions.length === 0 && (\n <p className=\"text-sm text-slate-400\">\n Nenhuma permission.\n </p>\n )}\n {permissions.map((permission) => (\n <div\n className=\"overflow-hidden rounded-xl border border-slate-200 p-3\"\n key={permission.id}\n >\n <p className=\"truncate text-sm font-semibold text-slate-900\">\n {permission.key}\n </p>\n <p className=\"truncate text-xs text-slate-400\">\n {permission.category ?? \"custom\"}\n </p>\n </div>\n ))}\n </div>\n </div>\n </div>\n )}\n </div>\n </div>\n </div>\n );\n }\n\n return {\n SignInButton,\n SignOutButton,\n AccountSwitcher,\n OrgSwitcher,\n UserButton,\n OrganizationButton,\n ProfileModal,\n ManageOrganizationModal,\n CreateOrganizationForm,\n };\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n type ButtonHTMLAttributes,\n type FormEvent,\n type ReactNode,\n useEffect,\n useState,\n} from \"react\";\n\n// ── Local type definitions ────────────────────────────────────────────────────\n\nexport type ElementSize = \"sm\" | \"md\" | \"lg\";\nexport type ElementTone = \"default\" | \"primary\" | \"danger\" | \"ghost\";\n\nexport type ConnectedAccount = {\n id: string;\n sessionId?: string;\n isActive: boolean;\n user: {\n id?: string;\n name: string | null;\n email: string | null;\n imageUrl: string | null;\n phone?: string | null;\n };\n};\n\nexport type Organization = {\n id: string;\n name: string;\n description: string | null;\n slug: string;\n domain: string | null;\n imageUrl: string | null;\n faviconUrl: string | null;\n type?: OrganizationType;\n taxId?: string | null;\n taxIdType?: TaxIdType | null;\n legalName?: string | null;\n members?: Array<{\n id: string;\n user: { name: string | null; email: string | null; imageUrl: string | null };\n roleAssignments?: Array<{\n id: string;\n roleDefinition?: { name: string } | null;\n customRole?: { name: string } | null;\n }>;\n }>;\n};\n\nexport type OrganizationType = \"standard\" | \"legal\";\nexport type TaxIdType = \"br_cnpj\" | \"generic\";\n\ntype OrganizationLegalAddress = Partial<\n Record<\"street\" | \"number\" | \"complement\" | \"district\" | \"city\" | \"state\" | \"postalCode\" | \"country\", string | null>\n>;\n\nexport type OrganizationCreateInput = {\n name: string;\n slug: string;\n type?: OrganizationType;\n taxId?: string | null;\n taxIdType?: TaxIdType | null;\n taxIdCountry?: string | null;\n legalName?: string | null;\n tradeName?: string | null;\n legalEmail?: string | null;\n legalPhone?: string | null;\n legalAddress?: OrganizationLegalAddress | null;\n};\n\nexport type TaxIdLookupResult = {\n taxId: string;\n taxIdType: TaxIdType;\n taxIdCountry: string | null;\n alreadyRegistered: boolean;\n lookupAvailable: boolean;\n found: boolean;\n registrationStatus: string | null;\n suggestedName: string | null;\n data: {\n legalName: string | null;\n tradeName: string | null;\n legalEmail: string | null;\n legalPhone: string | null;\n legalAddress: OrganizationLegalAddress | null;\n };\n missingFields: string[];\n};\n\nconst ADDRESS_KEYS = [\n \"street\",\n \"number\",\n \"complement\",\n \"district\",\n \"city\",\n \"state\",\n \"postalCode\",\n \"country\",\n] as const;\n\nconst REQUIRED_LEGAL = new Set([\n \"taxIdCountry\",\n \"legalName\",\n \"legalAddress.street\",\n \"legalAddress.city\",\n \"legalAddress.postalCode\",\n \"legalAddress.country\",\n]);\n\nconst EMPTY_ORG_FORM: Record<string, string> = {\n type: \"standard\",\n taxIdType: \"br_cnpj\",\n taxId: \"\",\n name: \"\",\n slug: \"\",\n};\n\nfunction slugify(value: string) {\n return value\n .normalize(\"NFD\")\n .replace(/[\\u0300-\\u036f]/g, \"\")\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\")\n .slice(0, 60);\n}\n\nexport type Permission = {\n id: string;\n key: string;\n category: string | null;\n};\n\nexport type Role = {\n id: string;\n key: string;\n name: string;\n permissions: unknown[];\n};\n\nexport type UserSession = {\n id: string;\n deviceName: string | null;\n ip: string | null;\n expiresAt: string | Date;\n};\n\ntype User = {\n id: string;\n name: string | null;\n email: string | null;\n imageUrl: string | null;\n phone?: string | null;\n};\n\n/** Espelha `AuthResult` do auth-nextjs >=0.26 (campos extras são opcionais). */\nexport type AuthResult<T> =\n | { success: true; data: T }\n | {\n success: false;\n error?: string;\n status?: number;\n code?: string;\n retryAfter?: number;\n missingFields?: string[];\n };\n\nexport type JoinWaitlistParams = { clientId: string; email: string; name?: string };\nexport type JoinWaitlistResponse = {\n ok: true;\n status: \"waiting\" | \"approved\" | \"joined\";\n position: number | null;\n};\n\n/** Mensagem em português para um resultado de erro; `fallback` se o código for desconhecido. */\nexport function authErrorMessage(\n result: { error?: string; code?: string; retryAfter?: number },\n fallback: string,\n): string {\n switch (result.code) {\n case \"waitlist_required\":\n return \"Esta aplicação está com lista de espera. Entre na lista para receber acesso.\";\n case \"waitlist_disabled\":\n return \"A lista de espera não está ativa para esta aplicação.\";\n case \"password_reset_required\":\n return \"Sua senha precisa ser redefinida antes de continuar. Use a opção de recuperar senha.\";\n case \"account_locked\": {\n const s = result.retryAfter;\n if (typeof s === \"number\" && s > 0) {\n const wait = s >= 60 ? `${Math.ceil(s / 60)} min` : `${s} s`;\n return `Conta temporariamente bloqueada por tentativas excessivas. Tente novamente em ${wait}.`;\n }\n return \"Conta temporariamente bloqueada. Tente novamente mais tarde.\";\n }\n case \"invalid_credentials\":\n return result.error ?? \"E-mail ou senha incorretos.\";\n default:\n return result.error ?? fallback;\n }\n}\n\n// ── Hook contract (structural — no import from auth-nextjs) ───────────────────\n\ntype UseAuthHook = () => {\n user: User | null;\n signIn: (opts?: { redirectTo?: string }) => Promise<void> | void;\n signOut: () => Promise<void> | void;\n signOutAll: () => Promise<void> | void;\n accounts: ConnectedAccount[];\n addAccount: (opts?: { redirectTo?: string }) => Promise<void> | void;\n isLoadingAccounts: boolean;\n refreshAccounts: () => Promise<void>;\n switchAccount: (id: string, opts?: { redirectTo?: string }) => Promise<void>;\n organizations: Organization[];\n currentOrg: Organization | null;\n currentOrgId?: string | null;\n isLoadingOrganizations: boolean;\n refreshOrganizations: () => Promise<void>;\n setCurrentOrg: (id: string) => Promise<void>;\n createOrganization: (input: OrganizationCreateInput) => Promise<AuthResult<Organization>>;\n /** Opcional: SDKs antigos não têm — sem ele, o formulário só não busca os dados do CNPJ. */\n lookupTaxId?: (value: string, type?: TaxIdType) => Promise<AuthResult<TaxIdLookupResult>>;\n /** Opcional (auth-nextjs >=0.26): sem ele o WaitlistForm mostra um aviso. */\n joinWaitlist?: (params: JoinWaitlistParams) => Promise<AuthResult<JoinWaitlistResponse>>;\n updateOrganization: (\n id: string,\n input: Partial<{\n name: string;\n slug: string;\n description: string | null;\n domain: string | null;\n imageUrl: string | null;\n faviconUrl: string | null;\n }>,\n ) => Promise<AuthResult<Organization>>;\n updateUser: (\n id: string,\n input: { name?: string | null; phone?: string | null; imageUrl?: string | null },\n ) => Promise<AuthResult<User>>;\n listUserSessions: (params: { userId?: string; organizationId?: string }) => Promise<UserSession[]>;\n revokeUserSession: (sessionId: string) => Promise<AuthResult<null>>;\n listPermissions: (params: {\n applicationId?: string;\n roleId?: string | null;\n }) => Promise<Permission[]>;\n listRoles: (params?: {\n organizationId?: string;\n applicationId?: string;\n type?: \"system\" | \"custom\" | \"all\";\n }) => Promise<{ systemRoles: Role[]; customRoles: Role[] }>;\n};\n\n// ── Primitive UI helpers ──────────────────────────────────────────────────────\n\ntype ButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & {\n tone?: ElementTone;\n size?: ElementSize;\n};\n\nfunction cx(...classes: Array<string | false | null | undefined>) {\n return classes.filter(Boolean).join(\" \");\n}\n\nfunction initials(value?: string | null) {\n const normalized = value?.trim();\n if (!normalized) return \"?\";\n const parts = normalized.split(/\\s+/).slice(0, 2);\n return parts.map((part) => part[0]?.toUpperCase()).join(\"\") || \"?\";\n}\n\nfunction formatDate(value?: string | Date | null) {\n if (!value) return \"-\";\n return new Intl.DateTimeFormat(undefined, {\n dateStyle: \"medium\",\n timeStyle: \"short\",\n }).format(new Date(value));\n}\n\nfunction isExpired(value: string | Date) {\n return new Date(value).getTime() <= Date.now();\n}\n\nfunction Button({\n className,\n tone = \"default\",\n size = \"md\",\n ...props\n}: ButtonProps) {\n return (\n <button\n {...props}\n className={cx(\n \"inline-flex items-center justify-center gap-2 rounded-lg font-medium transition disabled:cursor-not-allowed disabled:opacity-50\",\n size === \"sm\" && \"h-8 px-3 text-xs\",\n size === \"md\" && \"h-10 px-4 text-sm\",\n size === \"lg\" && \"h-11 px-5 text-sm\",\n tone === \"default\" &&\n \"border border-slate-200 bg-white text-slate-800 hover:bg-slate-50\",\n tone === \"primary\" && \"bg-slate-950 text-white hover:bg-slate-800\",\n tone === \"danger\" && \"bg-red-600 text-white hover:bg-red-700\",\n tone === \"ghost\" &&\n \"bg-transparent text-slate-600 hover:bg-slate-100 hover:text-slate-950\",\n className,\n )}\n />\n );\n}\n\nfunction Input(props: React.InputHTMLAttributes<HTMLInputElement>) {\n return (\n <input\n {...props}\n className={cx(\n \"h-10 w-full rounded-lg border border-slate-200 bg-white px-3 text-sm text-slate-900 outline-none placeholder:text-slate-400 focus:border-slate-400\",\n props.className,\n )}\n />\n );\n}\n\nfunction Textarea(props: React.TextareaHTMLAttributes<HTMLTextAreaElement>) {\n return (\n <textarea\n {...props}\n className={cx(\n \"min-h-[86px] w-full resize-none rounded-lg border border-slate-200 bg-white px-3 py-2 text-sm text-slate-900 outline-none placeholder:text-slate-400 focus:border-slate-400\",\n props.className,\n )}\n />\n );\n}\n\nfunction Field({ label, children }: { label: string; children: ReactNode }) {\n return (\n <label className=\"grid gap-1.5\">\n <span className=\"text-xs font-medium text-slate-600\">{label}</span>\n {children}\n </label>\n );\n}\n\n// ── Standalone components (no hooks) ─────────────────────────────────────────\n\nexport function Avatar({\n src,\n name,\n size = \"md\",\n className,\n}: {\n src?: string | null;\n name?: string | null;\n size?: ElementSize;\n className?: string;\n}) {\n return (\n <span\n className={cx(\n \"inline-flex shrink-0 items-center justify-center overflow-hidden rounded-full bg-slate-100 font-semibold text-slate-700\",\n size === \"sm\" && \"h-8 w-8 text-xs\",\n size === \"md\" && \"h-10 w-10 text-sm\",\n size === \"lg\" && \"h-12 w-12 text-base\",\n className,\n )}\n >\n {src ? (\n <img\n alt={name ?? \"Avatar\"}\n className=\"h-full w-full object-cover\"\n src={src}\n />\n ) : (\n initials(name)\n )}\n </span>\n );\n}\n\nexport function Modal({\n open,\n onOpenChange,\n title,\n description,\n children,\n footer,\n}: {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n title: string;\n description?: string;\n children: ReactNode;\n footer?: ReactNode;\n}) {\n if (!open) return null;\n\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4\">\n <div className=\"max-h-[90vh] w-full max-w-3xl overflow-hidden rounded-2xl bg-white shadow-xl\">\n <div className=\"flex items-start justify-between gap-4 border-b border-slate-200 p-5\">\n <div>\n <h2 className=\"text-lg font-semibold text-slate-950\">{title}</h2>\n {description && (\n <p className=\"mt-1 text-sm text-slate-500\">{description}</p>\n )}\n </div>\n <Button\n aria-label=\"Close\"\n onClick={() => onOpenChange(false)}\n size=\"sm\"\n tone=\"ghost\"\n type=\"button\"\n >\n ✕\n </Button>\n </div>\n <div className=\"max-h-[68vh] overflow-y-auto p-5\">{children}</div>\n {footer && (\n <div className=\"border-t border-slate-200 p-5\">{footer}</div>\n )}\n </div>\n </div>\n );\n}\n\n// ── Factory ───────────────────────────────────────────────────────────────────\n\n/**\n * Creates auth UI components bound to the provided `useAuth` hook instance.\n * This lets consumers supply their own auth-nextjs instance without requiring\n * a separate installed copy inside auth-elements-nextjs.\n *\n * @example\n * import { createAuthElements } from '@geekapps/auth-elements-nextjs'\n * import { useAuth } from '@geekapps/auth-nextjs/client'\n * export const { SignInButton, ProfileModal } = createAuthElements({ useAuth })\n */\nexport function createAuthElements(hooks: { useAuth: UseAuthHook }) {\n const { useAuth } = hooks;\n\n function SignInButton({\n children = \"Entrar\",\n redirectTo,\n }: {\n children?: ReactNode;\n redirectTo?: string;\n }) {\n const { signIn } = useAuth();\n return (\n <Button\n onClick={() => void signIn({ redirectTo })}\n tone=\"primary\"\n type=\"button\"\n >\n {children}\n </Button>\n );\n }\n\n function SignOutButton({ children = \"Sair\" }: { children?: ReactNode }) {\n const { signOut } = useAuth();\n return (\n <Button onClick={() => void signOut()} tone=\"ghost\" type=\"button\">\n {children}\n </Button>\n );\n }\n\n function AccountSwitcher() {\n const {\n accounts,\n addAccount,\n isLoadingAccounts,\n refreshAccounts,\n switchAccount,\n } = useAuth();\n const activeAccount =\n accounts.find((account) => account.isActive) ?? accounts[0] ?? null;\n const [open, setOpen] = useState(false);\n\n return (\n <div className=\"relative\">\n <button\n className=\"flex h-10 w-10 items-center justify-center rounded-xl transition hover:opacity-80\"\n onClick={() => setOpen((value) => !value)}\n title={activeAccount?.user.name ?? activeAccount?.user.email ?? \"Conta\"}\n type=\"button\"\n >\n <Avatar\n name={activeAccount?.user.name ?? activeAccount?.user.email}\n size=\"sm\"\n src={activeAccount?.user.imageUrl}\n />\n </button>\n\n {open && (\n <>\n <div className=\"fixed inset-0 z-20\" onClick={() => setOpen(false)} />\n <div className=\"absolute bottom-0 left-14 z-30 w-72 overflow-hidden rounded-xl border border-slate-200 bg-white shadow-lg\">\n <div className=\"border-b border-slate-100 px-3 py-2.5\">\n <p className=\"text-[11px] font-medium uppercase tracking-wider text-slate-400\">\n Contas\n </p>\n </div>\n <div className=\"p-1.5\">\n {isLoadingAccounts && (\n <p className=\"px-2 py-3 text-xs text-slate-400\">\n Carregando...\n </p>\n )}\n {accounts.map((account) => (\n <button\n className={cx(\n \"flex w-full items-center gap-2.5 rounded-lg px-2 py-2 text-left transition hover:bg-slate-50\",\n account.isActive && \"bg-slate-50\",\n )}\n key={account.sessionId ?? account.id}\n onClick={() => {\n void switchAccount(account.sessionId ?? account.id);\n setOpen(false);\n }}\n type=\"button\"\n >\n <Avatar\n name={account.user.name ?? account.user.email}\n size=\"sm\"\n src={account.user.imageUrl}\n />\n <span className=\"min-w-0 flex-1\">\n <span className=\"block truncate text-sm font-medium text-slate-900\">\n {account.user.name ?? account.user.email}\n </span>\n <span className=\"block truncate text-xs text-slate-500\">\n {account.user.email}\n </span>\n </span>\n {account.isActive && (\n <span className=\"shrink-0 text-xs font-medium text-emerald-600\">\n ✓\n </span>\n )}\n </button>\n ))}\n </div>\n <div className=\"flex gap-1.5 border-t border-slate-100 p-1.5\">\n <Button\n className=\"flex-1\"\n onClick={() => void addAccount()}\n size=\"sm\"\n type=\"button\"\n >\n + Conta\n </Button>\n <Button\n className=\"flex-1\"\n onClick={() => void refreshAccounts()}\n size=\"sm\"\n tone=\"ghost\"\n type=\"button\"\n >\n Atualizar\n </Button>\n </div>\n </div>\n </>\n )}\n </div>\n );\n }\n\n // Formulário de criação compartilhado: organização padrão (sem documento)\n // ou legal (associada a CNPJ / Tax ID, com os dados da empresa buscados\n // automaticamente e os obrigatórios que faltarem pedidos ao usuário).\n function CreateOrganizationForm({\n onCreated,\n onCancel,\n compact = false,\n }: {\n onCreated?: (organization: Organization) => void;\n onCancel?: () => void;\n compact?: boolean;\n }) {\n const { createOrganization, lookupTaxId, setCurrentOrg } = useAuth();\n const [values, setValues] = useState<Record<string, string>>({ ...EMPTY_ORG_FORM });\n const [missing, setMissing] = useState<string[]>([]);\n const [lookupInfo, setLookupInfo] = useState<string | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [busy, setBusy] = useState<\"lookup\" | \"create\" | null>(null);\n const isLegal = values.type === \"legal\";\n const isCnpj = values.taxIdType === \"br_cnpj\";\n\n const set = (key: string, value: string) =>\n setValues((current) => {\n const next = { ...current, [key]: value };\n if (key === \"name\" && !current.slugTouched) next.slug = slugify(value);\n if (key === \"slug\") next.slugTouched = \"1\";\n return next;\n });\n\n async function runLookup() {\n if (!lookupTaxId || !values.taxId) return;\n setBusy(\"lookup\");\n setError(null);\n setLookupInfo(null);\n const result = await lookupTaxId(values.taxId, values.taxIdType as TaxIdType);\n setBusy(null);\n if (!result.success) {\n setError(authErrorMessage(result, \"Tax ID inválido.\"));\n return;\n }\n const { data } = result.data;\n setValues((current) => {\n const next: Record<string, string> = { ...current, taxId: result.data.taxId };\n const fill = (key: string, value: string | null | undefined) => {\n if (value && !current[key]) next[key] = value;\n };\n fill(\"legalName\", data.legalName);\n fill(\"tradeName\", data.tradeName);\n fill(\"legalEmail\", data.legalEmail);\n fill(\"legalPhone\", data.legalPhone);\n for (const key of ADDRESS_KEYS) fill(`legalAddress.${key}`, data.legalAddress?.[key]);\n if (result.data.taxIdCountry) next.taxIdCountry = result.data.taxIdCountry;\n if (!current.name && result.data.suggestedName) {\n next.name = result.data.suggestedName;\n if (!current.slugTouched) next.slug = slugify(result.data.suggestedName);\n }\n return next;\n });\n setMissing(result.data.missingFields);\n if (result.data.alreadyRegistered) {\n setError(\"Já existe uma organização com este documento neste app.\");\n } else if (result.data.found) {\n setLookupInfo(\n `Dados encontrados${result.data.registrationStatus ? ` · situação ${result.data.registrationStatus}` : \"\"}. Revise e complete o que faltar.`,\n );\n } else {\n setLookupInfo(\n result.data.lookupAvailable\n ? \"Documento válido, mas sem dados públicos. Preencha os campos obrigatórios.\"\n : \"Consulta indisponível no momento. Preencha os campos obrigatórios.\",\n );\n }\n }\n\n async function onSubmit(event: FormEvent<HTMLFormElement>) {\n event.preventDefault();\n setBusy(\"create\");\n setError(null);\n const blank = (key: string) => values[key]?.trim() || null;\n const input: OrganizationCreateInput = {\n name: values.name.trim(),\n slug: values.slug.trim(),\n type: isLegal ? \"legal\" : \"standard\",\n };\n if (isLegal) {\n Object.assign(input, {\n taxId: blank(\"taxId\"),\n taxIdType: values.taxIdType,\n taxIdCountry: isCnpj ? \"BR\" : blank(\"taxIdCountry\"),\n legalName: blank(\"legalName\"),\n tradeName: blank(\"tradeName\"),\n legalEmail: blank(\"legalEmail\"),\n legalPhone: blank(\"legalPhone\"),\n legalAddress: Object.fromEntries(\n ADDRESS_KEYS.map((key) => [key, blank(`legalAddress.${key}`)]),\n ),\n });\n if (!isCnpj && !input.legalAddress?.country) {\n (input.legalAddress as Record<string, string | null>).country = blank(\"taxIdCountry\");\n }\n }\n const result = await createOrganization(input);\n setBusy(null);\n if (!result.success) {\n if (result.missingFields?.length) setMissing(result.missingFields);\n setError(authErrorMessage(result, \"Erro ao criar organização.\"));\n return;\n }\n setValues({ ...EMPTY_ORG_FORM });\n setMissing([]);\n setLookupInfo(null);\n if (result.data?.id) void setCurrentOrg(result.data.id);\n onCreated?.(result.data);\n }\n\n const field = (key: string, label: string, props: React.InputHTMLAttributes<HTMLInputElement> = {}) => {\n const required = REQUIRED_LEGAL.has(key);\n return (\n <Field label={`${label}${required ? \" *\" : \"\"}`}>\n <Input\n {...props}\n className={missing.includes(key) && !values[key] ? \"border-red-300\" : undefined}\n name={key}\n onChange={(event) => set(key, event.target.value)}\n required={required}\n value={values[key] ?? \"\"}\n />\n </Field>\n );\n };\n\n return (\n <form className={cx(\"grid\", compact ? \"gap-2\" : \"gap-4\")} onSubmit={onSubmit}>\n <div className=\"grid grid-cols-2 gap-1 rounded-lg bg-slate-100 p-1\">\n {(\n [\n [\"standard\", \"Padrão\"],\n [\"legal\", \"Empresa (CNPJ / Tax ID)\"],\n ] as const\n ).map(([type, label]) => (\n <button\n className={cx(\n \"rounded-md px-2 py-1.5 text-xs font-medium transition\",\n values.type === type ? \"bg-white text-slate-900 shadow-sm\" : \"text-slate-500\",\n )}\n key={type}\n onClick={() => set(\"type\", type)}\n type=\"button\"\n >\n {label}\n </button>\n ))}\n </div>\n\n {isLegal && (\n <>\n <div className=\"grid grid-cols-[auto_1fr] gap-2\">\n <select\n className=\"h-10 rounded-lg border border-slate-200 bg-white px-2 text-sm text-slate-900\"\n onChange={(event) => set(\"taxIdType\", event.target.value)}\n value={values.taxIdType}\n >\n <option value=\"br_cnpj\">CNPJ</option>\n <option value=\"generic\">Outro Tax ID</option>\n </select>\n <div className=\"flex gap-2\">\n <Input\n name=\"taxId\"\n onBlur={() => isCnpj && void runLookup()}\n onChange={(event) => set(\"taxId\", event.target.value)}\n placeholder={isCnpj ? \"00.000.000/0000-00\" : \"Tax ID\"}\n required\n value={values.taxId}\n />\n <Button disabled={busy !== null || !values.taxId} onClick={() => void runLookup()} size=\"sm\" type=\"button\">\n {busy === \"lookup\" ? \"Buscando…\" : isCnpj ? \"Buscar\" : \"Validar\"}\n </Button>\n </div>\n </div>\n {!isCnpj && field(\"taxIdCountry\", \"País do Tax ID (ISO, ex.: US)\", { maxLength: 2 })}\n {lookupInfo && (\n <p className=\"rounded-lg bg-slate-50 px-3 py-2 text-xs text-slate-600\">{lookupInfo}</p>\n )}\n </>\n )}\n\n {field(\"name\", \"Nome\", { placeholder: \"Minha organização\", required: true })}\n {field(\"slug\", \"Slug\", { placeholder: \"minha-org\", required: true })}\n\n {isLegal && (\n <>\n {field(\"legalName\", \"Razão social\")}\n {field(\"tradeName\", \"Nome fantasia\")}\n <div className=\"grid gap-2 sm:grid-cols-2\">\n {field(\"legalEmail\", \"E-mail\", { type: \"email\" })}\n {field(\"legalPhone\", \"Telefone\")}\n </div>\n {field(\"legalAddress.street\", \"Logradouro\")}\n <div className=\"grid gap-2 sm:grid-cols-2\">\n {field(\"legalAddress.number\", \"Número\")}\n {field(\"legalAddress.complement\", \"Complemento\")}\n {field(\"legalAddress.district\", \"Bairro\")}\n {field(\"legalAddress.city\", \"Cidade\")}\n {field(\"legalAddress.state\", \"Estado\")}\n {field(\"legalAddress.postalCode\", \"CEP / Código postal\")}\n </div>\n {!isCnpj && field(\"legalAddress.country\", \"País do endereço (ISO)\", { maxLength: 2 })}\n </>\n )}\n\n {error && <p className=\"rounded-lg bg-red-50 px-3 py-2 text-xs text-red-600\">{error}</p>}\n\n <div className=\"flex justify-end gap-2\">\n {onCancel && (\n <Button onClick={onCancel} size=\"sm\" tone=\"ghost\" type=\"button\">\n Cancelar\n </Button>\n )}\n <Button disabled={busy !== null} size=\"sm\" tone=\"primary\" type=\"submit\">\n {busy === \"create\" ? \"Criando…\" : \"Criar organização\"}\n </Button>\n </div>\n </form>\n );\n }\n\n function OrgSwitcher() {\n const {\n currentOrg,\n isLoadingOrganizations,\n organizations,\n refreshOrganizations,\n setCurrentOrg,\n } = useAuth();\n const [open, setOpen] = useState(false);\n const [creating, setCreating] = useState(false);\n\n return (\n <div className=\"relative\">\n <button\n className=\"flex w-full items-center gap-3 rounded-xl border border-slate-200 bg-white p-2 text-left hover:bg-slate-50\"\n onClick={() => setOpen((value) => !value)}\n type=\"button\"\n >\n <Avatar name={currentOrg?.name} src={currentOrg?.imageUrl} />\n <span className=\"min-w-0 flex-1\">\n <span className=\"block truncate text-sm font-medium text-slate-950\">\n {currentOrg?.name ?? \"Selecionar organização\"}\n </span>\n <span className=\"block truncate text-xs text-slate-500\">\n {isLoadingOrganizations\n ? \"Carregando...\"\n : `${organizations.length} organizações`}\n </span>\n </span>\n <span className=\"text-slate-400\">⌄</span>\n </button>\n\n {open && (\n <div className=\"absolute right-0 z-30 mt-2 w-80 overflow-hidden rounded-xl border border-slate-200 bg-white shadow-lg\">\n <div className=\"max-h-72 overflow-y-auto p-2\">\n {organizations.map((organization) => (\n <button\n className=\"flex w-full items-center gap-3 rounded-lg p-2 text-left hover:bg-slate-50\"\n key={organization.id}\n onClick={() => {\n void setCurrentOrg(organization.id);\n setOpen(false);\n }}\n type=\"button\"\n >\n <Avatar\n name={organization.name}\n size=\"sm\"\n src={organization.imageUrl}\n />\n <span className=\"min-w-0 flex-1\">\n <span className=\"block truncate text-sm font-medium text-slate-900\">\n {organization.name}\n </span>\n <span className=\"block truncate text-xs text-slate-500\">\n {organization.slug}\n </span>\n </span>\n {organization.id === currentOrg?.id && (\n <span className=\"text-xs font-medium text-emerald-600\">\n Atual\n </span>\n )}\n </button>\n ))}\n </div>\n\n {creating ? (\n <div className=\"max-h-[70vh] overflow-y-auto border-t border-slate-200 p-3\">\n <CreateOrganizationForm\n compact\n onCancel={() => setCreating(false)}\n onCreated={() => {\n setCreating(false);\n setOpen(false);\n void refreshOrganizations();\n }}\n />\n </div>\n ) : (\n <div className=\"flex gap-2 border-t border-slate-200 p-2\">\n <Button\n className=\"flex-1\"\n onClick={() => setCreating(true)}\n size=\"sm\"\n type=\"button\"\n >\n Nova org\n </Button>\n <Button\n className=\"flex-1\"\n onClick={() => void refreshOrganizations()}\n size=\"sm\"\n tone=\"ghost\"\n type=\"button\"\n >\n Atualizar\n </Button>\n </div>\n )}\n </div>\n )}\n </div>\n );\n }\n\n function UserButton() {\n const { user } = useAuth();\n const [open, setOpen] = useState(false);\n return (\n <>\n <button onClick={() => setOpen(true)} type=\"button\">\n <Avatar name={user?.name ?? user?.email} src={user?.imageUrl} />\n </button>\n <ProfileModal open={open} onOpenChange={setOpen} />\n </>\n );\n }\n\n function OrganizationButton() {\n const { currentOrg } = useAuth();\n const [open, setOpen] = useState(false);\n return (\n <>\n <button\n className=\"flex h-10 w-10 items-center justify-center rounded-xl bg-white border border-slate-200 text-xs font-semibold text-slate-700 transition hover:bg-slate-50 hover:border-slate-300\"\n onClick={() => setOpen(true)}\n title={currentOrg?.name ?? \"Organização\"}\n type=\"button\"\n >\n {currentOrg?.imageUrl ? (\n <img\n alt={currentOrg.name}\n className=\"h-full w-full rounded-xl object-cover\"\n src={currentOrg.imageUrl}\n />\n ) : (\n (currentOrg?.name ?? \"O\")[0]?.toUpperCase()\n )}\n </button>\n <ManageOrganizationModal open={open} onOpenChange={setOpen} />\n </>\n );\n }\n\n function ProfileModal({\n open,\n onOpenChange,\n }: {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n }) {\n const {\n signOut,\n signOutAll,\n user,\n organizations,\n currentOrg,\n setCurrentOrg,\n updateUser,\n listUserSessions,\n revokeUserSession,\n } = useAuth();\n const [tab, setTab] = useState(\"profile\");\n const [sessions, setSessions] = useState<UserSession[]>([]);\n const [saving, setSaving] = useState(false);\n const [saveError, setSaveError] = useState<string | null>(null);\n const [saveSuccess, setSaveSuccess] = useState(false);\n\n useEffect(() => {\n if (!open) {\n setTab(\"profile\");\n setSaveError(null);\n setSaveSuccess(false);\n }\n }, [open]);\n\n useEffect(() => {\n if (open && user && tab === \"sessions\") {\n void listUserSessions({ userId: user.id })\n .then(setSessions)\n .catch(() => setSessions([]));\n }\n }, [listUserSessions, open, tab, user]);\n\n async function onProfileSubmit(event: FormEvent<HTMLFormElement>) {\n event.preventDefault();\n if (!user) return;\n const form = new FormData(event.currentTarget);\n setSaving(true);\n setSaveError(null);\n setSaveSuccess(false);\n try {\n await updateUser(user.id, {\n name: String(form.get(\"name\") ?? \"\") || null,\n phone: String(form.get(\"phone\") ?? \"\") || null,\n imageUrl: String(form.get(\"imageUrl\") ?? \"\") || null,\n });\n setSaveSuccess(true);\n setTimeout(() => setSaveSuccess(false), 2500);\n } catch (err) {\n setSaveError(err instanceof Error ? err.message : \"Erro ao salvar.\");\n } finally {\n setSaving(false);\n }\n }\n\n if (!open) return null;\n\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4\">\n <div className=\"flex max-h-[90vh] w-full max-w-lg flex-col overflow-hidden rounded-2xl bg-white shadow-2xl\">\n {/* Header */}\n <div className=\"flex shrink-0 items-center justify-between border-b border-slate-100 px-6 py-4\">\n <div className=\"flex items-center gap-3\">\n <Avatar\n name={user?.name ?? user?.email}\n size=\"sm\"\n src={user?.imageUrl}\n />\n <div>\n <p className=\"text-sm font-semibold text-slate-900\">\n {user?.name ?? user?.email ?? \"Minha conta\"}\n </p>\n <p className=\"text-xs text-slate-500\">{user?.email}</p>\n </div>\n </div>\n <button\n aria-label=\"Fechar\"\n className=\"rounded-lg p-1.5 text-slate-400 transition hover:bg-slate-100 hover:text-slate-700\"\n onClick={() => onOpenChange(false)}\n type=\"button\"\n >\n ✕\n </button>\n </div>\n\n {/* Tabs */}\n <div className=\"shrink-0 flex gap-1 border-b border-slate-100 px-6 pt-3\">\n {(\n [\n { id: \"profile\", label: \"Perfil\" },\n { id: \"sessions\", label: \"Sessões\" },\n { id: \"orgs\", label: \"Organizações\" },\n ] as const\n ).map((t) => (\n <button\n className={cx(\n \"mb-[-1px] border-b-2 px-3 pb-2.5 text-xs font-medium transition\",\n tab === t.id\n ? \"border-slate-900 text-slate-900\"\n : \"border-transparent text-slate-500 hover:text-slate-700\",\n )}\n key={t.id}\n onClick={() => setTab(t.id)}\n type=\"button\"\n >\n {t.label}\n </button>\n ))}\n </div>\n\n {/* Body */}\n <div className=\"flex-1 overflow-y-auto px-6 py-5\">\n {tab === \"profile\" && user && (\n <form className=\"grid gap-4\" onSubmit={onProfileSubmit}>\n <div className=\"flex items-center gap-4 rounded-xl bg-slate-50 p-4\">\n <Avatar\n name={user.name ?? user.email}\n size=\"lg\"\n src={user.imageUrl}\n />\n <div>\n <p className=\"text-sm font-semibold text-slate-900\">\n {user.name ?? \"Sem nome\"}\n </p>\n <p className=\"text-xs text-slate-500\">{user.email}</p>\n </div>\n </div>\n\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <Field label=\"Nome\">\n <Input\n defaultValue={user.name ?? \"\"}\n name=\"name\"\n placeholder=\"Seu nome\"\n />\n </Field>\n <Field label=\"Telefone\">\n <Input\n defaultValue={user.phone ?? \"\"}\n name=\"phone\"\n placeholder=\"+55 11 99999-9999\"\n />\n </Field>\n </div>\n <Field label=\"URL da imagem\">\n <Input\n defaultValue={user.imageUrl ?? \"\"}\n name=\"imageUrl\"\n placeholder=\"https://...\"\n />\n </Field>\n\n {saveError && (\n <p className=\"rounded-lg bg-red-50 px-3 py-2 text-xs text-red-600\">\n {saveError}\n </p>\n )}\n {saveSuccess && (\n <p className=\"rounded-lg bg-emerald-50 px-3 py-2 text-xs text-emerald-600\">\n Perfil salvo com sucesso.\n </p>\n )}\n\n <div className=\"flex items-center justify-between border-t border-slate-100 pt-2\">\n <div className=\"flex gap-2\">\n <Button\n onClick={() => void signOut()}\n size=\"sm\"\n tone=\"ghost\"\n type=\"button\"\n >\n Sair\n </Button>\n <Button\n onClick={() => void signOutAll()}\n size=\"sm\"\n tone=\"danger\"\n type=\"button\"\n >\n Sair de todas\n </Button>\n </div>\n <Button\n disabled={saving}\n size=\"sm\"\n tone=\"primary\"\n type=\"submit\"\n >\n {saving ? \"Salvando…\" : \"Salvar\"}\n </Button>\n </div>\n </form>\n )}\n\n {tab === \"sessions\" && (\n <div className=\"grid gap-2\">\n {sessions.length === 0 && (\n <p className=\"py-6 text-center text-sm text-slate-400\">\n Nenhuma sessão ativa.\n </p>\n )}\n {sessions.map((session) => {\n const expired = isExpired(session.expiresAt);\n return (\n <div\n className=\"flex items-center justify-between gap-4 rounded-xl border border-slate-200 p-4\"\n key={session.id}\n >\n <div className=\"min-w-0\">\n <p className=\"truncate text-sm font-medium text-slate-900\">\n {session.deviceName ?? \"Dispositivo\"}\n </p>\n <p className=\"mt-0.5 truncate text-xs text-slate-500\">\n {session.ip ?? \"IP desconhecido\"} ·{\" \"}\n <span className={expired ? \"text-amber-600\" : \"\"}>\n {expired\n ? \"Expirada\"\n : `Expira ${formatDate(session.expiresAt)}`}\n </span>\n </p>\n </div>\n <Button\n onClick={async () => {\n await revokeUserSession(session.id);\n setSessions((s) =>\n s.filter((x) => x.id !== session.id),\n );\n }}\n size=\"sm\"\n tone=\"danger\"\n type=\"button\"\n >\n Revogar\n </Button>\n </div>\n );\n })}\n </div>\n )}\n\n {tab === \"orgs\" && (\n <div className=\"grid gap-2\">\n {organizations.length === 0 && (\n <p className=\"py-6 text-center text-sm text-slate-400\">\n Nenhuma organização.\n </p>\n )}\n {organizations.map((org) => (\n <button\n className={cx(\n \"flex w-full items-center gap-3 rounded-xl border p-3 text-left transition\",\n org.id === currentOrg?.id\n ? \"border-slate-900 bg-slate-50\"\n : \"border-slate-200 hover:border-slate-300 hover:bg-slate-50\",\n )}\n key={org.id}\n onClick={() => void setCurrentOrg(org.id)}\n type=\"button\"\n >\n <Avatar name={org.name} size=\"sm\" src={org.imageUrl} />\n <div className=\"min-w-0 flex-1\">\n <p className=\"truncate text-sm font-medium text-slate-900\">\n {org.name}\n </p>\n <p className=\"truncate text-xs text-slate-500\">\n /{org.slug}\n </p>\n </div>\n {org.id === currentOrg?.id && (\n <span className=\"shrink-0 rounded-full bg-slate-900 px-2 py-0.5 text-[10px] font-medium text-white\">\n Ativa\n </span>\n )}\n </button>\n ))}\n </div>\n )}\n </div>\n </div>\n </div>\n );\n }\n\n function ManageOrganizationModal({\n open,\n onOpenChange,\n }: {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n }) {\n const {\n createOrganization,\n currentOrg,\n organizations,\n refreshOrganizations,\n setCurrentOrg,\n updateOrganization,\n listPermissions,\n listRoles,\n } = useAuth();\n const [tab, setTab] = useState(\"orgs\");\n const [roles, setRoles] = useState<{\n systemRoles: Role[];\n customRoles: Role[];\n }>({ systemRoles: [], customRoles: [] });\n const [permissions, setPermissions] = useState<Permission[]>([]);\n const [saving, setSaving] = useState(false);\n const [saveSuccess, setSaveSuccess] = useState(false);\n const [saveError, setSaveError] = useState<string | null>(null);\n\n useEffect(() => {\n if (!open) {\n setTab(\"orgs\");\n setSaveError(null);\n setSaveSuccess(false);\n }\n }, [open]);\n\n useEffect(() => {\n if (!open || !currentOrg) return;\n if (tab === \"members\" || tab === \"roles\") {\n void listRoles({ organizationId: currentOrg.id })\n .then(setRoles)\n .catch(() => setRoles({ systemRoles: [], customRoles: [] }));\n void listPermissions({})\n .then(setPermissions)\n .catch(() => setPermissions([]));\n }\n }, [currentOrg, listPermissions, listRoles, open, tab]);\n\n async function onOrgSubmit(event: FormEvent<HTMLFormElement>) {\n event.preventDefault();\n if (!currentOrg) return;\n const form = new FormData(event.currentTarget);\n setSaving(true);\n setSaveError(null);\n setSaveSuccess(false);\n try {\n await updateOrganization(currentOrg.id, {\n name: String(form.get(\"name\") ?? \"\"),\n description: String(form.get(\"description\") ?? \"\") || null,\n slug: String(form.get(\"slug\") ?? \"\"),\n domain: String(form.get(\"domain\") ?? \"\") || null,\n imageUrl: String(form.get(\"imageUrl\") ?? \"\") || null,\n faviconUrl: String(form.get(\"faviconUrl\") ?? \"\") || null,\n });\n setSaveSuccess(true);\n setTimeout(() => setSaveSuccess(false), 2500);\n } catch (err) {\n setSaveError(err instanceof Error ? err.message : \"Erro ao salvar.\");\n } finally {\n setSaving(false);\n }\n }\n\n if (!open) return null;\n\n const orgTabs = [\n { id: \"orgs\", label: \"Organizações\" },\n { id: \"info\", label: \"Geral\" },\n { id: \"members\", label: \"Membros\" },\n { id: \"roles\", label: \"Roles\" },\n { id: \"new\", label: \"+ Nova org\" },\n ] as const;\n\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4\">\n <div className=\"flex max-h-[90vh] w-full max-w-2xl flex-col overflow-hidden rounded-2xl bg-white shadow-2xl\">\n {/* Header */}\n <div className=\"flex shrink-0 items-center justify-between border-b border-slate-100 px-6 py-4\">\n <div className=\"flex items-center gap-3\">\n {currentOrg?.imageUrl ? (\n <img\n alt={currentOrg.name}\n className=\"h-8 w-8 rounded-lg object-cover\"\n src={currentOrg.imageUrl}\n />\n ) : (\n <span className=\"flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-slate-100 text-xs font-semibold text-slate-600\">\n {(currentOrg?.name ?? \"O\")[0]?.toUpperCase()}\n </span>\n )}\n <div>\n <p className=\"text-sm font-semibold text-slate-900\">\n {currentOrg?.name ?? \"Organização\"}\n </p>\n {currentOrg?.slug && (\n <p className=\"text-xs text-slate-500\">/{currentOrg.slug}</p>\n )}\n </div>\n </div>\n <button\n aria-label=\"Fechar\"\n className=\"rounded-lg p-1.5 text-slate-400 transition hover:bg-slate-100 hover:text-slate-700\"\n onClick={() => onOpenChange(false)}\n type=\"button\"\n >\n ✕\n </button>\n </div>\n\n {/* Tabs */}\n <div className=\"flex shrink-0 gap-1 border-b border-slate-100 px-6 pt-3\">\n {orgTabs.map((t) => (\n <button\n className={cx(\n \"mb-[-1px] border-b-2 px-3 pb-2.5 text-xs font-medium transition\",\n tab === t.id\n ? \"border-slate-900 text-slate-900\"\n : \"border-transparent text-slate-500 hover:text-slate-700\",\n )}\n key={t.id}\n onClick={() => setTab(t.id)}\n type=\"button\"\n >\n {t.label}\n </button>\n ))}\n </div>\n\n {/* Body */}\n <div className=\"flex-1 overflow-y-auto px-6 py-5\">\n {!currentOrg && (\n <p className=\"py-8 text-center text-sm text-slate-400\">\n Nenhuma organização selecionada.\n </p>\n )}\n\n {tab === \"orgs\" && (\n <div className=\"grid gap-2\">\n {organizations.length === 0 && (\n <p className=\"py-8 text-center text-sm text-slate-400\">\n Nenhuma organização disponível.\n </p>\n )}\n {organizations.map((org) => (\n <button\n className={cx(\n \"flex w-full items-center gap-3 rounded-xl border p-3 text-left transition\",\n org.id === currentOrg?.id\n ? \"border-slate-900 bg-slate-50\"\n : \"border-slate-200 hover:border-slate-300 hover:bg-slate-50\",\n )}\n key={org.id}\n onClick={() => {\n void setCurrentOrg(org.id);\n onOpenChange(false);\n }}\n type=\"button\"\n >\n <Avatar name={org.name} size=\"sm\" src={org.imageUrl} />\n <div className=\"min-w-0 flex-1\">\n <p className=\"truncate text-sm font-medium text-slate-900\">\n {org.name}\n </p>\n <p className=\"truncate text-xs text-slate-500\">\n /{org.slug}\n </p>\n </div>\n {org.id === currentOrg?.id && (\n <span className=\"shrink-0 rounded-full bg-slate-900 px-2 py-0.5 text-[10px] font-medium text-white\">\n Ativa\n </span>\n )}\n </button>\n ))}\n </div>\n )}\n\n {tab === \"info\" && currentOrg && (\n <form className=\"grid gap-4\" onSubmit={onOrgSubmit}>\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <Field label=\"Nome *\">\n <Input defaultValue={currentOrg.name} name=\"name\" required />\n </Field>\n <Field label=\"Slug *\">\n <Input defaultValue={currentOrg.slug} name=\"slug\" required />\n </Field>\n </div>\n <Field label=\"Descrição\">\n <Textarea\n defaultValue={currentOrg.description ?? \"\"}\n name=\"description\"\n placeholder=\"Descreva a organização…\"\n />\n </Field>\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <Field label=\"Domínio\">\n <Input\n defaultValue={currentOrg.domain ?? \"\"}\n name=\"domain\"\n placeholder=\"acme.com\"\n />\n </Field>\n <Field label=\"URL da imagem\">\n <Input\n defaultValue={currentOrg.imageUrl ?? \"\"}\n name=\"imageUrl\"\n placeholder=\"https://...\"\n />\n </Field>\n </div>\n <Field label=\"URL do favicon\">\n <Input\n defaultValue={currentOrg.faviconUrl ?? \"\"}\n name=\"faviconUrl\"\n placeholder=\"https://...\"\n />\n </Field>\n\n {saveError && (\n <p className=\"rounded-lg bg-red-50 px-3 py-2 text-xs text-red-600\">\n {saveError}\n </p>\n )}\n {saveSuccess && (\n <p className=\"rounded-lg bg-emerald-50 px-3 py-2 text-xs text-emerald-600\">\n Organização atualizada.\n </p>\n )}\n\n <div className=\"flex justify-end pt-1\">\n <Button\n disabled={saving}\n size=\"sm\"\n tone=\"primary\"\n type=\"submit\"\n >\n {saving ? \"Salvando…\" : \"Salvar organização\"}\n </Button>\n </div>\n </form>\n )}\n\n {tab === \"members\" && currentOrg && (\n <div className=\"grid gap-2\">\n {(currentOrg.members ?? []).length === 0 && (\n <p className=\"py-8 text-center text-sm text-slate-400\">\n Nenhum membro nesta organização.\n </p>\n )}\n {(currentOrg.members ?? []).map((member) => (\n <div\n className=\"flex items-center gap-3 rounded-xl border border-slate-200 p-4\"\n key={member.id}\n >\n <Avatar\n name={member.user.name ?? member.user.email}\n size=\"sm\"\n src={member.user.imageUrl}\n />\n <div className=\"min-w-0 flex-1\">\n <p className=\"truncate text-sm font-medium text-slate-900\">\n {member.user.name ?? member.user.email}\n </p>\n <p className=\"truncate text-xs text-slate-500\">\n {member.user.email}\n </p>\n </div>\n <div className=\"flex shrink-0 flex-wrap justify-end gap-1\">\n {(member.roleAssignments ?? []).map((a) => (\n <span\n className=\"rounded-full bg-slate-900 px-2 py-0.5 text-[11px] font-medium text-white\"\n key={a.id}\n >\n {a.roleDefinition?.name ?? a.customRole?.name ?? a.id}\n </span>\n ))}\n </div>\n </div>\n ))}\n </div>\n )}\n\n {tab === \"new\" && (\n <div className=\"grid gap-4\">\n <p className=\"text-sm text-slate-500\">\n Crie uma nova organização e alterne para ela automaticamente.\n </p>\n <CreateOrganizationForm\n onCancel={() => setTab(\"info\")}\n onCreated={() => {\n void refreshOrganizations();\n setTab(\"info\");\n }}\n />\n </div>\n )}\n\n {tab === \"roles\" && (\n <div className=\"grid gap-5 sm:grid-cols-2\">\n <div className=\"min-w-0\">\n <h3 className=\"mb-3 text-xs font-semibold uppercase tracking-wider text-slate-400\">\n Roles ({roles.systemRoles.length + roles.customRoles.length})\n </h3>\n <div className=\"max-h-[280px] space-y-2 overflow-y-auto pr-1\">\n {roles.systemRoles.length === 0 &&\n roles.customRoles.length === 0 && (\n <p className=\"text-sm text-slate-400\">Nenhuma role.</p>\n )}\n {[...roles.systemRoles, ...roles.customRoles].map((role) => (\n <div\n className=\"overflow-hidden rounded-xl border border-slate-200 p-3\"\n key={role.id}\n >\n <p className=\"truncate text-sm font-semibold text-slate-900\">\n {role.name}\n </p>\n <p className=\"truncate text-xs text-slate-400\">\n {role.key}\n </p>\n <p className=\"mt-1 text-xs text-slate-500\">\n {role.permissions.length} permission\n {role.permissions.length !== 1 ? \"s\" : \"\"}\n </p>\n </div>\n ))}\n </div>\n </div>\n <div className=\"min-w-0\">\n <h3 className=\"mb-3 text-xs font-semibold uppercase tracking-wider text-slate-400\">\n Permissions ({permissions.length})\n </h3>\n <div className=\"max-h-[280px] space-y-2 overflow-y-auto pr-1\">\n {permissions.length === 0 && (\n <p className=\"text-sm text-slate-400\">\n Nenhuma permission.\n </p>\n )}\n {permissions.map((permission) => (\n <div\n className=\"overflow-hidden rounded-xl border border-slate-200 p-3\"\n key={permission.id}\n >\n <p className=\"truncate text-sm font-semibold text-slate-900\">\n {permission.key}\n </p>\n <p className=\"truncate text-xs text-slate-400\">\n {permission.category ?? \"custom\"}\n </p>\n </div>\n ))}\n </div>\n </div>\n </div>\n )}\n </div>\n </div>\n </div>\n );\n }\n\n function WaitlistForm({\n clientId,\n defaultEmail = \"\",\n onJoined,\n submitLabel = \"Entrar na lista de espera\",\n }: {\n clientId: string;\n defaultEmail?: string;\n onJoined?: (response: JoinWaitlistResponse) => void;\n submitLabel?: string;\n }) {\n const { joinWaitlist } = useAuth();\n const [name, setName] = useState(\"\");\n const [email, setEmail] = useState(defaultEmail);\n const [busy, setBusy] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [done, setDone] = useState<JoinWaitlistResponse | null>(null);\n\n async function submit(event: FormEvent) {\n event.preventDefault();\n if (!joinWaitlist) {\n setError(\"Lista de espera indisponível: atualize @geekapps/auth-nextjs para 0.26 ou superior.\");\n return;\n }\n setBusy(true);\n setError(null);\n const result = await joinWaitlist({\n clientId,\n email: email.trim(),\n name: name.trim() || undefined,\n });\n setBusy(false);\n if (!result.success) {\n setError(authErrorMessage(result, \"Não foi possível entrar na lista de espera.\"));\n return;\n }\n setDone(result.data);\n onJoined?.(result.data);\n }\n\n if (done) {\n return (\n <div className=\"grid gap-1 rounded-xl border border-emerald-200 bg-emerald-50 p-4 text-center\">\n <p className=\"text-sm font-semibold text-emerald-800\">\n {done.status === \"approved\"\n ? \"Seu acesso foi liberado!\"\n : done.status === \"joined\"\n ? \"Você já tem acesso.\"\n : \"Você está na lista de espera.\"}\n </p>\n {done.status === \"waiting\" && done.position != null && (\n <p className=\"text-sm text-emerald-700\">\n Sua posição na fila: <span className=\"font-semibold\">#{done.position}</span>\n </p>\n )}\n </div>\n );\n }\n\n return (\n <form className=\"grid gap-3\" onSubmit={(event) => void submit(event)}>\n <Field label=\"Nome\">\n <Input\n autoComplete=\"name\"\n onChange={(event) => setName(event.target.value)}\n placeholder=\"Seu nome\"\n value={name}\n />\n </Field>\n <Field label=\"E-mail\">\n <Input\n autoComplete=\"email\"\n onChange={(event) => setEmail(event.target.value)}\n placeholder=\"voce@exemplo.com\"\n required\n type=\"email\"\n value={email}\n />\n </Field>\n {error && <p className=\"text-xs text-red-600\">{error}</p>}\n <Button disabled={busy || !email.trim()} tone=\"primary\" type=\"submit\">\n {busy ? \"Enviando...\" : submitLabel}\n </Button>\n </form>\n );\n }\n\n return {\n WaitlistForm,\n SignInButton,\n SignOutButton,\n AccountSwitcher,\n OrgSwitcher,\n UserButton,\n OrganizationButton,\n ProfileModal,\n ManageOrganizationModal,\n CreateOrganizationForm,\n };\n}\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@geekapps/auth-elements-nextjs",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"sideEffects": [
|
|
6
6
|
"./src/styles.css"
|
|
@@ -17,7 +17,8 @@
|
|
|
17
17
|
"README.md"
|
|
18
18
|
],
|
|
19
19
|
"scripts": {
|
|
20
|
-
"build": "tsup && tailwindcss -i ./src/styles.css -o ./dist/styles.css --minify"
|
|
20
|
+
"build": "tsup && tailwindcss -i ./src/styles.css -o ./dist/styles.css --minify",
|
|
21
|
+
"check:contract": "tsc --noEmit -p tsconfig.contract.json"
|
|
21
22
|
},
|
|
22
23
|
"dependencies": {
|
|
23
24
|
"tailwindcss": "^4.2.2"
|
|
@@ -26,7 +27,8 @@
|
|
|
26
27
|
"next": ">=15",
|
|
27
28
|
"react": ">=18",
|
|
28
29
|
"react-dom": ">=18",
|
|
29
|
-
"typescript": ">=5"
|
|
30
|
+
"typescript": ">=5",
|
|
31
|
+
"@geekapps/auth-nextjs": ">=0.20.0"
|
|
30
32
|
},
|
|
31
33
|
"devDependencies": {
|
|
32
34
|
"@types/node": "^25.0.0",
|
|
@@ -34,5 +36,10 @@
|
|
|
34
36
|
"tsup": "^8.5.1",
|
|
35
37
|
"typescript": "^5.0.0",
|
|
36
38
|
"@tailwindcss/cli": "^4.2.2"
|
|
39
|
+
},
|
|
40
|
+
"peerDependenciesMeta": {
|
|
41
|
+
"@geekapps/auth-nextjs": {
|
|
42
|
+
"optional": true
|
|
43
|
+
}
|
|
37
44
|
}
|
|
38
|
-
}
|
|
45
|
+
}
|