@greatapps/common 1.1.784 → 1.1.786
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/layouts/AppMobileNavBar.mjs +5 -64
- package/dist/components/layouts/AppMobileNavBar.mjs.map +1 -1
- package/dist/components/layouts/AppNavBar.mjs +0 -2
- package/dist/components/layouts/AppNavBar.mjs.map +1 -1
- package/dist/components/layouts/NavBar.mjs +52 -111
- package/dist/components/layouts/NavBar.mjs.map +1 -1
- package/dist/components/modals/cards/AddCardModal.mjs +3 -2
- package/dist/components/modals/cards/AddCardModal.mjs.map +1 -1
- package/dist/components/ui/form/PhoneInput.mjs +1 -1
- package/dist/components/ui/form/PhoneInput.mjs.map +1 -1
- package/dist/handlers.mjs +0 -2
- package/dist/handlers.mjs.map +1 -1
- package/dist/i18n/messages/en-us.mjs +1 -3
- package/dist/i18n/messages/en-us.mjs.map +1 -1
- package/dist/i18n/messages/es-es.mjs +1 -3
- package/dist/i18n/messages/es-es.mjs.map +1 -1
- package/dist/i18n/messages/pt-br.mjs +1 -3
- package/dist/i18n/messages/pt-br.mjs.map +1 -1
- package/dist/index.mjs +3 -10
- package/dist/index.mjs.map +1 -1
- package/dist/infra/api/client.mjs +1 -5
- package/dist/infra/api/client.mjs.map +1 -1
- package/dist/infra/api/types.mjs +1 -1
- package/dist/infra/api/types.mjs.map +1 -1
- package/dist/infra/route/safe-route-handler.mjs +1 -4
- package/dist/infra/route/safe-route-handler.mjs.map +1 -1
- package/dist/middlewares/create-auth-middleware.mjs +11 -1
- package/dist/middlewares/create-auth-middleware.mjs.map +1 -1
- package/dist/modules/auth/utils/assert-account-not-frozen.mjs +5 -6
- package/dist/modules/auth/utils/assert-account-not-frozen.mjs.map +1 -1
- package/dist/modules/auth/utils/assert-management-subscription.mjs +14 -7
- package/dist/modules/auth/utils/assert-management-subscription.mjs.map +1 -1
- package/dist/modules/auth/utils/assert-paid-subscription.mjs +12 -7
- package/dist/modules/auth/utils/assert-paid-subscription.mjs.map +1 -1
- package/dist/modules/auth/utils/assert-subscription-addon.mjs +10 -2
- package/dist/modules/auth/utils/assert-subscription-addon.mjs.map +1 -1
- package/dist/modules/plans/hooks/use-plan-by-id.hook.mjs.map +1 -1
- package/dist/modules/subscriptions/actions/update-subscription-payment.action.mjs.map +1 -1
- package/dist/modules/subscriptions/constants/subscription.constants.mjs +0 -2
- package/dist/modules/subscriptions/constants/subscription.constants.mjs.map +1 -1
- package/dist/modules/subscriptions/hooks/find-active-subscription.hook.mjs +13 -2
- package/dist/modules/subscriptions/hooks/find-active-subscription.hook.mjs.map +1 -1
- package/dist/modules/subscriptions/hooks/update-subscription-payment.hook.mjs +10 -2
- package/dist/modules/subscriptions/hooks/update-subscription-payment.hook.mjs.map +1 -1
- package/dist/modules/subscriptions/services/subscriptions.service.mjs +12 -27
- package/dist/modules/subscriptions/services/subscriptions.service.mjs.map +1 -1
- package/dist/modules/subscriptions/types/subscription.type.mjs.map +1 -1
- package/dist/modules/subscriptions/utils/has-active-paid-subscription.mjs +1 -1
- package/dist/modules/subscriptions/utils/has-active-paid-subscription.mjs.map +1 -1
- package/dist/modules/subscriptions/utils/has-paid-subscription.mjs +1 -1
- package/dist/modules/subscriptions/utils/has-paid-subscription.mjs.map +1 -1
- package/dist/modules/whitelabel/actions/find-whitelabel.action.mjs +9 -6
- package/dist/modules/whitelabel/actions/find-whitelabel.action.mjs.map +1 -1
- package/dist/modules/whitelabel/services/whitelabel.service.mjs +28 -2
- package/dist/modules/whitelabel/services/whitelabel.service.mjs.map +1 -1
- package/dist/providers/auth.provider.mjs +12 -9
- package/dist/providers/auth.provider.mjs.map +1 -1
- package/dist/server.mjs +0 -4
- package/dist/server.mjs.map +1 -1
- package/dist/store/useMdSidebarStore.mjs +4 -17
- package/dist/store/useMdSidebarStore.mjs.map +1 -1
- package/dist/utils/redirect.mjs +10 -0
- package/dist/utils/redirect.mjs.map +1 -1
- package/dist/utils/safeServerAction.mjs +1 -4
- package/dist/utils/safeServerAction.mjs.map +1 -1
- package/dist/utils/withAction.mjs +1 -2
- package/dist/utils/withAction.mjs.map +1 -1
- package/package.json +1 -1
- package/src/components/layouts/AppMobileNavBar.tsx +6 -90
- package/src/components/layouts/AppNavBar.tsx +1 -5
- package/src/components/layouts/NavBar.tsx +66 -160
- package/src/components/modals/cards/AddCardModal.tsx +15 -2
- package/src/components/ui/form/PhoneInput.tsx +1 -1
- package/src/handlers.ts +0 -1
- package/src/i18n/messages/en-us.ts +0 -2
- package/src/i18n/messages/es-es.ts +0 -2
- package/src/i18n/messages/pt-br.ts +0 -2
- package/src/index.ts +3 -8
- package/src/infra/api/client.ts +3 -11
- package/src/infra/api/types.ts +5 -7
- package/src/infra/route/safe-route-handler.ts +1 -4
- package/src/middlewares/create-auth-middleware.ts +12 -1
- package/src/modules/auth/utils/assert-account-not-frozen.ts +6 -7
- package/src/modules/auth/utils/assert-management-subscription.ts +23 -15
- package/src/modules/auth/utils/assert-paid-subscription.ts +15 -7
- package/src/modules/auth/utils/assert-subscription-addon.ts +12 -2
- package/src/modules/plans/hooks/use-plan-by-id.hook.ts +1 -1
- package/src/modules/subscriptions/actions/update-subscription-payment.action.ts +6 -1
- package/src/modules/subscriptions/constants/subscription.constants.ts +0 -3
- package/src/modules/subscriptions/hooks/find-active-subscription.hook.ts +17 -7
- package/src/modules/subscriptions/hooks/update-subscription-payment.hook.ts +21 -3
- package/src/modules/subscriptions/services/subscriptions.service.ts +46 -38
- package/src/modules/subscriptions/types/subscription.type.ts +27 -2
- package/src/modules/subscriptions/utils/has-active-paid-subscription.ts +2 -1
- package/src/modules/subscriptions/utils/has-paid-subscription.ts +2 -1
- package/src/modules/whitelabel/actions/find-whitelabel.action.ts +13 -9
- package/src/modules/whitelabel/services/whitelabel.service.ts +34 -2
- package/src/providers/auth.provider.tsx +13 -10
- package/src/server.ts +0 -2
- package/src/store/useMdSidebarStore.ts +5 -20
- package/src/utils/redirect.ts +10 -0
- package/src/utils/safeServerAction.ts +6 -4
- package/src/utils/withAction.ts +1 -2
- package/dist/components/layouts/GreatDomainIcon.mjs +0 -40
- package/dist/components/layouts/GreatDomainIcon.mjs.map +0 -1
- package/dist/modules/subscriptions/actions/get-current-subscription.action.mjs +0 -10
- package/dist/modules/subscriptions/actions/get-current-subscription.action.mjs.map +0 -1
- package/dist/modules/subscriptions/handlers/current-subscription.handler.mjs +0 -17
- package/dist/modules/subscriptions/handlers/current-subscription.handler.mjs.map +0 -1
- package/dist/modules/subscriptions/hooks/use-current-subscription.hook.mjs +0 -28
- package/dist/modules/subscriptions/hooks/use-current-subscription.hook.mjs.map +0 -1
- package/dist/modules/subscriptions/utils/group-subscriptions-by-product.mjs +0 -16
- package/dist/modules/subscriptions/utils/group-subscriptions-by-product.mjs.map +0 -1
- package/dist/modules/subscriptions/utils/read-current-subscription.mjs +0 -21
- package/dist/modules/subscriptions/utils/read-current-subscription.mjs.map +0 -1
- package/src/components/layouts/GreatDomainIcon.tsx +0 -43
- package/src/modules/subscriptions/actions/get-current-subscription.action.ts +0 -8
- package/src/modules/subscriptions/handlers/current-subscription.handler.ts +0 -16
- package/src/modules/subscriptions/hooks/use-current-subscription.hook.ts +0 -38
- package/src/modules/subscriptions/utils/group-subscriptions-by-product.ts +0 -23
- package/src/modules/subscriptions/utils/read-current-subscription.ts +0 -34
package/dist/server.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/server.ts"],"sourcesContent":["import 'server-only';\r\n\r\n// API Client\r\nexport { ApiClient, api, apiClient } from './infra/api/client';\r\n\r\n// Services\r\nexport { authService } from './modules/auth/services/auth.service';\r\nexport { whitelabelService } from './modules/whitelabel/services/whitelabel.service';\r\nexport { revalidateWhitelabelAction } from './modules/whitelabel/actions/revalidate-whitelabel.action';\r\nexport { assertManagementPermission } from './modules/auth/utils/assert-management-permission';\r\nexport { assertManagementSubscription } from './modules/auth/utils/assert-management-subscription';\r\nexport { assertSubscriptionAddon } from './modules/auth/utils/assert-subscription-addon';\r\nexport { assertPaidSubscription } from './modules/auth/utils/assert-paid-subscription';\r\nexport { assertAccountNotFrozen } from './modules/auth/utils/assert-account-not-frozen';\r\nexport { subscriptionsService } from './modules/subscriptions/services/subscriptions.service';\r\nexport { plansService } from './modules/plans/services/plans.service';\r\nexport { cardsService } from './modules/cards/services/cards.service';\r\nexport { chargesService } from './modules/charges/services/charges.service';\r\nexport { iaCreditsService } from './modules/ia-credits/services/ia-credits.service';\r\n\r\n// Actions\r\nexport { findWhitelabel } from './modules/whitelabel/actions/find-whitelabel.action';\r\nexport { validateSessionAction } from './modules/auth/actions/validate-session.action';\r\nexport { socialGoogleLoginAction } from './modules/auth/actions/social-google-login.action';\r\nexport { socialGoogleOnboardingAction } from './modules/auth/actions/social-google-onboarding.action';\r\nexport { unlinkGoogleAction } from './modules/auth/actions/unlink-google.action';\r\nexport { findUserById } from './modules/users/action/find-user-by-id.action';\r\nexport { findCurrentAccount } from './modules/accounts/actions/find-current-account.action';\r\nexport { getAccountTokenAction } from './modules/accounts/actions/get-account-token.action';\r\nexport { listSubscriptionsAction } from './modules/subscriptions/actions/list-subscriptions.action';\r\nexport {
|
|
1
|
+
{"version":3,"sources":["../src/server.ts"],"sourcesContent":["import 'server-only';\r\n\r\n// API Client\r\nexport { ApiClient, api, apiClient } from './infra/api/client';\r\n\r\n// Services\r\nexport { authService } from './modules/auth/services/auth.service';\r\nexport { whitelabelService } from './modules/whitelabel/services/whitelabel.service';\r\nexport { revalidateWhitelabelAction } from './modules/whitelabel/actions/revalidate-whitelabel.action';\r\nexport { assertManagementPermission } from './modules/auth/utils/assert-management-permission';\r\nexport { assertManagementSubscription } from './modules/auth/utils/assert-management-subscription';\r\nexport { assertSubscriptionAddon } from './modules/auth/utils/assert-subscription-addon';\r\nexport { assertPaidSubscription } from './modules/auth/utils/assert-paid-subscription';\r\nexport { assertAccountNotFrozen } from './modules/auth/utils/assert-account-not-frozen';\r\nexport { subscriptionsService } from './modules/subscriptions/services/subscriptions.service';\r\nexport { plansService } from './modules/plans/services/plans.service';\r\nexport { cardsService } from './modules/cards/services/cards.service';\r\nexport { chargesService } from './modules/charges/services/charges.service';\r\nexport { iaCreditsService } from './modules/ia-credits/services/ia-credits.service';\r\n\r\n// Actions\r\nexport { findWhitelabel } from './modules/whitelabel/actions/find-whitelabel.action';\r\nexport { validateSessionAction } from './modules/auth/actions/validate-session.action';\r\nexport { socialGoogleLoginAction } from './modules/auth/actions/social-google-login.action';\r\nexport { socialGoogleOnboardingAction } from './modules/auth/actions/social-google-onboarding.action';\r\nexport { unlinkGoogleAction } from './modules/auth/actions/unlink-google.action';\r\nexport { findUserById } from './modules/users/action/find-user-by-id.action';\r\nexport { findCurrentAccount } from './modules/accounts/actions/find-current-account.action';\r\nexport { getAccountTokenAction } from './modules/accounts/actions/get-account-token.action';\r\nexport { listSubscriptionsAction } from './modules/subscriptions/actions/list-subscriptions.action';\r\nexport { ackFreezeNoticeAction } from './modules/subscriptions/actions/ack-freeze-notice.action';\r\nexport { calculateSubscriptionAction } from './modules/subscriptions/actions/calculate-subscription.action';\r\nexport { updateSubscriptionPlanAction } from './modules/subscriptions/actions/update-subscription-plan.action';\r\nexport { updateSubscriptionPaymentAction } from './modules/subscriptions/actions/update-subscription-payment.action';\r\nexport { createCardAction } from './modules/cards/actions/create-card.action';\r\nexport { createSetupIntentAction } from './modules/cards/actions/create-setup-intent.action';\r\nexport { chargeActionAction } from './modules/charges/actions/charge-action.action';\r\nexport { resolvePlanExtrasPrices } from './modules/subscriptions/utils/resolve-plan-extras-prices';\r\nexport { hasSubscriptionExpired } from './modules/subscriptions/utils/has-subscription-expired';\r\nexport { hasActivePaidSubscription } from './modules/subscriptions/utils/has-active-paid-subscription';\r\n\r\n// Project Services & Actions (server-only)\r\nexport { projectsService } from './modules/projects/services/projects.service';\r\nexport { listProjectsAction } from './modules/projects/actions/list-projects.action';\r\nexport { findProjectAction } from './modules/projects/actions/find-project.action';\r\nexport { createProjectAction } from './modules/projects/actions/create-project.action';\r\nexport { updateProjectAction } from './modules/projects/actions/update-project.action';\r\nexport { deleteProjectAction } from './modules/projects/actions/delete-project.action';\r\n\r\n// Project Users Services & Actions (server-only)\r\nexport { projectUsersService } from './modules/projects/services/project-users.service';\r\nexport { listProjectUsersAction } from './modules/projects/actions/list-project-users.action';\r\nexport { addProjectUserAction } from './modules/projects/actions/add-project-user.action';\r\nexport { removeProjectUserAction } from './modules/projects/actions/remove-project-user.action';\r\n\r\n// Account Services & Actions (server-only)\r\nexport { accountService } from './modules/accounts/services/account.service';\r\nexport { twoFactorService } from './modules/accounts/services/two-factor.service';\r\nexport {\r\n listAccountUsersAction,\r\n updateUserAction,\r\n updateAccountAction,\r\n updateAccountUserByIdAction,\r\n updateBillingDataAction,\r\n deleteAccountUserAction,\r\n deleteAccountAction,\r\n createAccountUserAction,\r\n changePasswordAction,\r\n requestEmailChangeAction,\r\n confirmEmailChangeAction,\r\n requestPhoneChangeAction,\r\n confirmPhoneChangeAction,\r\n generateTwoFactorAction,\r\n confirmTwoFactorAction,\r\n disableTwoFactorAction,\r\n} from './modules/accounts/actions/account-management.action';\r\n\r\n// Server Utils\r\nexport { getClientInfoFromRequest } from './infra/utils/client-info';\r\nexport { getUserContext } from './modules/auth/utils/get-user-context';\r\nexport { resolveLocale } from './i18n/resolve-locale';\r\nexport type { ResolveLocaleOptions } from './i18n/resolve-locale';\r\nexport { requireValidSession } from './modules/auth/utils/require-valid-session';\r\nexport { requireTokenNotExpired } from './modules/auth/utils/require-token-not-expired';\r\nexport { buildWlOverride, buildWlOverrideFromJwt } from './modules/auth/utils/build-wl-override';\r\nexport { safeServerAction } from './utils/safeServerAction';\r\nexport { safeMutationAction } from './utils/safeMutationAction';\r\n\r\n// Image Processing (server-side)\r\nexport { processImageAction } from './modules/images/actions/process-image.action';\r\nexport { processImage } from './modules/images/services/image-processing.service';\r\nexport type {\r\n ProcessImageInput,\r\n ProcessImageOutput,\r\n ProcessImageActionInput,\r\n ProcessImageActionOutput,\r\n} from './modules/images/types/image.type';\r\n"],"mappings":"AAAA,OAAO;AAGP,SAAS,WAAW,KAAK,iBAAiB;AAG1C,SAAS,mBAAmB;AAC5B,SAAS,yBAAyB;AAClC,SAAS,kCAAkC;AAC3C,SAAS,kCAAkC;AAC3C,SAAS,oCAAoC;AAC7C,SAAS,+BAA+B;AACxC,SAAS,8BAA8B;AACvC,SAAS,8BAA8B;AACvC,SAAS,4BAA4B;AACrC,SAAS,oBAAoB;AAC7B,SAAS,oBAAoB;AAC7B,SAAS,sBAAsB;AAC/B,SAAS,wBAAwB;AAGjC,SAAS,sBAAsB;AAC/B,SAAS,6BAA6B;AACtC,SAAS,+BAA+B;AACxC,SAAS,oCAAoC;AAC7C,SAAS,0BAA0B;AACnC,SAAS,oBAAoB;AAC7B,SAAS,0BAA0B;AACnC,SAAS,6BAA6B;AACtC,SAAS,+BAA+B;AACxC,SAAS,6BAA6B;AACtC,SAAS,mCAAmC;AAC5C,SAAS,oCAAoC;AAC7C,SAAS,uCAAuC;AAChD,SAAS,wBAAwB;AACjC,SAAS,+BAA+B;AACxC,SAAS,0BAA0B;AACnC,SAAS,+BAA+B;AACxC,SAAS,8BAA8B;AACvC,SAAS,iCAAiC;AAG1C,SAAS,uBAAuB;AAChC,SAAS,0BAA0B;AACnC,SAAS,yBAAyB;AAClC,SAAS,2BAA2B;AACpC,SAAS,2BAA2B;AACpC,SAAS,2BAA2B;AAGpC,SAAS,2BAA2B;AACpC,SAAS,8BAA8B;AACvC,SAAS,4BAA4B;AACrC,SAAS,+BAA+B;AAGxC,SAAS,sBAAsB;AAC/B,SAAS,wBAAwB;AACjC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAGP,SAAS,gCAAgC;AACzC,SAAS,sBAAsB;AAC/B,SAAS,qBAAqB;AAE9B,SAAS,2BAA2B;AACpC,SAAS,8BAA8B;AACvC,SAAS,iBAAiB,8BAA8B;AACxD,SAAS,wBAAwB;AACjC,SAAS,0BAA0B;AAGnC,SAAS,0BAA0B;AACnC,SAAS,oBAAoB;","names":[]}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { create } from "zustand";
|
|
2
|
-
import { useEffect } from "react";
|
|
3
2
|
import { readStorage, writeStorage } from "../utils/browser/safe-storage";
|
|
4
3
|
const STORAGE_KEY = "md-sidebar-expanded";
|
|
4
|
+
function getInitialState() {
|
|
5
|
+
return readStorage(STORAGE_KEY) === "true";
|
|
6
|
+
}
|
|
5
7
|
const useMdSidebarStore = create((set) => ({
|
|
6
|
-
isExpanded:
|
|
7
|
-
_hydrated: false,
|
|
8
|
+
isExpanded: getInitialState(),
|
|
8
9
|
toggle: () => set((state) => {
|
|
9
10
|
const next = !state.isExpanded;
|
|
10
11
|
writeStorage(STORAGE_KEY, String(next));
|
|
@@ -17,23 +18,9 @@ const useMdSidebarStore = create((set) => ({
|
|
|
17
18
|
collapse: () => {
|
|
18
19
|
writeStorage(STORAGE_KEY, "false");
|
|
19
20
|
return set({ isExpanded: false });
|
|
20
|
-
},
|
|
21
|
-
_hydrate: () => {
|
|
22
|
-
const value = readStorage(STORAGE_KEY) === "true";
|
|
23
|
-
set({ isExpanded: value, _hydrated: true });
|
|
24
21
|
}
|
|
25
22
|
}));
|
|
26
|
-
function useMdSidebarHydration() {
|
|
27
|
-
const hydrate = useMdSidebarStore((s) => s._hydrate);
|
|
28
|
-
const hydrated = useMdSidebarStore((s) => s._hydrated);
|
|
29
|
-
useEffect(() => {
|
|
30
|
-
if (!hydrated) {
|
|
31
|
-
hydrate();
|
|
32
|
-
}
|
|
33
|
-
}, [hydrate, hydrated]);
|
|
34
|
-
}
|
|
35
23
|
export {
|
|
36
|
-
useMdSidebarHydration,
|
|
37
24
|
useMdSidebarStore
|
|
38
25
|
};
|
|
39
26
|
//# sourceMappingURL=useMdSidebarStore.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/store/useMdSidebarStore.ts"],"sourcesContent":["import { create } from \"zustand\";\nimport {
|
|
1
|
+
{"version":3,"sources":["../../src/store/useMdSidebarStore.ts"],"sourcesContent":["import { create } from \"zustand\";\nimport { readStorage, writeStorage } from \"../utils/browser/safe-storage\";\n\nconst STORAGE_KEY = \"md-sidebar-expanded\";\n\nfunction getInitialState(): boolean {\n return readStorage(STORAGE_KEY) === \"true\";\n}\n\ntype MdSidebarStore = {\n isExpanded: boolean;\n toggle: () => void;\n expand: () => void;\n collapse: () => void;\n};\n\nexport const useMdSidebarStore = create<MdSidebarStore>((set) => ({\n isExpanded: getInitialState(),\n toggle: () => set((state) => {\n const next = !state.isExpanded;\n writeStorage(STORAGE_KEY, String(next));\n return { isExpanded: next };\n }),\n expand: () => {\n writeStorage(STORAGE_KEY, \"true\");\n return set({ isExpanded: true });\n },\n collapse: () => {\n writeStorage(STORAGE_KEY, \"false\");\n return set({ isExpanded: false });\n },\n}));\n"],"mappings":"AAAA,SAAS,cAAc;AACvB,SAAS,aAAa,oBAAoB;AAE1C,MAAM,cAAc;AAEpB,SAAS,kBAA2B;AAChC,SAAO,YAAY,WAAW,MAAM;AACxC;AASO,MAAM,oBAAoB,OAAuB,CAAC,SAAS;AAAA,EAC9D,YAAY,gBAAgB;AAAA,EAC5B,QAAQ,MAAM,IAAI,CAAC,UAAU;AACzB,UAAM,OAAO,CAAC,MAAM;AACpB,iBAAa,aAAa,OAAO,IAAI,CAAC;AACtC,WAAO,EAAE,YAAY,KAAK;AAAA,EAC9B,CAAC;AAAA,EACD,QAAQ,MAAM;AACV,iBAAa,aAAa,MAAM;AAChC,WAAO,IAAI,EAAE,YAAY,KAAK,CAAC;AAAA,EACnC;AAAA,EACA,UAAU,MAAM;AACZ,iBAAa,aAAa,OAAO;AACjC,WAAO,IAAI,EAAE,YAAY,MAAM,CAAC;AAAA,EACpC;AACJ,EAAE;","names":[]}
|
package/dist/utils/redirect.mjs
CHANGED
|
@@ -13,6 +13,15 @@ function resolveSafeRedirect(redirect, currentHostname, fallback) {
|
|
|
13
13
|
if (!isSameSite(url.hostname, currentHostname)) return fallback;
|
|
14
14
|
return url.toString();
|
|
15
15
|
}
|
|
16
|
+
function isSameSiteUrl(target, currentHost) {
|
|
17
|
+
let hostname;
|
|
18
|
+
try {
|
|
19
|
+
hostname = new URL(target).hostname;
|
|
20
|
+
} catch {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
return isSameSite(hostname, currentHost.split(":")[0]);
|
|
24
|
+
}
|
|
16
25
|
function isSameSite(target, current) {
|
|
17
26
|
const host = target.toLowerCase();
|
|
18
27
|
const base = baseDomain(current.toLowerCase());
|
|
@@ -34,6 +43,7 @@ function sameHostOr(candidate, host, fallback) {
|
|
|
34
43
|
}
|
|
35
44
|
}
|
|
36
45
|
export {
|
|
46
|
+
isSameSiteUrl,
|
|
37
47
|
resolveSafeRedirect,
|
|
38
48
|
sameHostOr
|
|
39
49
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/redirect.ts"],"sourcesContent":["/**\n * Resolve o destino pós-login com proteção contra open redirect.\n *\n * Só aceita o `redirect` recebido na query quando ele aponta para o MESMO site do\n * accounts onde o usuário está — mesmo domínio-base, qualquer subdomínio. Em\n * `accounts.greatpages.com.br` libera `*.greatpages.com.br` (editor-new, editor, app…);\n * num whitelabel em `accounts.marca.com.br` libera `*.marca.com.br`. Qualquer outro host\n * (`evil.com`, `greatpages.com.br.evil.com`) cai no `fallback`.\n *\n * `currentHostname` é o host do accounts (`window.location.hostname`). O accounts vive\n * sempre num subdomínio de 1 nível (`accounts.` / `acc.` / `great-accounts.`), então o\n * domínio-base é o host sem o primeiro rótulo.\n */\nexport function resolveSafeRedirect(\n redirect: string | null | undefined,\n currentHostname: string,\n fallback: string,\n): string {\n if (!redirect) return fallback;\n\n // path relativo same-origin — uma barra só (bloqueia `//evil.com` e `/\\evil.com`)\n if (redirect[0] === '/' && redirect[1] !== '/' && redirect[1] !== '\\\\') {\n return redirect;\n }\n\n let url: URL;\n try {\n url = new URL(redirect);\n } catch {\n return fallback;\n }\n\n if (url.protocol !== 'https:' && url.protocol !== 'http:') return fallback;\n if (!isSameSite(url.hostname, currentHostname)) return fallback;\n\n return url.toString();\n}\n\nfunction isSameSite(target: string, current: string): boolean {\n const host = target.toLowerCase();\n const base = baseDomain(current.toLowerCase());\n return host === base || host.endsWith(`.${base}`);\n}\n\n// Sufixos públicos de 2 rótulos (não há PSL completa aqui — só os que aparecem nos domínios\n// dos whitelabels). Um host terminando num destes tem o domínio registrável com 1 rótulo a mais.\nconst TWO_LABEL_PUBLIC_SUFFIXES = ['com.br', 'net.br', 'org.br', 'dev.br', 'app.br', 'co.uk', 'com.mx', 'com.ar'];\n\nfunction baseDomain(host: string): string {\n const labels = host.split('.');\n const publicSuffix = TWO_LABEL_PUBLIC_SUFFIXES.find((s) => host === s || host.endsWith(`.${s}`));\n // Domínio registrável = nº de rótulos do sufixo + 1 (ex.: `x.com.br` = 3; `x.app` = 2).\n const registrableLabels = (publicSuffix ? publicSuffix.split('.').length : 1) + 1;\n // accounts está sempre num subdomínio de 1 nível → base = host sem o 1º rótulo. Mas nunca\n // reduz até o domínio registrável ou abaixo (senão `greatpages.com.br` viraria `com.br` e\n // liberaria qualquer `*.com.br` — open redirect). Nesse caso exige host exato.\n return labels.length > registrableLabels ? labels.slice(1).join('.') : host;\n}\n\n/**\n * Devolve `candidate` apenas se ele for uma URL do MESMO host; senão o `fallback`.\n *\n * Usado no bounce do `/login` de cada app (editor, pages…), que recebe no param a URL\n * absoluta da própria página de origem e a repassa ao accounts — match exato de host\n * porque o destino esperado é o do próprio app.\n */\nexport function sameHostOr(\n candidate: string | undefined,\n host: string,\n fallback: string,\n): string {\n if (!candidate) return fallback;\n try {\n return new URL(candidate).host === host ? candidate : fallback;\n } catch {\n return fallback;\n }\n}\n"],"mappings":"AAaO,SAAS,oBACd,UACA,iBACA,UACQ;AACR,MAAI,CAAC,SAAU,QAAO;AAGtB,MAAI,SAAS,CAAC,MAAM,OAAO,SAAS,CAAC,MAAM,OAAO,SAAS,CAAC,MAAM,MAAM;AACtE,WAAO;AAAA,EACT;AAEA,MAAI;AACJ,MAAI;AACF,UAAM,IAAI,IAAI,QAAQ;AAAA,EACxB,QAAQ;AACN,WAAO;AAAA,EACT;AAEA,MAAI,IAAI,aAAa,YAAY,IAAI,aAAa,QAAS,QAAO;AAClE,MAAI,CAAC,WAAW,IAAI,UAAU,eAAe,EAAG,QAAO;AAEvD,SAAO,IAAI,SAAS;AACtB;AAEA,SAAS,WAAW,QAAgB,SAA0B;AAC5D,QAAM,OAAO,OAAO,YAAY;AAChC,QAAM,OAAO,WAAW,QAAQ,YAAY,CAAC;AAC7C,SAAO,SAAS,QAAQ,KAAK,SAAS,IAAI,IAAI,EAAE;AAClD;AAIA,MAAM,4BAA4B,CAAC,UAAU,UAAU,UAAU,UAAU,UAAU,SAAS,UAAU,QAAQ;AAEhH,SAAS,WAAW,MAAsB;AACxC,QAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,QAAM,eAAe,0BAA0B,KAAK,CAAC,MAAM,SAAS,KAAK,KAAK,SAAS,IAAI,CAAC,EAAE,CAAC;AAE/F,QAAM,qBAAqB,eAAe,aAAa,MAAM,GAAG,EAAE,SAAS,KAAK;AAIhF,SAAO,OAAO,SAAS,oBAAoB,OAAO,MAAM,CAAC,EAAE,KAAK,GAAG,IAAI;AACzE;AASO,SAAS,WACd,WACA,MACA,UACQ;AACR,MAAI,CAAC,UAAW,QAAO;AACvB,MAAI;AACF,WAAO,IAAI,IAAI,SAAS,EAAE,SAAS,OAAO,YAAY;AAAA,EACxD,QAAQ;AACN,WAAO;AAAA,EACT;AACF;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/utils/redirect.ts"],"sourcesContent":["/**\n * Resolve o destino pós-login com proteção contra open redirect.\n *\n * Só aceita o `redirect` recebido na query quando ele aponta para o MESMO site do\n * accounts onde o usuário está — mesmo domínio-base, qualquer subdomínio. Em\n * `accounts.greatpages.com.br` libera `*.greatpages.com.br` (editor-new, editor, app…);\n * num whitelabel em `accounts.marca.com.br` libera `*.marca.com.br`. Qualquer outro host\n * (`evil.com`, `greatpages.com.br.evil.com`) cai no `fallback`.\n *\n * `currentHostname` é o host do accounts (`window.location.hostname`). O accounts vive\n * sempre num subdomínio de 1 nível (`accounts.` / `acc.` / `great-accounts.`), então o\n * domínio-base é o host sem o primeiro rótulo.\n */\nexport function resolveSafeRedirect(\n redirect: string | null | undefined,\n currentHostname: string,\n fallback: string,\n): string {\n if (!redirect) return fallback;\n\n // path relativo same-origin — uma barra só (bloqueia `//evil.com` e `/\\evil.com`)\n if (redirect[0] === '/' && redirect[1] !== '/' && redirect[1] !== '\\\\') {\n return redirect;\n }\n\n let url: URL;\n try {\n url = new URL(redirect);\n } catch {\n return fallback;\n }\n\n if (url.protocol !== 'https:' && url.protocol !== 'http:') return fallback;\n if (!isSameSite(url.hostname, currentHostname)) return fallback;\n\n return url.toString();\n}\n\nexport function isSameSiteUrl(target: string, currentHost: string): boolean {\n let hostname: string;\n try {\n hostname = new URL(target).hostname;\n } catch {\n return false;\n }\n return isSameSite(hostname, currentHost.split(':')[0]);\n}\n\nfunction isSameSite(target: string, current: string): boolean {\n const host = target.toLowerCase();\n const base = baseDomain(current.toLowerCase());\n return host === base || host.endsWith(`.${base}`);\n}\n\n// Sufixos públicos de 2 rótulos (não há PSL completa aqui — só os que aparecem nos domínios\n// dos whitelabels). Um host terminando num destes tem o domínio registrável com 1 rótulo a mais.\nconst TWO_LABEL_PUBLIC_SUFFIXES = ['com.br', 'net.br', 'org.br', 'dev.br', 'app.br', 'co.uk', 'com.mx', 'com.ar'];\n\nfunction baseDomain(host: string): string {\n const labels = host.split('.');\n const publicSuffix = TWO_LABEL_PUBLIC_SUFFIXES.find((s) => host === s || host.endsWith(`.${s}`));\n // Domínio registrável = nº de rótulos do sufixo + 1 (ex.: `x.com.br` = 3; `x.app` = 2).\n const registrableLabels = (publicSuffix ? publicSuffix.split('.').length : 1) + 1;\n // accounts está sempre num subdomínio de 1 nível → base = host sem o 1º rótulo. Mas nunca\n // reduz até o domínio registrável ou abaixo (senão `greatpages.com.br` viraria `com.br` e\n // liberaria qualquer `*.com.br` — open redirect). Nesse caso exige host exato.\n return labels.length > registrableLabels ? labels.slice(1).join('.') : host;\n}\n\n/**\n * Devolve `candidate` apenas se ele for uma URL do MESMO host; senão o `fallback`.\n *\n * Usado no bounce do `/login` de cada app (editor, pages…), que recebe no param a URL\n * absoluta da própria página de origem e a repassa ao accounts — match exato de host\n * porque o destino esperado é o do próprio app.\n */\nexport function sameHostOr(\n candidate: string | undefined,\n host: string,\n fallback: string,\n): string {\n if (!candidate) return fallback;\n try {\n return new URL(candidate).host === host ? candidate : fallback;\n } catch {\n return fallback;\n }\n}\n"],"mappings":"AAaO,SAAS,oBACd,UACA,iBACA,UACQ;AACR,MAAI,CAAC,SAAU,QAAO;AAGtB,MAAI,SAAS,CAAC,MAAM,OAAO,SAAS,CAAC,MAAM,OAAO,SAAS,CAAC,MAAM,MAAM;AACtE,WAAO;AAAA,EACT;AAEA,MAAI;AACJ,MAAI;AACF,UAAM,IAAI,IAAI,QAAQ;AAAA,EACxB,QAAQ;AACN,WAAO;AAAA,EACT;AAEA,MAAI,IAAI,aAAa,YAAY,IAAI,aAAa,QAAS,QAAO;AAClE,MAAI,CAAC,WAAW,IAAI,UAAU,eAAe,EAAG,QAAO;AAEvD,SAAO,IAAI,SAAS;AACtB;AAEO,SAAS,cAAc,QAAgB,aAA8B;AAC1E,MAAI;AACJ,MAAI;AACF,eAAW,IAAI,IAAI,MAAM,EAAE;AAAA,EAC7B,QAAQ;AACN,WAAO;AAAA,EACT;AACA,SAAO,WAAW,UAAU,YAAY,MAAM,GAAG,EAAE,CAAC,CAAC;AACvD;AAEA,SAAS,WAAW,QAAgB,SAA0B;AAC5D,QAAM,OAAO,OAAO,YAAY;AAChC,QAAM,OAAO,WAAW,QAAQ,YAAY,CAAC;AAC7C,SAAO,SAAS,QAAQ,KAAK,SAAS,IAAI,IAAI,EAAE;AAClD;AAIA,MAAM,4BAA4B,CAAC,UAAU,UAAU,UAAU,UAAU,UAAU,SAAS,UAAU,QAAQ;AAEhH,SAAS,WAAW,MAAsB;AACxC,QAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,QAAM,eAAe,0BAA0B,KAAK,CAAC,MAAM,SAAS,KAAK,KAAK,SAAS,IAAI,CAAC,EAAE,CAAC;AAE/F,QAAM,qBAAqB,eAAe,aAAa,MAAM,GAAG,EAAE,SAAS,KAAK;AAIhF,SAAO,OAAO,SAAS,oBAAoB,OAAO,MAAM,CAAC,EAAE,KAAK,GAAG,IAAI;AACzE;AASO,SAAS,WACd,WACA,MACA,UACQ;AACR,MAAI,CAAC,UAAW,QAAO;AACvB,MAAI;AACF,WAAO,IAAI,IAAI,SAAS,EAAE,SAAS,OAAO,YAAY;AAAA,EACxD,QAAQ;AACN,WAAO;AAAA,EACT;AACF;","names":[]}
|
|
@@ -6,10 +6,7 @@ async function safeServerAction(fn) {
|
|
|
6
6
|
return { success: true, data };
|
|
7
7
|
} catch (error) {
|
|
8
8
|
if (isRedirectError(error)) throw error;
|
|
9
|
-
|
|
10
|
-
return { success: false, error: error.message, code: error.code, statusCode: error.statusCode };
|
|
11
|
-
}
|
|
12
|
-
const message = error instanceof Error ? error.message : "Erro desconhecido";
|
|
9
|
+
const message = error instanceof ApiError ? error.message : error instanceof Error ? error.message : "Erro desconhecido";
|
|
13
10
|
return { success: false, error: message };
|
|
14
11
|
}
|
|
15
12
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/safeServerAction.ts"],"sourcesContent":["import { isRedirectError } from 'next/dist/client/components/redirect-error';\nimport { ApiError } from '../infra/api/types';\nimport type { ActionResult } from '../infra/api/types';\n\nexport async function safeServerAction<T>(\n fn: () => Promise<T>\n): Promise<ActionResult<T>> {\n try {\n const data = await fn();\n return { success: true, data };\n } catch (error) {\n if (isRedirectError(error)) throw error;\n
|
|
1
|
+
{"version":3,"sources":["../../src/utils/safeServerAction.ts"],"sourcesContent":["import { isRedirectError } from 'next/dist/client/components/redirect-error';\nimport { ApiError } from '../infra/api/types';\nimport type { ActionResult } from '../infra/api/types';\n\nexport async function safeServerAction<T>(\n fn: () => Promise<T>\n): Promise<ActionResult<T>> {\n try {\n const data = await fn();\n return { success: true, data };\n } catch (error) {\n if (isRedirectError(error)) throw error;\n const message =\n error instanceof ApiError\n ? error.message\n : error instanceof Error\n ? error.message\n : 'Erro desconhecido';\n return { success: false, error: message };\n }\n}\n"],"mappings":"AAAA,SAAS,uBAAuB;AAChC,SAAS,gBAAgB;AAGzB,eAAsB,iBACpB,IAC0B;AAC1B,MAAI;AACF,UAAM,OAAO,MAAM,GAAG;AACtB,WAAO,EAAE,SAAS,MAAM,KAAK;AAAA,EAC/B,SAAS,OAAO;AACd,QAAI,gBAAgB,KAAK,EAAG,OAAM;AAClC,UAAM,UACJ,iBAAiB,WACb,MAAM,UACN,iBAAiB,QACf,MAAM,UACN;AACR,WAAO,EAAE,SAAS,OAAO,OAAO,QAAQ;AAAA,EAC1C;AACF;","names":[]}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { ApiError } from "../infra/api/types";
|
|
2
1
|
function withAction(action) {
|
|
3
2
|
return async (...args) => {
|
|
4
3
|
const result = await action(...args);
|
|
5
4
|
if (!result.success) {
|
|
6
|
-
throw new
|
|
5
|
+
throw new Error(result.error ?? "Erro desconhecido");
|
|
7
6
|
}
|
|
8
7
|
return result.data;
|
|
9
8
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/withAction.ts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"sources":["../../src/utils/withAction.ts"],"sourcesContent":["import type { ActionResult } from '../infra/api/types';\n\nexport function withAction<TArgs extends any[], TData>(\n action: (...args: TArgs) => Promise<ActionResult<TData>>\n): (...args: TArgs) => Promise<TData> {\n return async (...args) => {\n const result = await action(...args);\n if (!result.success) {\n throw new Error(result.error ?? 'Erro desconhecido');\n }\n return result.data as TData;\n };\n}\n"],"mappings":"AAEO,SAAS,WACd,QACoC;AACpC,SAAO,UAAU,SAAS;AACxB,UAAM,SAAS,MAAM,OAAO,GAAG,IAAI;AACnC,QAAI,CAAC,OAAO,SAAS;AACnB,YAAM,IAAI,MAAM,OAAO,SAAS,mBAAmB;AAAA,IACrD;AACA,WAAO,OAAO;AAAA,EAChB;AACF;","names":[]}
|
package/package.json
CHANGED
|
@@ -2,10 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
import { ReactNode } from "react";
|
|
4
4
|
import Image from "next/image";
|
|
5
|
-
import { useTranslations } from "next-intl";
|
|
6
5
|
import { IconMenu2, IconX } from "@tabler/icons-react";
|
|
7
6
|
import { ProfilePopover } from "./ProfilePopover";
|
|
8
|
-
import { GreatDomainIcon } from "./GreatDomainIcon";
|
|
9
7
|
import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/overlay/Tooltip";
|
|
10
8
|
import { useMobileNavbarSheet } from "../../store/useMobileNavbarSheet";
|
|
11
9
|
import {
|
|
@@ -17,13 +15,11 @@ import type { ProfileMenuItem } from "./ProfilePopover";
|
|
|
17
15
|
|
|
18
16
|
export interface AppMobileNavBarProps {
|
|
19
17
|
/** Which app is currently active — controls which icon gets the indicator */
|
|
20
|
-
activeApp?: "gapps" | "gpages"
|
|
18
|
+
activeApp?: "gapps" | "gpages";
|
|
21
19
|
/** Called when the GreatApps logo is clicked */
|
|
22
20
|
onLogoClick?: () => void;
|
|
23
21
|
/** Called when the app icon (e.g. GreatPages) is clicked */
|
|
24
22
|
onAppIconClick?: () => void;
|
|
25
|
-
/** Called when the GreatDomain icon is clicked; without it the icon is not rendered (app flag) */
|
|
26
|
-
onDomainIconClick?: () => void;
|
|
27
23
|
/** Extra slot rendered after the app icon (e.g. project selector) */
|
|
28
24
|
extraLeftSlot?: ReactNode;
|
|
29
25
|
menuItems?: ProfileMenuItem[];
|
|
@@ -34,12 +30,10 @@ export function AppMobileNavBar({
|
|
|
34
30
|
activeApp,
|
|
35
31
|
onLogoClick,
|
|
36
32
|
onAppIconClick,
|
|
37
|
-
onDomainIconClick,
|
|
38
33
|
extraLeftSlot,
|
|
39
34
|
menuItems = [],
|
|
40
35
|
showMenuToggle = true,
|
|
41
36
|
}: AppMobileNavBarProps) {
|
|
42
|
-
const translate = useTranslations();
|
|
43
37
|
const { isOpen, toggle } = useMobileNavbarSheet();
|
|
44
38
|
const { whitelabel } = useWhitelabel();
|
|
45
39
|
const isDefaultWl = useIsDefaultWhitelabel();
|
|
@@ -48,7 +42,6 @@ export function AppMobileNavBar({
|
|
|
48
42
|
|
|
49
43
|
const isGappsActive = activeApp === "gapps";
|
|
50
44
|
const isGpagesActive = activeApp === "gpages";
|
|
51
|
-
const isGdomainActive = activeApp === "gdomain";
|
|
52
45
|
|
|
53
46
|
const wlIcon = whitelabel?.secondary_logo ? (
|
|
54
47
|
<Image
|
|
@@ -87,9 +80,9 @@ export function AppMobileNavBar({
|
|
|
87
80
|
|
|
88
81
|
return (
|
|
89
82
|
<div className="fixed top-0 left-0 right-0 flex md:hidden items-center justify-between p-4 bg-white z-50 border-b border-gray-200">
|
|
90
|
-
<div className="flex items-center gap-1.5
|
|
83
|
+
<div className="flex items-center gap-1.5">
|
|
91
84
|
{/* GreatApps logo */}
|
|
92
|
-
<div className="relative
|
|
85
|
+
<div className="relative">
|
|
93
86
|
<Tooltip>
|
|
94
87
|
<TooltipTrigger asChild>
|
|
95
88
|
<div
|
|
@@ -126,7 +119,7 @@ export function AppMobileNavBar({
|
|
|
126
119
|
</div>
|
|
127
120
|
|
|
128
121
|
{/* GreatPages icon */}
|
|
129
|
-
<div className="relative
|
|
122
|
+
<div className="relative">
|
|
130
123
|
<Tooltip>
|
|
131
124
|
<TooltipTrigger asChild>
|
|
132
125
|
<div
|
|
@@ -194,86 +187,9 @@ export function AppMobileNavBar({
|
|
|
194
187
|
/>
|
|
195
188
|
</div>
|
|
196
189
|
|
|
197
|
-
{
|
|
198
|
-
{onDomainIconClick ? (
|
|
199
|
-
<div className="relative shrink-0">
|
|
200
|
-
<Tooltip>
|
|
201
|
-
<TooltipTrigger asChild>
|
|
202
|
-
<div
|
|
203
|
-
aria-label={
|
|
204
|
-
isDefaultWl
|
|
205
|
-
? translate("common.layout.navbar.greatDomain")
|
|
206
|
-
: translate("common.layout.navbar.domains")
|
|
207
|
-
}
|
|
208
|
-
className={cn(
|
|
209
|
-
"size-10 rounded-[10px] flex items-center justify-center border-2 ring-2 transition-colors duration-300",
|
|
210
|
-
isGdomainActive
|
|
211
|
-
? isDefaultWl
|
|
212
|
-
? "bg-[#EDE9FE] border-white ring-[#C092FF]"
|
|
213
|
-
: "border-white ring-transparent"
|
|
214
|
-
: isDefaultWl
|
|
215
|
-
? "hover:bg-gray-100 border-transparent ring-transparent"
|
|
216
|
-
: "border-transparent ring-transparent",
|
|
217
|
-
"cursor-pointer",
|
|
218
|
-
)}
|
|
219
|
-
style={
|
|
220
|
-
!isDefaultWl
|
|
221
|
-
? {
|
|
222
|
-
backgroundColor: primaryColor,
|
|
223
|
-
boxShadow: isGdomainActive
|
|
224
|
-
? `0 0 0 2px ${primaryColor}40`
|
|
225
|
-
: undefined,
|
|
226
|
-
opacity: !isGdomainActive ? 0.2 : undefined,
|
|
227
|
-
}
|
|
228
|
-
: undefined
|
|
229
|
-
}
|
|
230
|
-
onClick={onDomainIconClick}
|
|
231
|
-
>
|
|
232
|
-
{isDefaultWl ? (
|
|
233
|
-
<GreatDomainIcon active={isGdomainActive} />
|
|
234
|
-
) : (
|
|
235
|
-
<svg
|
|
236
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
237
|
-
width="24"
|
|
238
|
-
height="24"
|
|
239
|
-
viewBox="0 0 24 24"
|
|
240
|
-
fill="none"
|
|
241
|
-
stroke="white"
|
|
242
|
-
strokeWidth="2"
|
|
243
|
-
strokeLinecap="round"
|
|
244
|
-
strokeLinejoin="round"
|
|
245
|
-
>
|
|
246
|
-
<path d="M3 12a9 9 0 1 0 18 0a9 9 0 0 0 -18 0" />
|
|
247
|
-
<path d="M3.6 9h16.8" />
|
|
248
|
-
<path d="M3.6 15h16.8" />
|
|
249
|
-
<path d="M11.5 3a17 17 0 0 0 0 18" />
|
|
250
|
-
<path d="M12.5 3a17 17 0 0 1 0 18" />
|
|
251
|
-
</svg>
|
|
252
|
-
)}
|
|
253
|
-
</div>
|
|
254
|
-
</TooltipTrigger>
|
|
255
|
-
<TooltipContent side="bottom">
|
|
256
|
-
{isDefaultWl
|
|
257
|
-
? translate("common.layout.navbar.greatDomain")
|
|
258
|
-
: translate("common.layout.navbar.domains")}
|
|
259
|
-
</TooltipContent>
|
|
260
|
-
</Tooltip>
|
|
261
|
-
<div
|
|
262
|
-
className={cn(
|
|
263
|
-
"absolute -bottom-[17px] left-1/2 -translate-x-1/2 w-5 h-[3px] rounded-t-xl transition-opacity duration-300",
|
|
264
|
-
isDefaultWl ? "bg-[#984DFF]" : "",
|
|
265
|
-
isGdomainActive ? "opacity-100" : "opacity-0",
|
|
266
|
-
)}
|
|
267
|
-
style={!isDefaultWl ? { backgroundColor: primaryColor } : undefined}
|
|
268
|
-
/>
|
|
269
|
-
</div>
|
|
270
|
-
) : null}
|
|
271
|
-
|
|
272
|
-
{extraLeftSlot ? (
|
|
273
|
-
<div className="min-w-0 shrink [&>*]:max-w-full">{extraLeftSlot}</div>
|
|
274
|
-
) : null}
|
|
190
|
+
{extraLeftSlot}
|
|
275
191
|
</div>
|
|
276
|
-
<div className="flex items-center gap-1.5
|
|
192
|
+
<div className="flex items-center gap-1.5">
|
|
277
193
|
<ProfilePopover
|
|
278
194
|
side="bottom"
|
|
279
195
|
align="end"
|
|
@@ -8,10 +8,8 @@ import type { ProfileMenuItem } from "./ProfilePopover";
|
|
|
8
8
|
export interface AppNavBarProps {
|
|
9
9
|
logoHref: string;
|
|
10
10
|
appIconHref: string;
|
|
11
|
-
/** Sem href o ícone do GreatDomain não é renderizado: é a flag do app. */
|
|
12
|
-
domainIconHref?: string;
|
|
13
11
|
/** Which app is currently active — controls which icon gets the indicator */
|
|
14
|
-
activeApp?: "gapps" | "gpages"
|
|
12
|
+
activeApp?: "gapps" | "gpages";
|
|
15
13
|
showExpandButton?: boolean;
|
|
16
14
|
onExpandClick?: () => void;
|
|
17
15
|
menuItems?: ProfileMenuItem[];
|
|
@@ -21,7 +19,6 @@ export interface AppNavBarProps {
|
|
|
21
19
|
export function AppNavBar({
|
|
22
20
|
logoHref,
|
|
23
21
|
appIconHref,
|
|
24
|
-
domainIconHref,
|
|
25
22
|
activeApp,
|
|
26
23
|
showExpandButton = false,
|
|
27
24
|
onExpandClick,
|
|
@@ -32,7 +29,6 @@ export function AppNavBar({
|
|
|
32
29
|
<NavBar
|
|
33
30
|
logoHref={logoHref}
|
|
34
31
|
appIconHref={appIconHref}
|
|
35
|
-
domainIconHref={domainIconHref}
|
|
36
32
|
activeApp={activeApp}
|
|
37
33
|
showExpandButton={showExpandButton}
|
|
38
34
|
onExpandClick={onExpandClick}
|