@greatapps/common 1.0.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/dist/components/handlers/SearchParamsHandler.mjs +23 -0
- package/dist/components/handlers/SearchParamsHandler.mjs.map +1 -0
- package/dist/components/layouts/MainLayout.mjs +60 -0
- package/dist/components/layouts/MainLayout.mjs.map +1 -0
- package/dist/components/layouts/MdSideBarNavigation.mjs +36 -0
- package/dist/components/layouts/MdSideBarNavigation.mjs.map +1 -0
- package/dist/components/layouts/NavBar.mjs +45 -0
- package/dist/components/layouts/NavBar.mjs.map +1 -0
- package/dist/components/layouts/NotificationItem.mjs +7 -0
- package/dist/components/layouts/NotificationItem.mjs.map +1 -0
- package/dist/components/layouts/SideBarNavigation.mjs +22 -0
- package/dist/components/layouts/SideBarNavigation.mjs.map +1 -0
- package/dist/components/ui/buttons/Button.mjs +51 -0
- package/dist/components/ui/buttons/Button.mjs.map +1 -0
- package/dist/components/ui/buttons/CancelButton.mjs +16 -0
- package/dist/components/ui/buttons/CancelButton.mjs.map +1 -0
- package/dist/components/ui/buttons/CopyButton.mjs +34 -0
- package/dist/components/ui/buttons/CopyButton.mjs.map +1 -0
- package/dist/components/ui/data-display/Accordion.mjs +73 -0
- package/dist/components/ui/data-display/Accordion.mjs.map +1 -0
- package/dist/components/ui/data-display/Badge.mjs +41 -0
- package/dist/components/ui/data-display/Badge.mjs.map +1 -0
- package/dist/components/ui/data-display/Card.mjs +91 -0
- package/dist/components/ui/data-display/Card.mjs.map +1 -0
- package/dist/components/ui/data-display/Pagination.mjs +115 -0
- package/dist/components/ui/data-display/Pagination.mjs.map +1 -0
- package/dist/components/ui/data-display/ScrollArea.mjs +60 -0
- package/dist/components/ui/data-display/ScrollArea.mjs.map +1 -0
- package/dist/components/ui/data-display/Separator.mjs +28 -0
- package/dist/components/ui/data-display/Separator.mjs.map +1 -0
- package/dist/components/ui/data-display/Table.mjs +116 -0
- package/dist/components/ui/data-display/Table.mjs.map +1 -0
- package/dist/components/ui/data-display/Tabs.mjs +69 -0
- package/dist/components/ui/data-display/Tabs.mjs.map +1 -0
- package/dist/components/ui/feedback/CircularProgress.mjs +61 -0
- package/dist/components/ui/feedback/CircularProgress.mjs.map +1 -0
- package/dist/components/ui/feedback/DefaultCircularProgress.mjs +49 -0
- package/dist/components/ui/feedback/DefaultCircularProgress.mjs.map +1 -0
- package/dist/components/ui/feedback/Progress.mjs +37 -0
- package/dist/components/ui/feedback/Progress.mjs.map +1 -0
- package/dist/components/ui/feedback/Toast.mjs +73 -0
- package/dist/components/ui/feedback/Toast.mjs.map +1 -0
- package/dist/components/ui/form/Calendar.mjs +203 -0
- package/dist/components/ui/form/Calendar.mjs.map +1 -0
- package/dist/components/ui/form/Checkbox.mjs +33 -0
- package/dist/components/ui/form/Checkbox.mjs.map +1 -0
- package/dist/components/ui/form/DatePicker.mjs +78 -0
- package/dist/components/ui/form/DatePicker.mjs.map +1 -0
- package/dist/components/ui/form/DateRangePicker.mjs +86 -0
- package/dist/components/ui/form/DateRangePicker.mjs.map +1 -0
- package/dist/components/ui/form/Input.mjs +20 -0
- package/dist/components/ui/form/Input.mjs.map +1 -0
- package/dist/components/ui/form/InputOtp.mjs +67 -0
- package/dist/components/ui/form/InputOtp.mjs.map +1 -0
- package/dist/components/ui/form/RadioGroup.mjs +36 -0
- package/dist/components/ui/form/RadioGroup.mjs.map +1 -0
- package/dist/components/ui/form/Select.mjs +172 -0
- package/dist/components/ui/form/Select.mjs.map +1 -0
- package/dist/components/ui/form/Switch.mjs +33 -0
- package/dist/components/ui/form/Switch.mjs.map +1 -0
- package/dist/components/ui/form/Textarea.mjs +19 -0
- package/dist/components/ui/form/Textarea.mjs.map +1 -0
- package/dist/components/ui/overlay/Command.mjs +170 -0
- package/dist/components/ui/overlay/Command.mjs.map +1 -0
- package/dist/components/ui/overlay/Dialog.mjs +131 -0
- package/dist/components/ui/overlay/Dialog.mjs.map +1 -0
- package/dist/components/ui/overlay/Popover.mjs +46 -0
- package/dist/components/ui/overlay/Popover.mjs.map +1 -0
- package/dist/components/ui/overlay/Sheet.mjs +129 -0
- package/dist/components/ui/overlay/Sheet.mjs.map +1 -0
- package/dist/components/ui/overlay/Tooltip.mjs +55 -0
- package/dist/components/ui/overlay/Tooltip.mjs.map +1 -0
- package/dist/hooks/copy-to-clipboard.hook.mjs +39 -0
- package/dist/hooks/copy-to-clipboard.hook.mjs.map +1 -0
- package/dist/index.mjs +57 -0
- package/dist/index.mjs.map +1 -0
- package/dist/infra/api/client.mjs +115 -0
- package/dist/infra/api/client.mjs.map +1 -0
- package/dist/infra/api/types.mjs +31 -0
- package/dist/infra/api/types.mjs.map +1 -0
- package/dist/infra/utils/client-info.mjs +27 -0
- package/dist/infra/utils/client-info.mjs.map +1 -0
- package/dist/infra/utils/clsx.mjs +9 -0
- package/dist/infra/utils/clsx.mjs.map +1 -0
- package/dist/infra/utils/params.mjs +21 -0
- package/dist/infra/utils/params.mjs.map +1 -0
- package/dist/infra/utils/percentage.mjs +20 -0
- package/dist/infra/utils/percentage.mjs.map +1 -0
- package/dist/middlewares/chain.mjs +37 -0
- package/dist/middlewares/chain.mjs.map +1 -0
- package/dist/middlewares/create-auth-middleware.mjs +28 -0
- package/dist/middlewares/create-auth-middleware.mjs.map +1 -0
- package/dist/middlewares/types.mjs +11 -0
- package/dist/middlewares/types.mjs.map +1 -0
- package/dist/middlewares/validate-session.mjs +92 -0
- package/dist/middlewares/validate-session.mjs.map +1 -0
- package/dist/modules/auth/actions/login.action.mjs +11 -0
- package/dist/modules/auth/actions/login.action.mjs.map +1 -0
- package/dist/modules/auth/actions/logout.action.mjs +11 -0
- package/dist/modules/auth/actions/logout.action.mjs.map +1 -0
- package/dist/modules/auth/actions/register.action.mjs +9 -0
- package/dist/modules/auth/actions/register.action.mjs.map +1 -0
- package/dist/modules/auth/actions/validate-session.action.mjs +44 -0
- package/dist/modules/auth/actions/validate-session.action.mjs.map +1 -0
- package/dist/modules/auth/hooks/login.hook.mjs +12 -0
- package/dist/modules/auth/hooks/login.hook.mjs.map +1 -0
- package/dist/modules/auth/hooks/logout.hook.mjs +12 -0
- package/dist/modules/auth/hooks/logout.hook.mjs.map +1 -0
- package/dist/modules/auth/hooks/register.hook.mjs +12 -0
- package/dist/modules/auth/hooks/register.hook.mjs.map +1 -0
- package/dist/modules/auth/hooks/useUserQuery.mjs +48 -0
- package/dist/modules/auth/hooks/useUserQuery.mjs.map +1 -0
- package/dist/modules/auth/schema.mjs +1 -0
- package/dist/modules/auth/schema.mjs.map +1 -0
- package/dist/modules/auth/services/auth.service.mjs +163 -0
- package/dist/modules/auth/services/auth.service.mjs.map +1 -0
- package/dist/modules/users/action/find-user-by-id.action.mjs +21 -0
- package/dist/modules/users/action/find-user-by-id.action.mjs.map +1 -0
- package/dist/modules/users/schema.mjs +11 -0
- package/dist/modules/users/schema.mjs.map +1 -0
- package/dist/modules/users/services/user.service.mjs +50 -0
- package/dist/modules/users/services/user.service.mjs.map +1 -0
- package/dist/modules/whitelabel/actions/find-whitelabel.action.mjs +19 -0
- package/dist/modules/whitelabel/actions/find-whitelabel.action.mjs.map +1 -0
- package/dist/modules/whitelabel/schema.mjs +1 -0
- package/dist/modules/whitelabel/schema.mjs.map +1 -0
- package/dist/modules/whitelabel/services/whitelabel.service.mjs +62 -0
- package/dist/modules/whitelabel/services/whitelabel.service.mjs.map +1 -0
- package/dist/providers/auth.provider.mjs +84 -0
- package/dist/providers/auth.provider.mjs.map +1 -0
- package/dist/providers/query.provider.mjs +37 -0
- package/dist/providers/query.provider.mjs.map +1 -0
- package/dist/providers/whitelabel.provider.mjs +33 -0
- package/dist/providers/whitelabel.provider.mjs.map +1 -0
- package/dist/store/useMdSidebarStore.mjs +11 -0
- package/dist/store/useMdSidebarStore.mjs.map +1 -0
- package/package.json +68 -0
- package/src/components/handlers/SearchParamsHandler.tsx +61 -0
- package/src/components/layouts/MainLayout.tsx +59 -0
- package/src/components/layouts/MdSideBarNavigation.tsx +39 -0
- package/src/components/layouts/NavBar.tsx +79 -0
- package/src/components/layouts/NotificationItem.tsx +26 -0
- package/src/components/layouts/SideBarNavigation.tsx +22 -0
- package/src/components/ui/buttons/Button.tsx +55 -0
- package/src/components/ui/buttons/CancelButton.tsx +12 -0
- package/src/components/ui/buttons/CopyButton.tsx +47 -0
- package/src/components/ui/data-display/Accordion.tsx +79 -0
- package/src/components/ui/data-display/Badge.tsx +45 -0
- package/src/components/ui/data-display/Card.tsx +91 -0
- package/src/components/ui/data-display/Pagination.tsx +124 -0
- package/src/components/ui/data-display/ScrollArea.tsx +57 -0
- package/src/components/ui/data-display/Separator.tsx +27 -0
- package/src/components/ui/data-display/Table.tsx +115 -0
- package/src/components/ui/data-display/Tabs.tsx +65 -0
- package/src/components/ui/feedback/CircularProgress.tsx +75 -0
- package/src/components/ui/feedback/DefaultCircularProgress.tsx +53 -0
- package/src/components/ui/feedback/Progress.tsx +38 -0
- package/src/components/ui/feedback/Toast.tsx +99 -0
- package/src/components/ui/form/Calendar.tsx +226 -0
- package/src/components/ui/form/Checkbox.tsx +31 -0
- package/src/components/ui/form/DatePicker.tsx +97 -0
- package/src/components/ui/form/DateRangePicker.tsx +108 -0
- package/src/components/ui/form/Input.tsx +18 -0
- package/src/components/ui/form/InputOtp.tsx +78 -0
- package/src/components/ui/form/RadioGroup.tsx +43 -0
- package/src/components/ui/form/Select.tsx +195 -0
- package/src/components/ui/form/Switch.tsx +30 -0
- package/src/components/ui/form/Textarea.tsx +17 -0
- package/src/components/ui/overlay/Command.tsx +183 -0
- package/src/components/ui/overlay/Dialog.tsx +146 -0
- package/src/components/ui/overlay/Popover.tsx +47 -0
- package/src/components/ui/overlay/Sheet.tsx +145 -0
- package/src/components/ui/overlay/Tooltip.tsx +60 -0
- package/src/hooks/copy-to-clipboard.hook.tsx +52 -0
- package/src/index.ts +50 -0
- package/src/infra/api/client.ts +142 -0
- package/src/infra/api/types.ts +79 -0
- package/src/infra/utils/client-info.ts +35 -0
- package/src/infra/utils/clsx.ts +6 -0
- package/src/infra/utils/params.ts +27 -0
- package/src/infra/utils/percentage.ts +42 -0
- package/src/middlewares/chain.ts +45 -0
- package/src/middlewares/create-auth-middleware.ts +38 -0
- package/src/middlewares/types.ts +24 -0
- package/src/middlewares/validate-session.ts +116 -0
- package/src/modules/auth/actions/login.action.ts +11 -0
- package/src/modules/auth/actions/logout.action.ts +11 -0
- package/src/modules/auth/actions/register.action.ts +8 -0
- package/src/modules/auth/actions/validate-session.action.ts +51 -0
- package/src/modules/auth/hooks/login.hook.tsx +10 -0
- package/src/modules/auth/hooks/logout.hook.tsx +10 -0
- package/src/modules/auth/hooks/register.hook.tsx +10 -0
- package/src/modules/auth/hooks/useUserQuery.ts +49 -0
- package/src/modules/auth/schema.ts +220 -0
- package/src/modules/auth/services/auth.service.ts +225 -0
- package/src/modules/users/action/find-user-by-id.action.ts +25 -0
- package/src/modules/users/schema.ts +79 -0
- package/src/modules/users/services/user.service.ts +63 -0
- package/src/modules/whitelabel/actions/find-whitelabel.action.ts +20 -0
- package/src/modules/whitelabel/schema.ts +49 -0
- package/src/modules/whitelabel/services/whitelabel.service.ts +77 -0
- package/src/providers/auth.provider.tsx +113 -0
- package/src/providers/query.provider.tsx +52 -0
- package/src/providers/whitelabel.provider.tsx +44 -0
- package/src/store/useMdSidebarStore.ts +15 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/modules/users/action/find-user-by-id.action.ts"],"sourcesContent":["'use server';\r\n\r\nimport { userService } from '../services/user.service';\r\nimport { User } from '../schema';\r\n\r\nexport async function findUserById(): Promise<{\r\n success: boolean;\r\n data?: User;\r\n error?: string;\r\n}> {\r\n try {\r\n const user = await userService.findById();\r\n\r\n return {\r\n success: true,\r\n data: user,\r\n };\r\n } catch (error) {\r\n console.error('[findUserById] Error:', error);\r\n return {\r\n success: false,\r\n error: error instanceof Error ? error.message : 'Erro desconhecido',\r\n };\r\n }\r\n}\r\n"],"mappings":";AAEA,SAAS,mBAAmB;AAG5B,eAAsB,eAInB;AACD,MAAI;AACF,UAAM,OAAO,MAAM,YAAY,SAAS;AAExC,WAAO;AAAA,MACL,SAAS;AAAA,MACT,MAAM;AAAA,IACR;AAAA,EACF,SAAS,OAAO;AACd,YAAQ,MAAM,yBAAyB,KAAK;AAC5C,WAAO;AAAA,MACL,SAAS;AAAA,MACT,OAAO,iBAAiB,QAAQ,MAAM,UAAU;AAAA,IAClD;AAAA,EACF;AACF;","names":[]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
var UserProfile = /* @__PURE__ */ ((UserProfile2) => {
|
|
2
|
+
UserProfile2["viewer"] = "viewer";
|
|
3
|
+
UserProfile2["collaborator"] = "collaborator";
|
|
4
|
+
UserProfile2["admin"] = "admin";
|
|
5
|
+
UserProfile2["owner"] = "owner";
|
|
6
|
+
return UserProfile2;
|
|
7
|
+
})(UserProfile || {});
|
|
8
|
+
export {
|
|
9
|
+
UserProfile
|
|
10
|
+
};
|
|
11
|
+
//# sourceMappingURL=schema.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/modules/users/schema.ts"],"sourcesContent":["export enum UserProfile {\r\n viewer = 'viewer',\r\n collaborator = 'collaborator',\r\n admin = 'admin',\r\n owner = 'owner',\r\n}\r\n\r\nexport interface User {\r\n // Identificação\r\n id: number;\r\n id_wl: number;\r\n id_account: number;\r\n id_api: number;\r\n\r\n // Dados pessoais\r\n name: string;\r\n last_name: string;\r\n email: string;\r\n ddi: string;\r\n phone: string;\r\n rg: string | null;\r\n cpf: string | null;\r\n gender: number;\r\n\r\n // Autenticação e segurança\r\n two_factor_authentication: boolean;\r\n\r\n // Perfil e permissões\r\n profile: UserProfile;\r\n\r\n // Preferências\r\n language: string;\r\n receive_sms: boolean;\r\n receive_email: boolean;\r\n photo: string | null;\r\n\r\n // Metadados\r\n deleted: number;\r\n datetime_alt: string;\r\n datetime_del: string | null;\r\n datetime_add: string;\r\n\r\n total_projects: number;\r\n projects: { id: number; title: string }[];\r\n\r\n initials?: string;\r\n emailVerified?: boolean;\r\n createdAt?: string;\r\n updatedAt?: string;\r\n}\r\n\r\nexport interface GetUserDataResponse {\r\n status: 0 | 1;\r\n total: number;\r\n data: User[];\r\n}\r\n\r\nexport interface JWTPayload {\r\n session: {\r\n location: {\r\n continent: string;\r\n country: string;\r\n region: string;\r\n city: string;\r\n latitude: string;\r\n longitude: string;\r\n };\r\n ip: string;\r\n timezone: string;\r\n agent: string;\r\n code: string | null;\r\n };\r\n id_wl: string;\r\n id_account: number;\r\n id_user: number;\r\n iss: string;\r\n aud: string;\r\n iat: number;\r\n}\r\n"],"mappings":"AAAO,IAAK,cAAL,kBAAKA,iBAAL;AACL,EAAAA,aAAA,YAAS;AACT,EAAAA,aAAA,kBAAe;AACf,EAAAA,aAAA,WAAQ;AACR,EAAAA,aAAA,WAAQ;AAJE,SAAAA;AAAA,GAAA;","names":["UserProfile"]}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import "server-only";
|
|
2
|
+
import { cookies } from "next/headers";
|
|
3
|
+
import { ApiError } from "../../../infra/api/types";
|
|
4
|
+
import { findWhitelabel } from "../../whitelabel/actions/find-whitelabel.action";
|
|
5
|
+
const AUTH_COOKIE_NAME = "greatapps";
|
|
6
|
+
const API_BASE_URL = process.env.R3_API_URL || "https://r3-api.greatapps.dev.br";
|
|
7
|
+
class UserService {
|
|
8
|
+
async getAuthToken() {
|
|
9
|
+
const cookieStore = await cookies();
|
|
10
|
+
const token = cookieStore.get(AUTH_COOKIE_NAME)?.value;
|
|
11
|
+
if (!token) {
|
|
12
|
+
throw new ApiError("N\xE3o autenticado", "NOT_AUTHENTICATED", 401);
|
|
13
|
+
}
|
|
14
|
+
return token;
|
|
15
|
+
}
|
|
16
|
+
decodeJWT(token) {
|
|
17
|
+
try {
|
|
18
|
+
return JSON.parse(atob(token.split(".")[1]));
|
|
19
|
+
} catch {
|
|
20
|
+
throw new ApiError("Token inv\xE1lido", "INVALID_TOKEN", 401);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
async findById() {
|
|
24
|
+
const token = await this.getAuthToken();
|
|
25
|
+
const payload = this.decodeJWT(token);
|
|
26
|
+
const { id_wl, id_account, id_user } = payload;
|
|
27
|
+
const { token: wlToken } = await findWhitelabel();
|
|
28
|
+
const url = `${API_BASE_URL}/v1/pt-br/${id_wl}/accounts/${id_account}/users/${id_user}`;
|
|
29
|
+
const response = await fetch(url, {
|
|
30
|
+
method: "GET",
|
|
31
|
+
headers: {
|
|
32
|
+
"Content-Type": "application/json",
|
|
33
|
+
authorization: wlToken
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
if (!response.ok) {
|
|
37
|
+
throw new ApiError("Erro ao buscar dados do usu\xE1rio", "FETCH_ERROR", response.status);
|
|
38
|
+
}
|
|
39
|
+
const data = await response.json();
|
|
40
|
+
if (data.status === 0 || !data.data || data.data.length === 0) {
|
|
41
|
+
throw new ApiError("Dados do usu\xE1rio n\xE3o encontrados", "USER_NOT_FOUND", 404);
|
|
42
|
+
}
|
|
43
|
+
return data.data[0];
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
const userService = new UserService();
|
|
47
|
+
export {
|
|
48
|
+
userService
|
|
49
|
+
};
|
|
50
|
+
//# sourceMappingURL=user.service.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/modules/users/services/user.service.ts"],"sourcesContent":["import 'server-only';\r\n\r\nimport { cookies } from 'next/headers';\r\n\r\nimport { ApiError } from '../../../infra/api/types';\r\nimport { GetUserDataResponse, JWTPayload, User } from '../schema';\r\nimport { findWhitelabel } from '../../whitelabel/actions/find-whitelabel.action';\r\n\r\nconst AUTH_COOKIE_NAME = 'greatapps';\r\nconst API_BASE_URL = process.env.R3_API_URL || 'https://r3-api.greatapps.dev.br';\r\n\r\nclass UserService {\r\n private async getAuthToken(): Promise<string> {\r\n const cookieStore = await cookies();\r\n const token = cookieStore.get(AUTH_COOKIE_NAME)?.value;\r\n\r\n if (!token) {\r\n throw new ApiError('Não autenticado', 'NOT_AUTHENTICATED', 401);\r\n }\r\n\r\n return token;\r\n }\r\n\r\n private decodeJWT(token: string): JWTPayload {\r\n try {\r\n return JSON.parse(atob(token.split('.')[1])) as JWTPayload;\r\n } catch {\r\n throw new ApiError('Token inválido', 'INVALID_TOKEN', 401);\r\n }\r\n }\r\n\r\n async findById(): Promise<User> {\r\n const token = await this.getAuthToken();\r\n const payload = this.decodeJWT(token);\r\n\r\n const { id_wl, id_account, id_user } = payload;\r\n const { token: wlToken } = await findWhitelabel();\r\n\r\n const url = `${API_BASE_URL}/v1/pt-br/${id_wl}/accounts/${id_account}/users/${id_user}`;\r\n\r\n const response = await fetch(url, {\r\n method: 'GET',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n authorization: wlToken,\r\n },\r\n });\r\n\r\n if (!response.ok) {\r\n throw new ApiError('Erro ao buscar dados do usuário', 'FETCH_ERROR', response.status);\r\n }\r\n\r\n const data = (await response.json()) as GetUserDataResponse;\r\n\r\n if (data.status === 0 || !data.data || data.data.length === 0) {\r\n throw new ApiError('Dados do usuário não encontrados', 'USER_NOT_FOUND', 404);\r\n }\r\n\r\n return data.data[0];\r\n }\r\n}\r\n\r\nexport const userService = new UserService();\r\n"],"mappings":"AAAA,OAAO;AAEP,SAAS,eAAe;AAExB,SAAS,gBAAgB;AAEzB,SAAS,sBAAsB;AAE/B,MAAM,mBAAmB;AACzB,MAAM,eAAe,QAAQ,IAAI,cAAc;AAE/C,MAAM,YAAY;AAAA,EAChB,MAAc,eAAgC;AAC5C,UAAM,cAAc,MAAM,QAAQ;AAClC,UAAM,QAAQ,YAAY,IAAI,gBAAgB,GAAG;AAEjD,QAAI,CAAC,OAAO;AACV,YAAM,IAAI,SAAS,sBAAmB,qBAAqB,GAAG;AAAA,IAChE;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,UAAU,OAA2B;AAC3C,QAAI;AACF,aAAO,KAAK,MAAM,KAAK,MAAM,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC;AAAA,IAC7C,QAAQ;AACN,YAAM,IAAI,SAAS,qBAAkB,iBAAiB,GAAG;AAAA,IAC3D;AAAA,EACF;AAAA,EAEA,MAAM,WAA0B;AAC9B,UAAM,QAAQ,MAAM,KAAK,aAAa;AACtC,UAAM,UAAU,KAAK,UAAU,KAAK;AAEpC,UAAM,EAAE,OAAO,YAAY,QAAQ,IAAI;AACvC,UAAM,EAAE,OAAO,QAAQ,IAAI,MAAM,eAAe;AAEhD,UAAM,MAAM,GAAG,YAAY,aAAa,KAAK,aAAa,UAAU,UAAU,OAAO;AAErF,UAAM,WAAW,MAAM,MAAM,KAAK;AAAA,MAChC,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,eAAe;AAAA,MACjB;AAAA,IACF,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,IAAI,SAAS,sCAAmC,eAAe,SAAS,MAAM;AAAA,IACtF;AAEA,UAAM,OAAQ,MAAM,SAAS,KAAK;AAElC,QAAI,KAAK,WAAW,KAAK,CAAC,KAAK,QAAQ,KAAK,KAAK,WAAW,GAAG;AAC7D,YAAM,IAAI,SAAS,0CAAoC,kBAAkB,GAAG;AAAA,IAC9E;AAEA,WAAO,KAAK,KAAK,CAAC;AAAA,EACpB;AACF;AAEO,MAAM,cAAc,IAAI,YAAY;","names":[]}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { headers } from "next/headers";
|
|
2
|
+
import { whitelabelService } from "../services/whitelabel.service";
|
|
3
|
+
import { ApiError } from "../../../infra/api/types";
|
|
4
|
+
async function findWhitelabel() {
|
|
5
|
+
const headersList = await headers();
|
|
6
|
+
const host = headersList.get("host");
|
|
7
|
+
if (!host) {
|
|
8
|
+
throw new ApiError("Host header not found", "HOST_NOT_FOUND", 400);
|
|
9
|
+
}
|
|
10
|
+
const whitelabel = await whitelabelService.getTokenByDomain(host);
|
|
11
|
+
if (!whitelabel) {
|
|
12
|
+
throw new ApiError("Whitelabel not found", "WL_NOT_FOUND", 404);
|
|
13
|
+
}
|
|
14
|
+
return whitelabel;
|
|
15
|
+
}
|
|
16
|
+
export {
|
|
17
|
+
findWhitelabel
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=find-whitelabel.action.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/modules/whitelabel/actions/find-whitelabel.action.ts"],"sourcesContent":["import { headers } from \"next/headers\";\nimport { whitelabelService } from \"../services/whitelabel.service\";\nimport { ApiError } from \"../../../infra/api/types\";\n\nexport async function findWhitelabel() {\n const headersList = await headers();\n const host = headersList.get('host');\n\n if (!host) {\n throw new ApiError('Host header not found', 'HOST_NOT_FOUND', 400);\n }\n\n const whitelabel = await whitelabelService.getTokenByDomain(host);\n\n if (!whitelabel) {\n throw new ApiError('Whitelabel not found', 'WL_NOT_FOUND', 404);\n }\n\n return whitelabel;\n}"],"mappings":"AAAA,SAAS,eAAe;AACxB,SAAS,yBAAyB;AAClC,SAAS,gBAAgB;AAEzB,eAAsB,iBAAiB;AACnC,QAAM,cAAc,MAAM,QAAQ;AAClC,QAAM,OAAO,YAAY,IAAI,MAAM;AAEnC,MAAI,CAAC,MAAM;AACP,UAAM,IAAI,SAAS,yBAAyB,kBAAkB,GAAG;AAAA,EACrE;AAEA,QAAM,aAAa,MAAM,kBAAkB,iBAAiB,IAAI;AAEhE,MAAI,CAAC,YAAY;AACb,UAAM,IAAI,SAAS,wBAAwB,gBAAgB,GAAG;AAAA,EAClE;AAEA,SAAO;AACX;","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=schema.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import "server-only";
|
|
2
|
+
import greatCache from "@greatapps/cache";
|
|
3
|
+
import { ApiError } from "../../../infra/api/types";
|
|
4
|
+
class WhitelabelService {
|
|
5
|
+
getApiUrl() {
|
|
6
|
+
const apiUrl = process.env.R3_API_URL;
|
|
7
|
+
if (!apiUrl) {
|
|
8
|
+
throw new ApiError("R3_API_URL not configured", "CONFIG_ERROR", 500);
|
|
9
|
+
}
|
|
10
|
+
return apiUrl;
|
|
11
|
+
}
|
|
12
|
+
getToken() {
|
|
13
|
+
const token = process.env.WHITELABEL_TOKEN_MASTER;
|
|
14
|
+
if (!token) {
|
|
15
|
+
throw new ApiError("WHITELABEL_TOKEN_MASTER not configured", "CONFIG_ERROR", 500);
|
|
16
|
+
}
|
|
17
|
+
return token;
|
|
18
|
+
}
|
|
19
|
+
async getTokenByDomain(hostname) {
|
|
20
|
+
hostname = "greatapps.com.br";
|
|
21
|
+
const apiUrl = this.getApiUrl();
|
|
22
|
+
const whitelabelMasterToken = this.getToken();
|
|
23
|
+
const url = `${apiUrl}/v1/pt-br/1/whitelabel/${hostname}/token`;
|
|
24
|
+
console.log("[WhitelabelService] Fetching token for domain", { url });
|
|
25
|
+
const cache = new greatCache({
|
|
26
|
+
service: "whitelabel-service",
|
|
27
|
+
version: "1.0",
|
|
28
|
+
domain: "whitelabel-cache.greatapps.com.br",
|
|
29
|
+
ambient: process.env.NODE_ENV || "development"
|
|
30
|
+
});
|
|
31
|
+
const cachedData = await cache.select(`whitelabel-token-${hostname}`);
|
|
32
|
+
if (cachedData.status == 1 && "data" in cachedData && cachedData.data) {
|
|
33
|
+
console.log("[WhitelabelService] Cache hit for domain", { hostname });
|
|
34
|
+
return JSON.parse(cachedData.data);
|
|
35
|
+
}
|
|
36
|
+
const response = await fetch(url, {
|
|
37
|
+
method: "GET",
|
|
38
|
+
headers: {
|
|
39
|
+
authorization: whitelabelMasterToken
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
if (!response.ok) {
|
|
43
|
+
console.error("[WhitelabelService] Failed to fetch whitelabel token", { response });
|
|
44
|
+
throw new ApiError(
|
|
45
|
+
`Failed to fetch whitelabel token: ${response.status}`,
|
|
46
|
+
"FETCH_ERROR",
|
|
47
|
+
response.status
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
const result = await response.json();
|
|
51
|
+
if (result.status !== 1 || !result.data?.length) {
|
|
52
|
+
throw new ApiError("Whitelabel token not found", "TOKEN_NOT_FOUND", 404);
|
|
53
|
+
}
|
|
54
|
+
await cache.insert(`whitelabel-token-${hostname}`, JSON.stringify(result.data[0]), 604800);
|
|
55
|
+
return result.data[0];
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
const whitelabelService = new WhitelabelService();
|
|
59
|
+
export {
|
|
60
|
+
whitelabelService
|
|
61
|
+
};
|
|
62
|
+
//# sourceMappingURL=whitelabel.service.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/modules/whitelabel/services/whitelabel.service.ts"],"sourcesContent":["import 'server-only';\r\n\r\nimport greatCache from '@greatapps/cache';\r\nimport { ApiError } from '../../../infra/api/types';\r\nimport { WhitelabelTokenApiResponse, WhitelabelTokenData } from '../schema';\r\n\r\nclass WhitelabelService {\r\n private getApiUrl(): string {\r\n const apiUrl = process.env.R3_API_URL;\r\n if (!apiUrl) {\r\n throw new ApiError('R3_API_URL not configured', 'CONFIG_ERROR', 500);\r\n }\r\n return apiUrl;\r\n }\r\n\r\n private getToken(): string {\r\n const token = process.env.WHITELABEL_TOKEN_MASTER;\r\n if (!token) {\r\n throw new ApiError('WHITELABEL_TOKEN_MASTER not configured', 'CONFIG_ERROR', 500);\r\n }\r\n return token;\r\n }\r\n\r\n async getTokenByDomain(hostname: string): Promise<WhitelabelTokenData> {\r\n hostname = 'greatapps.com.br';\r\n\r\n const apiUrl = this.getApiUrl();\r\n const whitelabelMasterToken = this.getToken();\r\n\r\n const url = `${apiUrl}/v1/pt-br/1/whitelabel/${hostname}/token`;\r\n\r\n console.log('[WhitelabelService] Fetching token for domain', { url });\r\n\r\n const cache = new greatCache({\r\n service: 'whitelabel-service',\r\n version: '1.0',\r\n domain: 'whitelabel-cache.greatapps.com.br',\r\n ambient: process.env.NODE_ENV || 'development',\r\n });\r\n\r\n const cachedData = await cache.select(`whitelabel-token-${hostname}`);\r\n\r\n if (cachedData.status == 1 && 'data' in cachedData && cachedData.data) {\r\n console.log('[WhitelabelService] Cache hit for domain', { hostname });\r\n\r\n return JSON.parse(cachedData.data) as WhitelabelTokenData;\r\n }\r\n\r\n const response = await fetch(url, {\r\n method: 'GET',\r\n headers: {\r\n authorization: whitelabelMasterToken,\r\n },\r\n });\r\n\r\n if (!response.ok) {\r\n console.error('[WhitelabelService] Failed to fetch whitelabel token', { response });\r\n throw new ApiError(\r\n `Failed to fetch whitelabel token: ${response.status}`,\r\n 'FETCH_ERROR',\r\n response.status\r\n );\r\n }\r\n\r\n const result: WhitelabelTokenApiResponse = await response.json();\r\n\r\n if (result.status !== 1 || !result.data?.length) {\r\n throw new ApiError('Whitelabel token not found', 'TOKEN_NOT_FOUND', 404);\r\n }\r\n\r\n await cache.insert(`whitelabel-token-${hostname}`, JSON.stringify(result.data[0]), 604800);\r\n\r\n return result.data[0];\r\n }\r\n}\r\n\r\nexport const whitelabelService = new WhitelabelService();\r\n"],"mappings":"AAAA,OAAO;AAEP,OAAO,gBAAgB;AACvB,SAAS,gBAAgB;AAGzB,MAAM,kBAAkB;AAAA,EACd,YAAoB;AAC1B,UAAM,SAAS,QAAQ,IAAI;AAC3B,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI,SAAS,6BAA6B,gBAAgB,GAAG;AAAA,IACrE;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,WAAmB;AACzB,UAAM,QAAQ,QAAQ,IAAI;AAC1B,QAAI,CAAC,OAAO;AACV,YAAM,IAAI,SAAS,0CAA0C,gBAAgB,GAAG;AAAA,IAClF;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,iBAAiB,UAAgD;AACrE,eAAW;AAEX,UAAM,SAAS,KAAK,UAAU;AAC9B,UAAM,wBAAwB,KAAK,SAAS;AAE5C,UAAM,MAAM,GAAG,MAAM,0BAA0B,QAAQ;AAEvD,YAAQ,IAAI,iDAAiD,EAAE,IAAI,CAAC;AAEpE,UAAM,QAAQ,IAAI,WAAW;AAAA,MAC3B,SAAS;AAAA,MACT,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,SAAS,QAAQ,IAAI,YAAY;AAAA,IACnC,CAAC;AAED,UAAM,aAAa,MAAM,MAAM,OAAO,oBAAoB,QAAQ,EAAE;AAEpE,QAAI,WAAW,UAAU,KAAK,UAAU,cAAc,WAAW,MAAM;AACrE,cAAQ,IAAI,4CAA4C,EAAE,SAAS,CAAC;AAEpE,aAAO,KAAK,MAAM,WAAW,IAAI;AAAA,IACnC;AAEA,UAAM,WAAW,MAAM,MAAM,KAAK;AAAA,MAChC,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,eAAe;AAAA,MACjB;AAAA,IACF,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,cAAQ,MAAM,wDAAwD,EAAE,SAAS,CAAC;AAClF,YAAM,IAAI;AAAA,QACR,qCAAqC,SAAS,MAAM;AAAA,QACpD;AAAA,QACA,SAAS;AAAA,MACX;AAAA,IACF;AAEA,UAAM,SAAqC,MAAM,SAAS,KAAK;AAE/D,QAAI,OAAO,WAAW,KAAK,CAAC,OAAO,MAAM,QAAQ;AAC/C,YAAM,IAAI,SAAS,8BAA8B,mBAAmB,GAAG;AAAA,IACzE;AAEA,UAAM,MAAM,OAAO,oBAAoB,QAAQ,IAAI,KAAK,UAAU,OAAO,KAAK,CAAC,CAAC,GAAG,MAAM;AAEzF,WAAO,OAAO,KAAK,CAAC;AAAA,EACtB;AACF;AAEO,MAAM,oBAAoB,IAAI,kBAAkB;","names":[]}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import {
|
|
3
|
+
createContext,
|
|
4
|
+
useCallback,
|
|
5
|
+
useContext,
|
|
6
|
+
useMemo
|
|
7
|
+
} from "react";
|
|
8
|
+
import {
|
|
9
|
+
useUserQuery,
|
|
10
|
+
useSetUserData,
|
|
11
|
+
useInvalidateUser,
|
|
12
|
+
useUserValidateSession
|
|
13
|
+
} from "../modules/auth/hooks/useUserQuery";
|
|
14
|
+
import { useLogin } from "../modules/auth/hooks/login.hook";
|
|
15
|
+
import { useRegister } from "../modules/auth/hooks/register.hook";
|
|
16
|
+
import { useLogout } from "../modules/auth/hooks/logout.hook";
|
|
17
|
+
const AuthContext = createContext(
|
|
18
|
+
void 0
|
|
19
|
+
);
|
|
20
|
+
function AuthProvider({ children }) {
|
|
21
|
+
const { data: user, isLoading: isQueryLoading } = useUserQuery();
|
|
22
|
+
const { isLoading: isSessionLoading } = useUserValidateSession();
|
|
23
|
+
const setUserData = useSetUserData();
|
|
24
|
+
const invalidateUser = useInvalidateUser();
|
|
25
|
+
const { mutateAsync: loginMutate, isPending: isLogging } = useLogin();
|
|
26
|
+
const { mutateAsync: registerMutate, isPending: isRegistering } = useRegister();
|
|
27
|
+
const { mutateAsync: logoutMutate, isPending: isLoggingOut } = useLogout();
|
|
28
|
+
const isAuthenticated = !!user;
|
|
29
|
+
const isLoading = isLogging || isRegistering || isLoggingOut || isQueryLoading || isSessionLoading;
|
|
30
|
+
const login = useCallback(
|
|
31
|
+
async (credentials) => {
|
|
32
|
+
await loginMutate(credentials, {
|
|
33
|
+
onSuccess: (data) => {
|
|
34
|
+
invalidateUser();
|
|
35
|
+
setUserData(data.user);
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
},
|
|
39
|
+
[invalidateUser]
|
|
40
|
+
);
|
|
41
|
+
const register = useCallback(
|
|
42
|
+
async (data) => {
|
|
43
|
+
await registerMutate(data, {
|
|
44
|
+
onSuccess: (data2) => {
|
|
45
|
+
invalidateUser();
|
|
46
|
+
setUserData(data2.user);
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
},
|
|
50
|
+
[setUserData]
|
|
51
|
+
);
|
|
52
|
+
const logout = useCallback(async () => {
|
|
53
|
+
await logoutMutate(void 0, {
|
|
54
|
+
onSuccess: () => {
|
|
55
|
+
invalidateUser();
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
}, [setUserData]);
|
|
59
|
+
const value = useMemo(
|
|
60
|
+
() => ({
|
|
61
|
+
user: user ?? null,
|
|
62
|
+
isAuthenticated,
|
|
63
|
+
isLoading,
|
|
64
|
+
login,
|
|
65
|
+
register,
|
|
66
|
+
logout
|
|
67
|
+
}),
|
|
68
|
+
[user, isAuthenticated, isLoading, login, register, logout]
|
|
69
|
+
);
|
|
70
|
+
return /* @__PURE__ */ React.createElement(AuthContext.Provider, { value }, children);
|
|
71
|
+
}
|
|
72
|
+
function useAuth() {
|
|
73
|
+
const context = useContext(AuthContext);
|
|
74
|
+
if (context === void 0) {
|
|
75
|
+
throw new Error("useAuth deve ser usado dentro de um AuthProvider");
|
|
76
|
+
}
|
|
77
|
+
return context;
|
|
78
|
+
}
|
|
79
|
+
export {
|
|
80
|
+
AuthContext,
|
|
81
|
+
AuthProvider,
|
|
82
|
+
useAuth
|
|
83
|
+
};
|
|
84
|
+
//# sourceMappingURL=auth.provider.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/providers/auth.provider.tsx"],"sourcesContent":["\"use client\";\r\n\r\nimport {\r\n createContext,\r\n ReactNode,\r\n useCallback,\r\n useContext,\r\n useMemo,\r\n} from \"react\";\r\nimport {\r\n useUserQuery,\r\n useSetUserData,\r\n useInvalidateUser,\r\n useUserValidateSession,\r\n} from \"../modules/auth/hooks/useUserQuery\";\r\nimport { useLogin } from \"../modules/auth/hooks/login.hook\";\r\nimport { useRegister } from \"../modules/auth/hooks/register.hook\";\r\nimport { useLogout } from \"../modules/auth/hooks/logout.hook\";\r\nimport {\r\n AuthState,\r\n LoginRequest,\r\n RegisterRequest,\r\n} from \"../modules/auth/schema\";\r\n\r\ninterface AuthContextProps extends AuthState {\r\n login: (credentials: LoginRequest) => Promise<void>;\r\n register: (data: RegisterRequest) => Promise<void>;\r\n logout: () => Promise<void>;\r\n}\r\n\r\nexport const AuthContext = createContext<AuthContextProps | undefined>(\r\n undefined,\r\n);\r\n\r\ninterface AuthProviderProps {\r\n children: ReactNode;\r\n}\r\n\r\nexport function AuthProvider({ children }: AuthProviderProps) {\r\n const { data: user, isLoading: isQueryLoading } = useUserQuery();\r\n const { isLoading: isSessionLoading } = useUserValidateSession();\r\n const setUserData = useSetUserData();\r\n const invalidateUser = useInvalidateUser();\r\n\r\n const { mutateAsync: loginMutate, isPending: isLogging } = useLogin();\r\n const { mutateAsync: registerMutate, isPending: isRegistering } =\r\n useRegister();\r\n const { mutateAsync: logoutMutate, isPending: isLoggingOut } = useLogout();\r\n\r\n const isAuthenticated = !!user;\r\n const isLoading =\r\n isLogging ||\r\n isRegistering ||\r\n isLoggingOut ||\r\n isQueryLoading ||\r\n isSessionLoading;\r\n\r\n const login = useCallback(\r\n async (credentials: LoginRequest): Promise<void> => {\r\n await loginMutate(credentials, {\r\n onSuccess: (data) => {\r\n invalidateUser();\r\n setUserData(data.user);\r\n },\r\n });\r\n },\r\n [invalidateUser],\r\n );\r\n\r\n const register = useCallback(\r\n async (data: RegisterRequest): Promise<void> => {\r\n await registerMutate(data, {\r\n onSuccess: (data) => {\r\n invalidateUser();\r\n setUserData(data.user);\r\n },\r\n });\r\n },\r\n [setUserData],\r\n );\r\n\r\n const logout = useCallback(async (): Promise<void> => {\r\n await logoutMutate(undefined, {\r\n onSuccess: () => {\r\n invalidateUser();\r\n },\r\n });\r\n }, [setUserData]);\r\n\r\n const value: AuthContextProps = useMemo(\r\n () => ({\r\n user: user ?? null,\r\n isAuthenticated,\r\n isLoading,\r\n login,\r\n register,\r\n logout,\r\n }),\r\n [user, isAuthenticated, isLoading, login, register, logout],\r\n );\r\n\r\n return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;\r\n}\r\n\r\nexport function useAuth(): AuthContextProps {\r\n const context = useContext(AuthContext);\r\n\r\n if (context === undefined) {\r\n throw new Error(\"useAuth deve ser usado dentro de um AuthProvider\");\r\n }\r\n\r\n return context;\r\n}\r\n"],"mappings":";AAEA;AAAA,EACE;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,gBAAgB;AACzB,SAAS,mBAAmB;AAC5B,SAAS,iBAAiB;AAanB,MAAM,cAAc;AAAA,EACzB;AACF;AAMO,SAAS,aAAa,EAAE,SAAS,GAAsB;AAC5D,QAAM,EAAE,MAAM,MAAM,WAAW,eAAe,IAAI,aAAa;AAC/D,QAAM,EAAE,WAAW,iBAAiB,IAAI,uBAAuB;AAC/D,QAAM,cAAc,eAAe;AACnC,QAAM,iBAAiB,kBAAkB;AAEzC,QAAM,EAAE,aAAa,aAAa,WAAW,UAAU,IAAI,SAAS;AACpE,QAAM,EAAE,aAAa,gBAAgB,WAAW,cAAc,IAC5D,YAAY;AACd,QAAM,EAAE,aAAa,cAAc,WAAW,aAAa,IAAI,UAAU;AAEzE,QAAM,kBAAkB,CAAC,CAAC;AAC1B,QAAM,YACJ,aACA,iBACA,gBACA,kBACA;AAEF,QAAM,QAAQ;AAAA,IACZ,OAAO,gBAA6C;AAClD,YAAM,YAAY,aAAa;AAAA,QAC7B,WAAW,CAAC,SAAS;AACnB,yBAAe;AACf,sBAAY,KAAK,IAAI;AAAA,QACvB;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IACA,CAAC,cAAc;AAAA,EACjB;AAEA,QAAM,WAAW;AAAA,IACf,OAAO,SAAyC;AAC9C,YAAM,eAAe,MAAM;AAAA,QACzB,WAAW,CAACA,UAAS;AACnB,yBAAe;AACf,sBAAYA,MAAK,IAAI;AAAA,QACvB;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IACA,CAAC,WAAW;AAAA,EACd;AAEA,QAAM,SAAS,YAAY,YAA2B;AACpD,UAAM,aAAa,QAAW;AAAA,MAC5B,WAAW,MAAM;AACf,uBAAe;AAAA,MACjB;AAAA,IACF,CAAC;AAAA,EACH,GAAG,CAAC,WAAW,CAAC;AAEhB,QAAM,QAA0B;AAAA,IAC9B,OAAO;AAAA,MACL,MAAM,QAAQ;AAAA,MACd;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,CAAC,MAAM,iBAAiB,WAAW,OAAO,UAAU,MAAM;AAAA,EAC5D;AAEA,SAAO,oCAAC,YAAY,UAAZ,EAAqB,SAAe,QAAS;AACvD;AAEO,SAAS,UAA4B;AAC1C,QAAM,UAAU,WAAW,WAAW;AAEtC,MAAI,YAAY,QAAW;AACzB,UAAM,IAAI,MAAM,kDAAkD;AAAA,EACpE;AAEA,SAAO;AACT;","names":["data"]}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import {
|
|
3
|
+
QueryCache,
|
|
4
|
+
QueryClient,
|
|
5
|
+
QueryClientProvider
|
|
6
|
+
} from "@tanstack/react-query";
|
|
7
|
+
import { useState } from "react";
|
|
8
|
+
import dynamic from "next/dynamic";
|
|
9
|
+
import { toast } from "sonner";
|
|
10
|
+
const ReactQueryDevtools = process.env.NODE_ENV === "development" ? dynamic(
|
|
11
|
+
() => import("@tanstack/react-query-devtools").then((mod) => ({
|
|
12
|
+
default: mod.ReactQueryDevtools
|
|
13
|
+
})),
|
|
14
|
+
{ ssr: false }
|
|
15
|
+
) : () => null;
|
|
16
|
+
function QueryProvider({ children }) {
|
|
17
|
+
const [queryClient] = useState(
|
|
18
|
+
() => new QueryClient({
|
|
19
|
+
defaultOptions: {
|
|
20
|
+
queries: {
|
|
21
|
+
staleTime: 60 * 1e3,
|
|
22
|
+
refetchOnWindowFocus: false
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
queryCache: new QueryCache({
|
|
26
|
+
onError: (error) => {
|
|
27
|
+
toast.error(error.message);
|
|
28
|
+
}
|
|
29
|
+
})
|
|
30
|
+
})
|
|
31
|
+
);
|
|
32
|
+
return /* @__PURE__ */ React.createElement(QueryClientProvider, { client: queryClient }, children, /* @__PURE__ */ React.createElement(ReactQueryDevtools, { initialIsOpen: false }));
|
|
33
|
+
}
|
|
34
|
+
export {
|
|
35
|
+
QueryProvider
|
|
36
|
+
};
|
|
37
|
+
//# sourceMappingURL=query.provider.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/providers/query.provider.tsx"],"sourcesContent":["\"use client\";\r\n\r\nimport {\r\n QueryCache,\r\n QueryClient,\r\n QueryClientProvider,\r\n} from \"@tanstack/react-query\";\r\nimport { ReactNode, useState } from \"react\";\r\nimport dynamic from \"next/dynamic\";\r\nimport { toast } from \"sonner\";\r\n\r\n// React Query Devtools só em desenvolvimento - remove do bundle de produção\r\nconst ReactQueryDevtools =\r\n process.env.NODE_ENV === \"development\"\r\n ? dynamic(\r\n () =>\r\n import(\"@tanstack/react-query-devtools\").then((mod) => ({\r\n default: mod.ReactQueryDevtools,\r\n })),\r\n { ssr: false },\r\n )\r\n : () => null;\r\n\r\ninterface QueryProviderProps {\r\n children: ReactNode;\r\n}\r\n\r\nexport function QueryProvider({ children }: QueryProviderProps) {\r\n const [queryClient] = useState(\r\n () =>\r\n new QueryClient({\r\n defaultOptions: {\r\n queries: {\r\n staleTime: 60 * 1000,\r\n refetchOnWindowFocus: false,\r\n },\r\n },\r\n queryCache: new QueryCache({\r\n onError: (error) => {\r\n toast.error(error.message);\r\n },\r\n }),\r\n }),\r\n );\r\n\r\n return (\r\n <QueryClientProvider client={queryClient}>\r\n {children}\r\n <ReactQueryDevtools initialIsOpen={false} />\r\n </QueryClientProvider>\r\n );\r\n}\r\n"],"mappings":";AAEA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAoB,gBAAgB;AACpC,OAAO,aAAa;AACpB,SAAS,aAAa;AAGtB,MAAM,qBACJ,QAAQ,IAAI,aAAa,gBACrB;AAAA,EACE,MACE,OAAO,gCAAgC,EAAE,KAAK,CAAC,SAAS;AAAA,IACtD,SAAS,IAAI;AAAA,EACf,EAAE;AAAA,EACJ,EAAE,KAAK,MAAM;AACf,IACA,MAAM;AAML,SAAS,cAAc,EAAE,SAAS,GAAuB;AAC9D,QAAM,CAAC,WAAW,IAAI;AAAA,IACpB,MACE,IAAI,YAAY;AAAA,MACd,gBAAgB;AAAA,QACd,SAAS;AAAA,UACP,WAAW,KAAK;AAAA,UAChB,sBAAsB;AAAA,QACxB;AAAA,MACF;AAAA,MACA,YAAY,IAAI,WAAW;AAAA,QACzB,SAAS,CAAC,UAAU;AAClB,gBAAM,MAAM,MAAM,OAAO;AAAA,QAC3B;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAAA,EACL;AAEA,SACE,oCAAC,uBAAoB,QAAQ,eAC1B,UACD,oCAAC,sBAAmB,eAAe,OAAO,CAC5C;AAEJ;","names":[]}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { createContext, useContext } from "react";
|
|
3
|
+
const WhitelabelContext = createContext(
|
|
4
|
+
void 0
|
|
5
|
+
);
|
|
6
|
+
function WhitelabelProvider({
|
|
7
|
+
children,
|
|
8
|
+
whitelabel
|
|
9
|
+
}) {
|
|
10
|
+
return /* @__PURE__ */ React.createElement(
|
|
11
|
+
WhitelabelContext.Provider,
|
|
12
|
+
{
|
|
13
|
+
value: {
|
|
14
|
+
whitelabel
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
children
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
function useWhitelabel() {
|
|
21
|
+
const context = useContext(WhitelabelContext);
|
|
22
|
+
if (context === void 0) {
|
|
23
|
+
throw new Error(
|
|
24
|
+
"useWhitelabel deve ser usado dentro de um WhitelabelProvider"
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
return context;
|
|
28
|
+
}
|
|
29
|
+
export {
|
|
30
|
+
WhitelabelProvider,
|
|
31
|
+
useWhitelabel
|
|
32
|
+
};
|
|
33
|
+
//# sourceMappingURL=whitelabel.provider.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/providers/whitelabel.provider.tsx"],"sourcesContent":["\"use client\";\r\n\r\nimport { createContext, ReactNode, useContext } from \"react\";\r\nimport { WhitelabelData } from \"../modules/whitelabel/schema\";\r\n\r\ninterface WhitelabelContextProps {\r\n whitelabel: WhitelabelData | null;\r\n}\r\n\r\nconst WhitelabelContext = createContext<WhitelabelContextProps | undefined>(\r\n undefined,\r\n);\r\n\r\ninterface WhitelabelProviderProps {\r\n children: ReactNode;\r\n whitelabel: WhitelabelData | null;\r\n}\r\n\r\nexport function WhitelabelProvider({\r\n children,\r\n whitelabel,\r\n}: WhitelabelProviderProps) {\r\n return (\r\n <WhitelabelContext.Provider\r\n value={{\r\n whitelabel,\r\n }}\r\n >\r\n {children}\r\n </WhitelabelContext.Provider>\r\n );\r\n}\r\n\r\nexport function useWhitelabel(): WhitelabelContextProps {\r\n const context = useContext(WhitelabelContext);\r\n\r\n if (context === undefined) {\r\n throw new Error(\r\n \"useWhitelabel deve ser usado dentro de um WhitelabelProvider\",\r\n );\r\n }\r\n\r\n return context;\r\n}\r\n"],"mappings":";AAEA,SAAS,eAA0B,kBAAkB;AAOrD,MAAM,oBAAoB;AAAA,EACxB;AACF;AAOO,SAAS,mBAAmB;AAAA,EACjC;AAAA,EACA;AACF,GAA4B;AAC1B,SACE;AAAA,IAAC,kBAAkB;AAAA,IAAlB;AAAA,MACC,OAAO;AAAA,QACL;AAAA,MACF;AAAA;AAAA,IAEC;AAAA,EACH;AAEJ;AAEO,SAAS,gBAAwC;AACtD,QAAM,UAAU,WAAW,iBAAiB;AAE5C,MAAI,YAAY,QAAW;AACzB,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;","names":[]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { create } from "zustand";
|
|
2
|
+
const useMdSidebarStore = create((set) => ({
|
|
3
|
+
isExpanded: false,
|
|
4
|
+
toggle: () => set((state) => ({ isExpanded: !state.isExpanded })),
|
|
5
|
+
expand: () => set({ isExpanded: true }),
|
|
6
|
+
collapse: () => set({ isExpanded: false })
|
|
7
|
+
}));
|
|
8
|
+
export {
|
|
9
|
+
useMdSidebarStore
|
|
10
|
+
};
|
|
11
|
+
//# sourceMappingURL=useMdSidebarStore.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/store/useMdSidebarStore.ts"],"sourcesContent":["import { create } from \"zustand\";\r\n\r\ntype MdSidebarStore = {\r\n isExpanded: boolean;\r\n toggle: () => void;\r\n expand: () => void;\r\n collapse: () => void;\r\n};\r\n\r\nexport const useMdSidebarStore = create<MdSidebarStore>((set) => ({\r\n isExpanded: false,\r\n toggle: () => set((state) => ({ isExpanded: !state.isExpanded })),\r\n expand: () => set({ isExpanded: true }),\r\n collapse: () => set({ isExpanded: false }),\r\n}));\r\n"],"mappings":"AAAA,SAAS,cAAc;AAShB,MAAM,oBAAoB,OAAuB,CAAC,SAAS;AAAA,EAC9D,YAAY;AAAA,EACZ,QAAQ,MAAM,IAAI,CAAC,WAAW,EAAE,YAAY,CAAC,MAAM,WAAW,EAAE;AAAA,EAChE,QAAQ,MAAM,IAAI,EAAE,YAAY,KAAK,CAAC;AAAA,EACtC,UAAU,MAAM,IAAI,EAAE,YAAY,MAAM,CAAC;AAC7C,EAAE;","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@greatapps/common",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Shared library for GreatApps frontend applications",
|
|
5
|
+
"main": "./dist/index.mjs",
|
|
6
|
+
"types": "./src/index.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"import": "./dist/index.mjs",
|
|
10
|
+
"types": "./src/index.ts"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"files": ["dist", "src"],
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "tsup",
|
|
16
|
+
"dev": "tsup --watch",
|
|
17
|
+
"typecheck": "tsc --noEmit"
|
|
18
|
+
},
|
|
19
|
+
"keywords": [],
|
|
20
|
+
"author": "",
|
|
21
|
+
"license": "ISC",
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"@greatapps/cache": "^2.0.1",
|
|
24
|
+
"@radix-ui/react-accordion": "^1.2.12",
|
|
25
|
+
"@radix-ui/react-checkbox": "^1.3.3",
|
|
26
|
+
"@radix-ui/react-popover": "^1.1.15",
|
|
27
|
+
"@radix-ui/react-progress": "^1.1.8",
|
|
28
|
+
"@radix-ui/react-radio-group": "^1.3.8",
|
|
29
|
+
"@radix-ui/react-scroll-area": "^1.2.10",
|
|
30
|
+
"@radix-ui/react-separator": "^1.1.8",
|
|
31
|
+
"@radix-ui/react-switch": "^1.2.6",
|
|
32
|
+
"@radix-ui/react-tabs": "^1.1.13",
|
|
33
|
+
"@radix-ui/react-tooltip": "^1.2.8",
|
|
34
|
+
"axios": "^1.13.5",
|
|
35
|
+
"class-variance-authority": "^0.7.1",
|
|
36
|
+
"clsx": "^2.1.1",
|
|
37
|
+
"cmdk": "^1.1.1",
|
|
38
|
+
"date-fns": "^4.1.0",
|
|
39
|
+
"input-otp": "^1.4.2",
|
|
40
|
+
"lucide-react": "^0.575.0",
|
|
41
|
+
"react-day-picker": "^9.14.0",
|
|
42
|
+
"sonner": ">=2.0.0",
|
|
43
|
+
"tailwind-merge": "^3.5.0",
|
|
44
|
+
"zod": "^4.3.6"
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"@tanstack/react-query": "^5.90.5",
|
|
48
|
+
"@tanstack/react-query-devtools": "^5.90.2",
|
|
49
|
+
"@types/node": "^25.3.2",
|
|
50
|
+
"@types/react": "^19.2.14",
|
|
51
|
+
"@types/react-dom": "^19.2.3",
|
|
52
|
+
"glob": "^13.0.6",
|
|
53
|
+
"next": "15.5.9",
|
|
54
|
+
"react": "19.1.4",
|
|
55
|
+
"react-dom": "19.1.4",
|
|
56
|
+
"tsup": "^8.5.1",
|
|
57
|
+
"typescript": "^5.9.3",
|
|
58
|
+
"zustand": "^5.0.11"
|
|
59
|
+
},
|
|
60
|
+
"peerDependencies": {
|
|
61
|
+
"@tanstack/react-query": ">=5.0.0",
|
|
62
|
+
"next": ">=15.0.0",
|
|
63
|
+
"react": ">=19.0.0",
|
|
64
|
+
"react-dom": ">=19.0.0",
|
|
65
|
+
"sonner": ">=2.0.0",
|
|
66
|
+
"zustand": ">=4.0.0"
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { Suspense, useEffect } from "react";
|
|
4
|
+
import { useSearchParams } from "next/navigation";
|
|
5
|
+
|
|
6
|
+
interface SearchParamsHandlerProps {
|
|
7
|
+
handlers: {
|
|
8
|
+
[key: string]: () => void;
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* SearchParamsHandler
|
|
14
|
+
*
|
|
15
|
+
* Este componente é responsável por ler os parâmetros da URL e executar callbacks
|
|
16
|
+
* correspondentes a cada parâmetro encontrado.
|
|
17
|
+
*
|
|
18
|
+
* Por que precisamos deste componente?
|
|
19
|
+
* - O Next.js 16 exige que useSearchParams() seja envolvido em um <Suspense> boundary
|
|
20
|
+
* - Isso evita erros de prerendering durante o build
|
|
21
|
+
* - Permite que URLs como "/page?tab=performance" naveguem diretamente para uma aba específica
|
|
22
|
+
*
|
|
23
|
+
* Exemplo de como funciona
|
|
24
|
+
* 1. Usa useSearchParams() para ler o parâmetro "tab" da URL
|
|
25
|
+
* 2. Monitora mudanças nos parâmetros com useEffect
|
|
26
|
+
* 3. Quando encontra um parâmetro "tab", chama onTabChange com o valor
|
|
27
|
+
* 4. Retorna null porque não renderiza nada na tela
|
|
28
|
+
*
|
|
29
|
+
* Exemplo de uso:
|
|
30
|
+
* <Suspense fallback={null}>
|
|
31
|
+
* <SearchParamsHandler handlers={{ tab: () => console.log("Tab changed") }} />
|
|
32
|
+
* </Suspense>
|
|
33
|
+
*
|
|
34
|
+
* Exemplos de URL:
|
|
35
|
+
* - /greatpages/123?tab=performance → abre a aba "performance"
|
|
36
|
+
* - /greatpages/123?tab=leads → abre a aba "leads"
|
|
37
|
+
*/
|
|
38
|
+
export function SearchParamsHandler(options: SearchParamsHandlerProps) {
|
|
39
|
+
return (
|
|
40
|
+
<Suspense fallback={null}>
|
|
41
|
+
<SearchParamsHandlerChildren {...options} />
|
|
42
|
+
</Suspense>
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function SearchParamsHandlerChildren(options: SearchParamsHandlerProps) {
|
|
47
|
+
const searchParams = useSearchParams();
|
|
48
|
+
|
|
49
|
+
useEffect(() => {
|
|
50
|
+
Object.keys(options.handlers).forEach((key) => {
|
|
51
|
+
const value = searchParams.get(key);
|
|
52
|
+
|
|
53
|
+
if (value) {
|
|
54
|
+
options.handlers[key]();
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
58
|
+
}, [searchParams]);
|
|
59
|
+
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import * as React from "react"
|
|
4
|
+
import { cn } from "../../infra/utils/clsx"
|
|
5
|
+
|
|
6
|
+
function MainLayout({ className, children, ...props }: React.ComponentProps<"div">) {
|
|
7
|
+
return (
|
|
8
|
+
<div
|
|
9
|
+
data-slot="main-layout"
|
|
10
|
+
className={cn(
|
|
11
|
+
"h-dvh md:h-screen lg:h-screen flex flex-col md:flex-row lg:flex-row md:overflow-hidden lg:overflow-hidden",
|
|
12
|
+
className
|
|
13
|
+
)}
|
|
14
|
+
{...props}
|
|
15
|
+
>
|
|
16
|
+
{children}
|
|
17
|
+
</div>
|
|
18
|
+
)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function MainLayoutContent({ className, children, ...props }: React.ComponentProps<"div">) {
|
|
22
|
+
return (
|
|
23
|
+
<div
|
|
24
|
+
data-slot="main-layout-content"
|
|
25
|
+
className={cn("flex flex-col flex-1 min-h-0 md:overflow-hidden lg:overflow-hidden", className)}
|
|
26
|
+
{...props}
|
|
27
|
+
>
|
|
28
|
+
{children}
|
|
29
|
+
</div>
|
|
30
|
+
)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function MainLayoutSpacer({ className, height, ...props }: React.ComponentProps<"div"> & { height: string }) {
|
|
34
|
+
return (
|
|
35
|
+
<div
|
|
36
|
+
data-slot="main-layout-spacer"
|
|
37
|
+
className={cn("md:hidden lg:hidden shrink-0", className)}
|
|
38
|
+
style={{ height }}
|
|
39
|
+
{...props}
|
|
40
|
+
/>
|
|
41
|
+
)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function MainLayoutMain({ className, children, ...props }: React.ComponentProps<"main">) {
|
|
45
|
+
return (
|
|
46
|
+
<main
|
|
47
|
+
data-slot="main-layout-main"
|
|
48
|
+
className={cn(
|
|
49
|
+
"flex-1 min-h-0 overflow-y-auto overscroll-none md:overscroll-auto lg:overscroll-auto bg-(--color-base-light)",
|
|
50
|
+
className
|
|
51
|
+
)}
|
|
52
|
+
{...props}
|
|
53
|
+
>
|
|
54
|
+
{children}
|
|
55
|
+
</main>
|
|
56
|
+
)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export { MainLayout, MainLayoutContent, MainLayoutSpacer, MainLayoutMain }
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import * as React from "react"
|
|
4
|
+
import { useMdSidebarStore } from "../../store/useMdSidebarStore"
|
|
5
|
+
import { cn } from "../../infra/utils/clsx"
|
|
6
|
+
|
|
7
|
+
function MdSideBarNavigation({
|
|
8
|
+
className,
|
|
9
|
+
children,
|
|
10
|
+
...props
|
|
11
|
+
}: React.ComponentProps<"div">) {
|
|
12
|
+
const { isExpanded, collapse } = useMdSidebarStore()
|
|
13
|
+
|
|
14
|
+
return (
|
|
15
|
+
<>
|
|
16
|
+
<div
|
|
17
|
+
className={`hidden md:block lg:hidden fixed inset-0 bg-black/50 z-20 transition-opacity duration-300 ${
|
|
18
|
+
isExpanded ? "opacity-100" : "opacity-0 pointer-events-none"
|
|
19
|
+
}`}
|
|
20
|
+
onClick={collapse}
|
|
21
|
+
/>
|
|
22
|
+
<div
|
|
23
|
+
className={`hidden md:flex lg:hidden fixed top-0 bottom-0 left-[73px] z-30 transition-transform duration-300 ease-in-out overflow-visible ${
|
|
24
|
+
isExpanded ? "translate-x-0" : "-translate-x-full"
|
|
25
|
+
}`}
|
|
26
|
+
>
|
|
27
|
+
<div
|
|
28
|
+
data-slot="md-sidebar-navigation"
|
|
29
|
+
className={cn("w-[273px] h-full flex flex-col p-4 bg-white border-r border-gray-200", className)}
|
|
30
|
+
{...props}
|
|
31
|
+
>
|
|
32
|
+
{children}
|
|
33
|
+
</div>
|
|
34
|
+
</div>
|
|
35
|
+
</>
|
|
36
|
+
)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export { MdSideBarNavigation };
|