@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
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { useQuery } from "@tanstack/react-query";
|
|
3
|
-
import { apiFetch } from "../../../infra/http/api-fetch";
|
|
4
|
-
import { useAuthQueryKey } from "../../../hooks/useAuthQueryKey";
|
|
5
|
-
import { SUBSCRIPTIONS_QUERY_KEY } from "../constants/query-keys.constants";
|
|
6
|
-
function useCurrentSubscription() {
|
|
7
|
-
const queryKey = useAuthQueryKey([...SUBSCRIPTIONS_QUERY_KEY, "current"]);
|
|
8
|
-
return useQuery({
|
|
9
|
-
queryKey,
|
|
10
|
-
queryFn: async ({ signal }) => {
|
|
11
|
-
const result = await apiFetch(
|
|
12
|
-
"/api/subscriptions/current",
|
|
13
|
-
{ signal }
|
|
14
|
-
);
|
|
15
|
-
const subscription = result.data ?? null;
|
|
16
|
-
return {
|
|
17
|
-
success: true,
|
|
18
|
-
data: subscription ? [subscription] : [],
|
|
19
|
-
total: subscription ? 1 : 0
|
|
20
|
-
};
|
|
21
|
-
},
|
|
22
|
-
staleTime: 1e4
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
export {
|
|
26
|
-
useCurrentSubscription
|
|
27
|
-
};
|
|
28
|
-
//# sourceMappingURL=use-current-subscription.hook.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/modules/subscriptions/hooks/use-current-subscription.hook.ts"],"sourcesContent":["'use client';\n\nimport { useQuery } from '@tanstack/react-query';\nimport { apiFetch } from '../../../infra/http/api-fetch';\nimport { useAuthQueryKey } from '../../../hooks/useAuthQueryKey';\nimport type { PaginatedSuccessResult, SuccessResult } from '../../../infra/api/types';\nimport type { Subscription } from '../types/subscription.type';\nimport { SUBSCRIPTIONS_QUERY_KEY } from '../constants/query-keys.constants';\n\n/**\n * A assinatura corrente do plano da conta, pela regra única do backend\n * (contrato de domínio nunca é corrente; encerrada é decidida por `active`).\n *\n * Devolvida na mesma forma paginada de `useSubscriptions`/`useActiveSubscription`\n * (`{ data: [sub] }`) para não exigir mudança nos call sites que já leem\n * `data?.[0]`: só a URL e a regra por trás mudam.\n */\nexport function useCurrentSubscription() {\n const queryKey = useAuthQueryKey([...SUBSCRIPTIONS_QUERY_KEY, 'current']);\n\n return useQuery({\n queryKey,\n queryFn: async ({ signal }): Promise<PaginatedSuccessResult<Subscription>> => {\n const result = await apiFetch<SuccessResult<Subscription | null>>(\n '/api/subscriptions/current',\n { signal },\n );\n const subscription = result.data ?? null;\n\n return {\n success: true,\n data: subscription ? [subscription] : [],\n total: subscription ? 1 : 0,\n };\n },\n staleTime: 10_000,\n });\n}\n"],"mappings":";AAEA,SAAS,gBAAgB;AACzB,SAAS,gBAAgB;AACzB,SAAS,uBAAuB;AAGhC,SAAS,+BAA+B;AAUjC,SAAS,yBAAyB;AACvC,QAAM,WAAW,gBAAgB,CAAC,GAAG,yBAAyB,SAAS,CAAC;AAExE,SAAO,SAAS;AAAA,IACd;AAAA,IACA,SAAS,OAAO,EAAE,OAAO,MAAqD;AAC5E,YAAM,SAAS,MAAM;AAAA,QACnB;AAAA,QACA,EAAE,OAAO;AAAA,MACX;AACA,YAAM,eAAe,OAAO,QAAQ;AAEpC,aAAO;AAAA,QACL,SAAS;AAAA,QACT,MAAM,eAAe,CAAC,YAAY,IAAI,CAAC;AAAA,QACvC,OAAO,eAAe,IAAI;AAAA,MAC5B;AAAA,IACF;AAAA,IACA,WAAW;AAAA,EACb,CAAC;AACH;","names":[]}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
function groupSubscriptionsByProduct(subscriptions) {
|
|
2
|
-
const groups = /* @__PURE__ */ new Map();
|
|
3
|
-
for (const subscription of subscriptions) {
|
|
4
|
-
const group = groups.get(subscription.id_product);
|
|
5
|
-
if (group) {
|
|
6
|
-
group.push(subscription);
|
|
7
|
-
} else {
|
|
8
|
-
groups.set(subscription.id_product, [subscription]);
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
return groups;
|
|
12
|
-
}
|
|
13
|
-
export {
|
|
14
|
-
groupSubscriptionsByProduct
|
|
15
|
-
};
|
|
16
|
-
//# sourceMappingURL=group-subscriptions-by-product.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/modules/subscriptions/utils/group-subscriptions-by-product.ts"],"sourcesContent":["import type { Subscription } from '../types/subscription.type';\n\n/**\n * Agrupa assinaturas por `id_product`, preservando a ordem de chegada dentro\n * de cada grupo. Base da seção \"Domínios registrados\" do painel e da aba\n * Assinatura agrupada por produto no admin.\n */\nexport function groupSubscriptionsByProduct(\n subscriptions: Subscription[],\n): Map<number, Subscription[]> {\n const groups = new Map<number, Subscription[]>();\n\n for (const subscription of subscriptions) {\n const group = groups.get(subscription.id_product);\n if (group) {\n group.push(subscription);\n } else {\n groups.set(subscription.id_product, [subscription]);\n }\n }\n\n return groups;\n}\n"],"mappings":"AAOO,SAAS,4BACd,eAC6B;AAC7B,QAAM,SAAS,oBAAI,IAA4B;AAE/C,aAAW,gBAAgB,eAAe;AACxC,UAAM,QAAQ,OAAO,IAAI,aAAa,UAAU;AAChD,QAAI,OAAO;AACT,YAAM,KAAK,YAAY;AAAA,IACzB,OAAO;AACL,aAAO,IAAI,aAAa,YAAY,CAAC,YAAY,CAAC;AAAA,IACpD;AAAA,EACF;AAEA,SAAO;AACT;","names":[]}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import "server-only";
|
|
2
|
-
import { cache } from "react";
|
|
3
|
-
import { ApiError } from "../../../infra/api/types";
|
|
4
|
-
import { getCurrentSubscriptionAction } from "../actions/get-current-subscription.action";
|
|
5
|
-
const readCurrentSubscription = cache(
|
|
6
|
-
async () => {
|
|
7
|
-
const result = await getCurrentSubscriptionAction();
|
|
8
|
-
if (!result.success) {
|
|
9
|
-
throw new ApiError(
|
|
10
|
-
result.error || "N\xE3o foi poss\xEDvel validar a assinatura atual",
|
|
11
|
-
"SUBSCRIPTION_CONTEXT_FAILED",
|
|
12
|
-
403
|
|
13
|
-
);
|
|
14
|
-
}
|
|
15
|
-
return result.data?.data ?? null;
|
|
16
|
-
}
|
|
17
|
-
);
|
|
18
|
-
export {
|
|
19
|
-
readCurrentSubscription
|
|
20
|
-
};
|
|
21
|
-
//# sourceMappingURL=read-current-subscription.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/modules/subscriptions/utils/read-current-subscription.ts"],"sourcesContent":["import \"server-only\";\n\nimport { cache } from \"react\";\n\nimport { ApiError } from \"../../../infra/api/types\";\nimport { getCurrentSubscriptionAction } from \"../actions/get-current-subscription.action\";\nimport type { Subscription } from \"../types/subscription.type\";\n\n/**\n * Leitura única por request de \"qual é a assinatura corrente do plano desta\n * conta\", deduplicada via React.cache. Os quatro gates de auth\n * (`assertAccountNotFrozen`, `assertManagementSubscription`,\n * `assertPaidSubscription`, `assertSubscriptionAddon`) chamam esta função em\n * vez de repetir a própria leitura cada um: eram até 4 cópias da mesma\n * pergunta disputando a mesma fila (0,7 a 7s cada, medido em produção).\n *\n * Lança em falha de leitura; `assertAccountNotFrozen` é o único chamador que\n * precisa de fail-open, e faz isso capturando o erro no próprio call site.\n */\nexport const readCurrentSubscription = cache(\n async (): Promise<Subscription | null> => {\n const result = await getCurrentSubscriptionAction();\n\n if (!result.success) {\n throw new ApiError(\n result.error || \"Não foi possível validar a assinatura atual\",\n \"SUBSCRIPTION_CONTEXT_FAILED\",\n 403,\n );\n }\n\n return result.data?.data ?? null;\n },\n);\n"],"mappings":"AAAA,OAAO;AAEP,SAAS,aAAa;AAEtB,SAAS,gBAAgB;AACzB,SAAS,oCAAoC;AActC,MAAM,0BAA0B;AAAA,EACrC,YAA0C;AACxC,UAAM,SAAS,MAAM,6BAA6B;AAElD,QAAI,CAAC,OAAO,SAAS;AACnB,YAAM,IAAI;AAAA,QACR,OAAO,SAAS;AAAA,QAChB;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,WAAO,OAAO,MAAM,QAAQ;AAAA,EAC9B;AACF;","names":[]}
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import { cn } from "../../infra/utils/clsx";
|
|
4
|
-
|
|
5
|
-
type GreatDomainIconProps = {
|
|
6
|
-
/** Em repouso o círculo é #650CE4; só no estado ativo vira #984DFF. */
|
|
7
|
-
active?: boolean;
|
|
8
|
-
className?: string;
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Glifo do GreatDomain — geometria exportada do Figma (node 5929:2700), 23×23.
|
|
13
|
-
* O círculo só troca de cor quando ativo. No hover o container ganha fundo cinza
|
|
14
|
-
* (igual ao GreatPages) e o glifo fica como está.
|
|
15
|
-
*/
|
|
16
|
-
function GreatDomainIcon({ active, className }: GreatDomainIconProps) {
|
|
17
|
-
return (
|
|
18
|
-
<svg
|
|
19
|
-
width="23"
|
|
20
|
-
height="23"
|
|
21
|
-
viewBox="0 0 23 23"
|
|
22
|
-
fill="none"
|
|
23
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
24
|
-
className={className}
|
|
25
|
-
aria-hidden="true"
|
|
26
|
-
>
|
|
27
|
-
<path
|
|
28
|
-
d="M11.8444 17.0777C11.8444 20.3487 9.19292 23.0003 5.92218 23.0003C2.65145 23.0003 0 20.3487 0 17.0777C0 13.8068 2.65145 11.1551 5.92218 11.1551C9.19292 11.1551 11.8444 13.8068 11.8444 17.0777Z"
|
|
29
|
-
className={cn(
|
|
30
|
-
"transition-colors duration-300",
|
|
31
|
-
active ? "fill-[#984DFF]" : "fill-[#650CE4]",
|
|
32
|
-
)}
|
|
33
|
-
/>
|
|
34
|
-
<path
|
|
35
|
-
d="M11.8436 3.06666C11.8436 1.37299 13.2166 0 14.9103 0H19.9331C21.6267 0 22.9997 1.37299 22.9997 3.06666V19.9333C22.9997 21.6269 21.6267 22.9999 19.9331 22.9999H14.9103C13.2166 22.9999 11.8436 21.6269 11.8436 19.9333V3.06666Z"
|
|
36
|
-
fill="#C9B2FF"
|
|
37
|
-
/>
|
|
38
|
-
</svg>
|
|
39
|
-
);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export { GreatDomainIcon };
|
|
43
|
-
export type { GreatDomainIconProps };
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
'use server';
|
|
2
|
-
|
|
3
|
-
import { safeServerAction } from '../../../utils/safeServerAction';
|
|
4
|
-
import { subscriptionsService } from '../services/subscriptions.service';
|
|
5
|
-
|
|
6
|
-
export async function getCurrentSubscriptionAction(params?: { id_product?: number }) {
|
|
7
|
-
return safeServerAction(() => subscriptionsService.getCurrentSubscription(params));
|
|
8
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import 'server-only';
|
|
2
|
-
|
|
3
|
-
import type { NextRequest } from 'next/server';
|
|
4
|
-
import { safeRouteHandler } from '../../../infra/route/safe-route-handler';
|
|
5
|
-
import { searchParamsToParams } from '../../../infra/route/search-params';
|
|
6
|
-
import { subscriptionsService } from '../services/subscriptions.service';
|
|
7
|
-
|
|
8
|
-
export function createCurrentSubscriptionHandler() {
|
|
9
|
-
return async function GET(req: NextRequest) {
|
|
10
|
-
return safeRouteHandler(() =>
|
|
11
|
-
subscriptionsService.getCurrentSubscription(
|
|
12
|
-
searchParamsToParams<{ id_product?: number }>(req.nextUrl.searchParams),
|
|
13
|
-
),
|
|
14
|
-
);
|
|
15
|
-
};
|
|
16
|
-
}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
import { useQuery } from '@tanstack/react-query';
|
|
4
|
-
import { apiFetch } from '../../../infra/http/api-fetch';
|
|
5
|
-
import { useAuthQueryKey } from '../../../hooks/useAuthQueryKey';
|
|
6
|
-
import type { PaginatedSuccessResult, SuccessResult } from '../../../infra/api/types';
|
|
7
|
-
import type { Subscription } from '../types/subscription.type';
|
|
8
|
-
import { SUBSCRIPTIONS_QUERY_KEY } from '../constants/query-keys.constants';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* A assinatura corrente do plano da conta, pela regra única do backend
|
|
12
|
-
* (contrato de domínio nunca é corrente; encerrada é decidida por `active`).
|
|
13
|
-
*
|
|
14
|
-
* Devolvida na mesma forma paginada de `useSubscriptions`/`useActiveSubscription`
|
|
15
|
-
* (`{ data: [sub] }`) para não exigir mudança nos call sites que já leem
|
|
16
|
-
* `data?.[0]`: só a URL e a regra por trás mudam.
|
|
17
|
-
*/
|
|
18
|
-
export function useCurrentSubscription() {
|
|
19
|
-
const queryKey = useAuthQueryKey([...SUBSCRIPTIONS_QUERY_KEY, 'current']);
|
|
20
|
-
|
|
21
|
-
return useQuery({
|
|
22
|
-
queryKey,
|
|
23
|
-
queryFn: async ({ signal }): Promise<PaginatedSuccessResult<Subscription>> => {
|
|
24
|
-
const result = await apiFetch<SuccessResult<Subscription | null>>(
|
|
25
|
-
'/api/subscriptions/current',
|
|
26
|
-
{ signal },
|
|
27
|
-
);
|
|
28
|
-
const subscription = result.data ?? null;
|
|
29
|
-
|
|
30
|
-
return {
|
|
31
|
-
success: true,
|
|
32
|
-
data: subscription ? [subscription] : [],
|
|
33
|
-
total: subscription ? 1 : 0,
|
|
34
|
-
};
|
|
35
|
-
},
|
|
36
|
-
staleTime: 10_000,
|
|
37
|
-
});
|
|
38
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import type { Subscription } from '../types/subscription.type';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Agrupa assinaturas por `id_product`, preservando a ordem de chegada dentro
|
|
5
|
-
* de cada grupo. Base da seção "Domínios registrados" do painel e da aba
|
|
6
|
-
* Assinatura agrupada por produto no admin.
|
|
7
|
-
*/
|
|
8
|
-
export function groupSubscriptionsByProduct(
|
|
9
|
-
subscriptions: Subscription[],
|
|
10
|
-
): Map<number, Subscription[]> {
|
|
11
|
-
const groups = new Map<number, Subscription[]>();
|
|
12
|
-
|
|
13
|
-
for (const subscription of subscriptions) {
|
|
14
|
-
const group = groups.get(subscription.id_product);
|
|
15
|
-
if (group) {
|
|
16
|
-
group.push(subscription);
|
|
17
|
-
} else {
|
|
18
|
-
groups.set(subscription.id_product, [subscription]);
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
return groups;
|
|
23
|
-
}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import "server-only";
|
|
2
|
-
|
|
3
|
-
import { cache } from "react";
|
|
4
|
-
|
|
5
|
-
import { ApiError } from "../../../infra/api/types";
|
|
6
|
-
import { getCurrentSubscriptionAction } from "../actions/get-current-subscription.action";
|
|
7
|
-
import type { Subscription } from "../types/subscription.type";
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Leitura única por request de "qual é a assinatura corrente do plano desta
|
|
11
|
-
* conta", deduplicada via React.cache. Os quatro gates de auth
|
|
12
|
-
* (`assertAccountNotFrozen`, `assertManagementSubscription`,
|
|
13
|
-
* `assertPaidSubscription`, `assertSubscriptionAddon`) chamam esta função em
|
|
14
|
-
* vez de repetir a própria leitura cada um: eram até 4 cópias da mesma
|
|
15
|
-
* pergunta disputando a mesma fila (0,7 a 7s cada, medido em produção).
|
|
16
|
-
*
|
|
17
|
-
* Lança em falha de leitura; `assertAccountNotFrozen` é o único chamador que
|
|
18
|
-
* precisa de fail-open, e faz isso capturando o erro no próprio call site.
|
|
19
|
-
*/
|
|
20
|
-
export const readCurrentSubscription = cache(
|
|
21
|
-
async (): Promise<Subscription | null> => {
|
|
22
|
-
const result = await getCurrentSubscriptionAction();
|
|
23
|
-
|
|
24
|
-
if (!result.success) {
|
|
25
|
-
throw new ApiError(
|
|
26
|
-
result.error || "Não foi possível validar a assinatura atual",
|
|
27
|
-
"SUBSCRIPTION_CONTEXT_FAILED",
|
|
28
|
-
403,
|
|
29
|
-
);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
return result.data?.data ?? null;
|
|
33
|
-
},
|
|
34
|
-
);
|