@greatapps/common 1.1.777 → 1.1.778

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.
@@ -10,6 +10,7 @@ import {
10
10
  DialogHeader,
11
11
  DialogTitle
12
12
  } from "../ui/overlay/Dialog";
13
+ import { DialogLayer } from "../ui/overlay/layers";
13
14
  import { InputOTP, InputOTPGroup, InputOTPSlot } from "../ui/form/InputOtp";
14
15
  import { REGEXP_ONLY_DIGITS } from "input-otp";
15
16
  import useDisableTwoFactorAuthForm from "./hooks/useDisableTwoFactorAuthForm";
@@ -20,49 +21,52 @@ function DisableTwoFactorAuthModal({
20
21
  }) {
21
22
  const translate = useTranslations();
22
23
  const { code, setCode, isValid, isLoading, handleClose, handleSubmit } = useDisableTwoFactorAuthForm({ onClose, onSuccess });
23
- return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange: handleClose, children: /* @__PURE__ */ jsx(DialogContent, { overlayClassName: "z-[1010]", className: "z-[1011] flex flex-col p-0 gap-0 max-w-full sm:max-w-full border-0 rounded-t-2xl rounded-b-none h-dvh top-0 bottom-0 left-0 right-0 translate-x-0 translate-y-0 lg:max-w-117.5 lg:h-auto lg:rounded-lg lg:border lg:top-[50%] lg:left-[50%] lg:right-auto lg:bottom-auto lg:translate-x-[-50%] lg:translate-y-[-50%]", children: /* @__PURE__ */ jsxs(
24
- "form",
25
- {
26
- onSubmit: (e) => {
27
- e.preventDefault();
28
- handleSubmit();
29
- },
30
- className: "flex flex-col flex-1 lg:flex-none",
31
- children: [
32
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4 lg:gap-5 p-4 lg:p-5 flex-1 lg:flex-none", children: [
33
- /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center w-fit bg-gray-50 rounded-lg p-2", children: /* @__PURE__ */ jsx(IconShieldCheck, { size: 20, className: "text-gray-600" }) }),
34
- /* @__PURE__ */ jsxs(DialogHeader, { className: "p-0 gap-2", children: [
35
- /* @__PURE__ */ jsx(DialogTitle, { className: "paragraph-medium-semibold text-gray-950", children: translate("common.account.twoFactor.disableTitle") }),
36
- /* @__PURE__ */ jsx(DialogDescription, { className: "paragraph-small-regular text-gray-600", children: translate("common.account.twoFactor.disableDescription") })
24
+ return (
25
+ // Abre por cima do modal de configurações da conta, que é irmão na árvore.
26
+ /* @__PURE__ */ jsx(DialogLayer, { children: /* @__PURE__ */ jsx(Dialog, { open, onOpenChange: handleClose, children: /* @__PURE__ */ jsx(DialogContent, { className: "flex flex-col p-0 gap-0 max-w-full sm:max-w-full border-0 rounded-t-2xl rounded-b-none h-dvh top-0 bottom-0 left-0 right-0 translate-x-0 translate-y-0 lg:max-w-117.5 lg:h-auto lg:rounded-lg lg:border lg:top-[50%] lg:left-[50%] lg:right-auto lg:bottom-auto lg:translate-x-[-50%] lg:translate-y-[-50%]", children: /* @__PURE__ */ jsxs(
27
+ "form",
28
+ {
29
+ onSubmit: (e) => {
30
+ e.preventDefault();
31
+ handleSubmit();
32
+ },
33
+ className: "flex flex-col flex-1 lg:flex-none",
34
+ children: [
35
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4 lg:gap-5 p-4 lg:p-5 flex-1 lg:flex-none", children: [
36
+ /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center w-fit bg-gray-50 rounded-lg p-2", children: /* @__PURE__ */ jsx(IconShieldCheck, { size: 20, className: "text-gray-600" }) }),
37
+ /* @__PURE__ */ jsxs(DialogHeader, { className: "p-0 gap-2", children: [
38
+ /* @__PURE__ */ jsx(DialogTitle, { className: "paragraph-medium-semibold text-gray-950", children: translate("common.account.twoFactor.disableTitle") }),
39
+ /* @__PURE__ */ jsx(DialogDescription, { className: "paragraph-small-regular text-gray-600", children: translate("common.account.twoFactor.disableDescription") })
40
+ ] }),
41
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
42
+ /* @__PURE__ */ jsx("span", { className: "paragraph-small-medium text-gray-700", children: translate("common.account.twoFactor.authenticatorCode") }),
43
+ /* @__PURE__ */ jsx(InputOTP, { maxLength: 6, pattern: REGEXP_ONLY_DIGITS, value: code, onChange: setCode, children: /* @__PURE__ */ jsx(InputOTPGroup, { className: "gap-2", children: Array.from({ length: 6 }).map((_, i) => /* @__PURE__ */ jsx(
44
+ InputOTPSlot,
45
+ {
46
+ index: i,
47
+ className: "w-11! lg:w-12! h-13! lg:h-14! rounded-lg! text-lg border-gray-200"
48
+ },
49
+ i
50
+ )) }) })
51
+ ] })
37
52
  ] }),
38
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
39
- /* @__PURE__ */ jsx("span", { className: "paragraph-small-medium text-gray-700", children: translate("common.account.twoFactor.authenticatorCode") }),
40
- /* @__PURE__ */ jsx(InputOTP, { maxLength: 6, pattern: REGEXP_ONLY_DIGITS, value: code, onChange: setCode, children: /* @__PURE__ */ jsx(InputOTPGroup, { className: "gap-2", children: Array.from({ length: 6 }).map((_, i) => /* @__PURE__ */ jsx(
41
- InputOTPSlot,
53
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-row items-center gap-2 p-4 lg:p-5 border-t border-gray-200 mt-auto lg:mt-0", children: [
54
+ /* @__PURE__ */ jsx(Button, { className: "h-10! flex-1", disabled: !isValid || isLoading, type: "submit", children: isLoading ? translate("common.account.twoFactor.disabling") : translate("common.account.twoFactor.disable") }),
55
+ /* @__PURE__ */ jsx(
56
+ Button,
42
57
  {
43
- index: i,
44
- className: "w-11! lg:w-12! h-13! lg:h-14! rounded-lg! text-lg border-gray-200"
45
- },
46
- i
47
- )) }) })
58
+ variant: "secondary",
59
+ className: "h-10! flex-1",
60
+ type: "button",
61
+ onClick: handleClose,
62
+ children: translate("common.actions.cancel")
63
+ }
64
+ )
48
65
  ] })
49
- ] }),
50
- /* @__PURE__ */ jsxs("div", { className: "flex flex-row items-center gap-2 p-4 lg:p-5 border-t border-gray-200 mt-auto lg:mt-0", children: [
51
- /* @__PURE__ */ jsx(Button, { className: "h-10! flex-1", disabled: !isValid || isLoading, type: "submit", children: isLoading ? translate("common.account.twoFactor.disabling") : translate("common.account.twoFactor.disable") }),
52
- /* @__PURE__ */ jsx(
53
- Button,
54
- {
55
- variant: "secondary",
56
- className: "h-10! flex-1",
57
- type: "button",
58
- onClick: handleClose,
59
- children: translate("common.actions.cancel")
60
- }
61
- )
62
- ] })
63
- ]
64
- }
65
- ) }) });
66
+ ]
67
+ }
68
+ ) }) }) })
69
+ );
66
70
  }
67
71
  export {
68
72
  DisableTwoFactorAuthModal as default
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/account/DisableTwoFactorAuthModal.tsx"],"sourcesContent":["'use client';\n\nimport { useTranslations } from 'next-intl';\nimport { IconShieldCheck } from '@tabler/icons-react';\nimport { Button } from '../ui/buttons/Button';\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n} from '../ui/overlay/Dialog';\nimport { InputOTP, InputOTPGroup, InputOTPSlot } from '../ui/form/InputOtp';\nimport { REGEXP_ONLY_DIGITS } from 'input-otp';\nimport useDisableTwoFactorAuthForm from './hooks/useDisableTwoFactorAuthForm';\n\ninterface DisableTwoFactorAuthModalProps {\n open: boolean;\n onClose: () => void;\n onSuccess?: () => void;\n}\n\nexport default function DisableTwoFactorAuthModal({\n open,\n onClose,\n onSuccess,\n}: DisableTwoFactorAuthModalProps) {\n const translate = useTranslations();\n const { code, setCode, isValid, isLoading, handleClose, handleSubmit } =\n useDisableTwoFactorAuthForm({ onClose, onSuccess });\n\n return (\n <Dialog open={open} onOpenChange={handleClose}>\n <DialogContent overlayClassName=\"z-[1010]\" className=\"z-[1011] flex flex-col p-0 gap-0 max-w-full sm:max-w-full border-0 rounded-t-2xl rounded-b-none h-dvh top-0 bottom-0 left-0 right-0 translate-x-0 translate-y-0 lg:max-w-117.5 lg:h-auto lg:rounded-lg lg:border lg:top-[50%] lg:left-[50%] lg:right-auto lg:bottom-auto lg:translate-x-[-50%] lg:translate-y-[-50%]\">\n <form\n onSubmit={(e) => {\n e.preventDefault();\n handleSubmit();\n }}\n className=\"flex flex-col flex-1 lg:flex-none\"\n >\n <div className=\"flex flex-col gap-4 lg:gap-5 p-4 lg:p-5 flex-1 lg:flex-none\">\n <div className=\"flex items-center justify-center w-fit bg-gray-50 rounded-lg p-2\">\n <IconShieldCheck size={20} className=\"text-gray-600\" />\n </div>\n <DialogHeader className=\"p-0 gap-2\">\n <DialogTitle className=\"paragraph-medium-semibold text-gray-950\">\n {translate('common.account.twoFactor.disableTitle')}\n </DialogTitle>\n <DialogDescription className=\"paragraph-small-regular text-gray-600\">\n {translate('common.account.twoFactor.disableDescription')}\n </DialogDescription>\n </DialogHeader>\n\n <div className=\"flex flex-col gap-2\">\n <span className=\"paragraph-small-medium text-gray-700\">\n {translate('common.account.twoFactor.authenticatorCode')}\n </span>\n <InputOTP maxLength={6} pattern={REGEXP_ONLY_DIGITS} value={code} onChange={setCode}>\n <InputOTPGroup className=\"gap-2\">\n {Array.from({ length: 6 }).map((_, i) => (\n <InputOTPSlot\n key={i}\n index={i}\n className=\"w-11! lg:w-12! h-13! lg:h-14! rounded-lg! text-lg border-gray-200\"\n />\n ))}\n </InputOTPGroup>\n </InputOTP>\n </div>\n </div>\n\n <div className=\"flex flex-row items-center gap-2 p-4 lg:p-5 border-t border-gray-200 mt-auto lg:mt-0\">\n <Button className=\"h-10! flex-1\" disabled={!isValid || isLoading} type=\"submit\">\n {isLoading\n ? translate('common.account.twoFactor.disabling')\n : translate('common.account.twoFactor.disable')}\n </Button>\n <Button\n variant=\"secondary\"\n className=\"h-10! flex-1\"\n type=\"button\"\n onClick={handleClose}\n >\n {translate('common.actions.cancel')}\n </Button>\n </div>\n </form>\n </DialogContent>\n </Dialog>\n );\n}\n"],"mappings":";AA2Cc,cAEF,YAFE;AAzCd,SAAS,uBAAuB;AAChC,SAAS,uBAAuB;AAChC,SAAS,cAAc;AACvB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,UAAU,eAAe,oBAAoB;AACtD,SAAS,0BAA0B;AACnC,OAAO,iCAAiC;AAQzB,SAAR,0BAA2C;AAAA,EAChD;AAAA,EACA;AAAA,EACA;AACF,GAAmC;AACjC,QAAM,YAAY,gBAAgB;AAClC,QAAM,EAAE,MAAM,SAAS,SAAS,WAAW,aAAa,aAAa,IACnE,4BAA4B,EAAE,SAAS,UAAU,CAAC;AAEpD,SACE,oBAAC,UAAO,MAAY,cAAc,aAChC,8BAAC,iBAAc,kBAAiB,YAAW,WAAU,wTACnD;AAAA,IAAC;AAAA;AAAA,MACC,UAAU,CAAC,MAAM;AACf,UAAE,eAAe;AACjB,qBAAa;AAAA,MACf;AAAA,MACA,WAAU;AAAA,MAEV;AAAA,6BAAC,SAAI,WAAU,+DACb;AAAA,8BAAC,SAAI,WAAU,oEACb,8BAAC,mBAAgB,MAAM,IAAI,WAAU,iBAAgB,GACvD;AAAA,UACA,qBAAC,gBAAa,WAAU,aACtB;AAAA,gCAAC,eAAY,WAAU,2CACpB,oBAAU,uCAAuC,GACpD;AAAA,YACA,oBAAC,qBAAkB,WAAU,yCAC1B,oBAAU,6CAA6C,GAC1D;AAAA,aACF;AAAA,UAEA,qBAAC,SAAI,WAAU,uBACb;AAAA,gCAAC,UAAK,WAAU,wCACb,oBAAU,4CAA4C,GACzD;AAAA,YACA,oBAAC,YAAS,WAAW,GAAG,SAAS,oBAAoB,OAAO,MAAM,UAAU,SAC1E,8BAAC,iBAAc,WAAU,SACtB,gBAAM,KAAK,EAAE,QAAQ,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,MACjC;AAAA,cAAC;AAAA;AAAA,gBAEC,OAAO;AAAA,gBACP,WAAU;AAAA;AAAA,cAFL;AAAA,YAGP,CACD,GACH,GACF;AAAA,aACF;AAAA,WACF;AAAA,QAEA,qBAAC,SAAI,WAAU,wFACb;AAAA,8BAAC,UAAO,WAAU,gBAAe,UAAU,CAAC,WAAW,WAAW,MAAK,UACpE,sBACG,UAAU,oCAAoC,IAC9C,UAAU,kCAAkC,GAClD;AAAA,UACA;AAAA,YAAC;AAAA;AAAA,cACC,SAAQ;AAAA,cACR,WAAU;AAAA,cACV,MAAK;AAAA,cACL,SAAS;AAAA,cAER,oBAAU,uBAAuB;AAAA;AAAA,UACpC;AAAA,WACF;AAAA;AAAA;AAAA,EACF,GACF,GACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../src/components/account/DisableTwoFactorAuthModal.tsx"],"sourcesContent":["'use client';\n\nimport { useTranslations } from 'next-intl';\nimport { IconShieldCheck } from '@tabler/icons-react';\nimport { Button } from '../ui/buttons/Button';\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n} from '../ui/overlay/Dialog';\nimport { DialogLayer } from '../ui/overlay/layers';\nimport { InputOTP, InputOTPGroup, InputOTPSlot } from '../ui/form/InputOtp';\nimport { REGEXP_ONLY_DIGITS } from 'input-otp';\nimport useDisableTwoFactorAuthForm from './hooks/useDisableTwoFactorAuthForm';\n\ninterface DisableTwoFactorAuthModalProps {\n open: boolean;\n onClose: () => void;\n onSuccess?: () => void;\n}\n\nexport default function DisableTwoFactorAuthModal({\n open,\n onClose,\n onSuccess,\n}: DisableTwoFactorAuthModalProps) {\n const translate = useTranslations();\n const { code, setCode, isValid, isLoading, handleClose, handleSubmit } =\n useDisableTwoFactorAuthForm({ onClose, onSuccess });\n\n return (\n // Abre por cima do modal de configurações da conta, que é irmão na árvore.\n <DialogLayer>\n <Dialog open={open} onOpenChange={handleClose}>\n <DialogContent className=\"flex flex-col p-0 gap-0 max-w-full sm:max-w-full border-0 rounded-t-2xl rounded-b-none h-dvh top-0 bottom-0 left-0 right-0 translate-x-0 translate-y-0 lg:max-w-117.5 lg:h-auto lg:rounded-lg lg:border lg:top-[50%] lg:left-[50%] lg:right-auto lg:bottom-auto lg:translate-x-[-50%] lg:translate-y-[-50%]\">\n <form\n onSubmit={(e) => {\n e.preventDefault();\n handleSubmit();\n }}\n className=\"flex flex-col flex-1 lg:flex-none\"\n >\n <div className=\"flex flex-col gap-4 lg:gap-5 p-4 lg:p-5 flex-1 lg:flex-none\">\n <div className=\"flex items-center justify-center w-fit bg-gray-50 rounded-lg p-2\">\n <IconShieldCheck size={20} className=\"text-gray-600\" />\n </div>\n <DialogHeader className=\"p-0 gap-2\">\n <DialogTitle className=\"paragraph-medium-semibold text-gray-950\">\n {translate('common.account.twoFactor.disableTitle')}\n </DialogTitle>\n <DialogDescription className=\"paragraph-small-regular text-gray-600\">\n {translate('common.account.twoFactor.disableDescription')}\n </DialogDescription>\n </DialogHeader>\n\n <div className=\"flex flex-col gap-2\">\n <span className=\"paragraph-small-medium text-gray-700\">\n {translate('common.account.twoFactor.authenticatorCode')}\n </span>\n <InputOTP maxLength={6} pattern={REGEXP_ONLY_DIGITS} value={code} onChange={setCode}>\n <InputOTPGroup className=\"gap-2\">\n {Array.from({ length: 6 }).map((_, i) => (\n <InputOTPSlot\n key={i}\n index={i}\n className=\"w-11! lg:w-12! h-13! lg:h-14! rounded-lg! text-lg border-gray-200\"\n />\n ))}\n </InputOTPGroup>\n </InputOTP>\n </div>\n </div>\n\n <div className=\"flex flex-row items-center gap-2 p-4 lg:p-5 border-t border-gray-200 mt-auto lg:mt-0\">\n <Button className=\"h-10! flex-1\" disabled={!isValid || isLoading} type=\"submit\">\n {isLoading\n ? translate('common.account.twoFactor.disabling')\n : translate('common.account.twoFactor.disable')}\n </Button>\n <Button\n variant=\"secondary\"\n className=\"h-10! flex-1\"\n type=\"button\"\n onClick={handleClose}\n >\n {translate('common.actions.cancel')}\n </Button>\n </div>\n </form>\n </DialogContent>\n </Dialog>\n </DialogLayer>\n );\n}\n"],"mappings":";AA8CgB,cAEF,YAFE;AA5ChB,SAAS,uBAAuB;AAChC,SAAS,uBAAuB;AAChC,SAAS,cAAc;AACvB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,mBAAmB;AAC5B,SAAS,UAAU,eAAe,oBAAoB;AACtD,SAAS,0BAA0B;AACnC,OAAO,iCAAiC;AAQzB,SAAR,0BAA2C;AAAA,EAChD;AAAA,EACA;AAAA,EACA;AACF,GAAmC;AACjC,QAAM,YAAY,gBAAgB;AAClC,QAAM,EAAE,MAAM,SAAS,SAAS,WAAW,aAAa,aAAa,IACnE,4BAA4B,EAAE,SAAS,UAAU,CAAC;AAEpD;AAAA;AAAA,IAEE,oBAAC,eACC,8BAAC,UAAO,MAAY,cAAc,aAChC,8BAAC,iBAAc,WAAU,+SACvB;AAAA,MAAC;AAAA;AAAA,QACC,UAAU,CAAC,MAAM;AACf,YAAE,eAAe;AACjB,uBAAa;AAAA,QACf;AAAA,QACA,WAAU;AAAA,QAEV;AAAA,+BAAC,SAAI,WAAU,+DACb;AAAA,gCAAC,SAAI,WAAU,oEACb,8BAAC,mBAAgB,MAAM,IAAI,WAAU,iBAAgB,GACvD;AAAA,YACA,qBAAC,gBAAa,WAAU,aACtB;AAAA,kCAAC,eAAY,WAAU,2CACpB,oBAAU,uCAAuC,GACpD;AAAA,cACA,oBAAC,qBAAkB,WAAU,yCAC1B,oBAAU,6CAA6C,GAC1D;AAAA,eACF;AAAA,YAEA,qBAAC,SAAI,WAAU,uBACb;AAAA,kCAAC,UAAK,WAAU,wCACb,oBAAU,4CAA4C,GACzD;AAAA,cACA,oBAAC,YAAS,WAAW,GAAG,SAAS,oBAAoB,OAAO,MAAM,UAAU,SAC1E,8BAAC,iBAAc,WAAU,SACtB,gBAAM,KAAK,EAAE,QAAQ,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,MACjC;AAAA,gBAAC;AAAA;AAAA,kBAEC,OAAO;AAAA,kBACP,WAAU;AAAA;AAAA,gBAFL;AAAA,cAGP,CACD,GACH,GACF;AAAA,eACF;AAAA,aACF;AAAA,UAEA,qBAAC,SAAI,WAAU,wFACb;AAAA,gCAAC,UAAO,WAAU,gBAAe,UAAU,CAAC,WAAW,WAAW,MAAK,UACpE,sBACG,UAAU,oCAAoC,IAC9C,UAAU,kCAAkC,GAClD;AAAA,YACA;AAAA,cAAC;AAAA;AAAA,gBACC,SAAQ;AAAA,gBACR,WAAU;AAAA,gBACV,MAAK;AAAA,gBACL,SAAS;AAAA,gBAER,oBAAU,uBAAuB;AAAA;AAAA,YACpC;AAAA,aACF;AAAA;AAAA;AAAA,IACF,GACF,GACF,GACF;AAAA;AAEJ;","names":[]}
@@ -4,6 +4,7 @@ import { useTranslations } from "next-intl";
4
4
  import { IconX, IconCopy, IconRefresh } from "@tabler/icons-react";
5
5
  import { Button } from "../ui/buttons/Button";
6
6
  import { Dialog, DialogContent, DialogHeader, DialogTitle } from "../ui/overlay/Dialog";
7
+ import { DialogLayer } from "../ui/overlay/layers";
7
8
  import { Separator } from "../ui/data-display/Separator";
8
9
  import { InputOTP, InputOTPGroup, InputOTPSlot } from "../ui/form/InputOtp";
9
10
  import { REGEXP_ONLY_DIGITS } from "input-otp";
@@ -31,16 +32,74 @@ function TwoFactorAuthModal({ open, onClose, onSuccess }) {
31
32
  onClose();
32
33
  };
33
34
  if (step === "recovery") {
34
- return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(
35
+ return (
36
+ // Abre por cima do modal de configurações da conta, que é irmão na árvore.
37
+ /* @__PURE__ */ jsx(DialogLayer, { children: /* @__PURE__ */ jsx(Dialog, { open, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(
38
+ DialogContent,
39
+ {
40
+ showCloseButton: false,
41
+ className: "flex flex-col p-0 gap-0 max-w-full sm:max-w-full border-0 rounded-t-2xl rounded-b-none h-[100dvh] top-0 bottom-0 left-0 right-0 translate-x-0 translate-y-0 lg:max-w-[470px] lg:h-auto lg:rounded-lg lg:border lg:top-[50%] lg:left-[50%] lg:right-auto lg:bottom-auto lg:translate-x-[-50%] lg:translate-y-[-50%]",
42
+ children: [
43
+ /* @__PURE__ */ jsx(DialogHeader, { className: "sr-only", children: /* @__PURE__ */ jsx(DialogTitle, { children: translate("common.account.twoFactor.recoveryTitle") }) }),
44
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center px-4 py-3 relative border-b border-gray-200 lg:border-b-0", children: [
45
+ /* @__PURE__ */ jsx("span", { className: "paragraph-medium-semibold text-gray-950 text-center", children: translate("common.account.twoFactor.recoveryTitle") }),
46
+ /* @__PURE__ */ jsx(
47
+ Button,
48
+ {
49
+ type: "button",
50
+ variant: "ghost",
51
+ className: "size-8! p-0 absolute right-4",
52
+ onClick: handleClose,
53
+ children: /* @__PURE__ */ jsx(IconX, { size: 18 })
54
+ }
55
+ )
56
+ ] }),
57
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-5 lg:gap-6 px-4 lg:px-5 py-5 lg:py-6 flex-1 lg:flex-none", children: [
58
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
59
+ /* @__PURE__ */ jsx("h3", { className: "paragraph-medium-semibold text-gray-950 max-w-[269px]", children: translate("common.account.twoFactor.recoveryHeading") }),
60
+ /* @__PURE__ */ jsxs("div", { className: "paragraph-small-regular text-gray-600", children: [
61
+ /* @__PURE__ */ jsx("p", { children: translate("common.account.twoFactor.recoveryText1") }),
62
+ /* @__PURE__ */ jsx("br", {}),
63
+ /* @__PURE__ */ jsx("p", { children: translate("common.account.twoFactor.recoveryText2") })
64
+ ] })
65
+ ] }),
66
+ /* @__PURE__ */ jsxs("div", { className: "bg-gray-50 rounded-lg p-4 flex flex-col gap-4", children: [
67
+ /* @__PURE__ */ jsx("div", { className: "paragraph-small-medium text-gray-950 whitespace-nowrap", children: backupCodes.map((backupCode, i) => /* @__PURE__ */ jsx("p", { children: backupCode }, i)) }),
68
+ /* @__PURE__ */ jsxs(
69
+ Button,
70
+ {
71
+ type: "button",
72
+ variant: "secondary",
73
+ className: "h-8! w-fit",
74
+ onClick: handleCopyCodes,
75
+ children: [
76
+ /* @__PURE__ */ jsx(IconCopy, { size: 16 }),
77
+ translate("common.account.twoFactor.copyCodes")
78
+ ]
79
+ }
80
+ )
81
+ ] })
82
+ ] }),
83
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center p-4 lg:p-5 border-t border-gray-200 justify-between mt-auto lg:mt-0", children: [
84
+ /* @__PURE__ */ jsx(Button, { variant: "secondary", className: "h-10!", type: "button", onClick: handleClose, children: translate("common.actions.cancel") }),
85
+ /* @__PURE__ */ jsx(Button, { className: "h-10!", type: "button", onClick: handleFinalize, children: translate("common.account.twoFactor.finish") })
86
+ ] })
87
+ ]
88
+ }
89
+ ) }) })
90
+ );
91
+ }
92
+ return (
93
+ // Abre por cima do modal de configurações da conta, que é irmão na árvore.
94
+ /* @__PURE__ */ jsx(DialogLayer, { children: /* @__PURE__ */ jsx(Dialog, { open, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(
35
95
  DialogContent,
36
96
  {
37
97
  showCloseButton: false,
38
- overlayClassName: "z-[1010]",
39
- className: "z-[1011] flex flex-col p-0 gap-0 max-w-full sm:max-w-full border-0 rounded-t-2xl rounded-b-none h-[100dvh] top-0 bottom-0 left-0 right-0 translate-x-0 translate-y-0 lg:max-w-[470px] lg:h-auto lg:rounded-lg lg:border lg:top-[50%] lg:left-[50%] lg:right-auto lg:bottom-auto lg:translate-x-[-50%] lg:translate-y-[-50%]",
98
+ className: "flex flex-col p-0 gap-0 max-w-full sm:max-w-full border-0 rounded-t-2xl rounded-b-none h-[100dvh] top-0 bottom-0 left-0 right-0 translate-x-0 translate-y-0 lg:max-w-[470px] lg:h-auto lg:max-h-[90vh] lg:rounded-lg lg:border lg:top-[50%] lg:left-[50%] lg:right-auto lg:bottom-auto lg:translate-x-[-50%] lg:translate-y-[-50%]",
40
99
  children: [
41
- /* @__PURE__ */ jsx(DialogHeader, { className: "sr-only", children: /* @__PURE__ */ jsx(DialogTitle, { children: translate("common.account.twoFactor.recoveryTitle") }) }),
42
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center px-4 py-3 relative border-b border-gray-200 lg:border-b-0", children: [
43
- /* @__PURE__ */ jsx("span", { className: "paragraph-medium-semibold text-gray-950 text-center", children: translate("common.account.twoFactor.recoveryTitle") }),
100
+ /* @__PURE__ */ jsx(DialogHeader, { className: "sr-only", children: /* @__PURE__ */ jsx(DialogTitle, { children: translate("common.account.twoFactor.title") }) }),
101
+ /* @__PURE__ */ jsxs("div", { className: "shrink-0 flex items-center justify-center px-4 py-3 relative border-b border-gray-200 lg:border-b-0", children: [
102
+ /* @__PURE__ */ jsx("span", { className: "paragraph-medium-semibold text-gray-950 text-center", children: translate("common.account.twoFactor.title") }),
44
103
  /* @__PURE__ */ jsx(
45
104
  Button,
46
105
  {
@@ -52,129 +111,75 @@ function TwoFactorAuthModal({ open, onClose, onSuccess }) {
52
111
  }
53
112
  )
54
113
  ] }),
55
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-5 lg:gap-6 px-4 lg:px-5 py-5 lg:py-6 flex-1 lg:flex-none", children: [
56
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
57
- /* @__PURE__ */ jsx("h3", { className: "paragraph-medium-semibold text-gray-950 max-w-[269px]", children: translate("common.account.twoFactor.recoveryHeading") }),
58
- /* @__PURE__ */ jsxs("div", { className: "paragraph-small-regular text-gray-600", children: [
59
- /* @__PURE__ */ jsx("p", { children: translate("common.account.twoFactor.recoveryText1") }),
60
- /* @__PURE__ */ jsx("br", {}),
61
- /* @__PURE__ */ jsx("p", { children: translate("common.account.twoFactor.recoveryText2") })
62
- ] })
63
- ] }),
64
- /* @__PURE__ */ jsxs("div", { className: "bg-gray-50 rounded-lg p-4 flex flex-col gap-4", children: [
65
- /* @__PURE__ */ jsx("div", { className: "paragraph-small-medium text-gray-950 whitespace-nowrap", children: backupCodes.map((backupCode, i) => /* @__PURE__ */ jsx("p", { children: backupCode }, i)) }),
66
- /* @__PURE__ */ jsxs(
67
- Button,
68
- {
69
- type: "button",
70
- variant: "secondary",
71
- className: "h-8! w-fit",
72
- onClick: handleCopyCodes,
73
- children: [
74
- /* @__PURE__ */ jsx(IconCopy, { size: 16 }),
75
- translate("common.account.twoFactor.copyCodes")
76
- ]
77
- }
78
- )
79
- ] })
80
- ] }),
81
- /* @__PURE__ */ jsxs("div", { className: "flex items-center p-4 lg:p-5 border-t border-gray-200 justify-between mt-auto lg:mt-0", children: [
82
- /* @__PURE__ */ jsx(Button, { variant: "secondary", className: "h-10!", type: "button", onClick: handleClose, children: translate("common.actions.cancel") }),
83
- /* @__PURE__ */ jsx(Button, { className: "h-10!", type: "button", onClick: handleFinalize, children: translate("common.account.twoFactor.finish") })
84
- ] })
85
- ]
86
- }
87
- ) });
88
- }
89
- return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(
90
- DialogContent,
91
- {
92
- showCloseButton: false,
93
- overlayClassName: "z-[1010]",
94
- className: "z-[1011] flex flex-col p-0 gap-0 max-w-full sm:max-w-full border-0 rounded-t-2xl rounded-b-none h-[100dvh] top-0 bottom-0 left-0 right-0 translate-x-0 translate-y-0 lg:max-w-[470px] lg:h-auto lg:max-h-[90vh] lg:rounded-lg lg:border lg:top-[50%] lg:left-[50%] lg:right-auto lg:bottom-auto lg:translate-x-[-50%] lg:translate-y-[-50%]",
95
- children: [
96
- /* @__PURE__ */ jsx(DialogHeader, { className: "sr-only", children: /* @__PURE__ */ jsx(DialogTitle, { children: translate("common.account.twoFactor.title") }) }),
97
- /* @__PURE__ */ jsxs("div", { className: "shrink-0 flex items-center justify-center px-4 py-3 relative border-b border-gray-200 lg:border-b-0", children: [
98
- /* @__PURE__ */ jsx("span", { className: "paragraph-medium-semibold text-gray-950 text-center", children: translate("common.account.twoFactor.title") }),
99
- /* @__PURE__ */ jsx(
100
- Button,
114
+ /* @__PURE__ */ jsxs(
115
+ "form",
101
116
  {
102
- type: "button",
103
- variant: "ghost",
104
- className: "size-8! p-0 absolute right-4",
105
- onClick: handleClose,
106
- children: /* @__PURE__ */ jsx(IconX, { size: 18 })
107
- }
108
- )
109
- ] }),
110
- /* @__PURE__ */ jsxs(
111
- "form",
112
- {
113
- className: "flex-1 min-h-0 flex flex-col",
114
- onSubmit: (e) => {
115
- e.preventDefault();
116
- if (isCodeComplete) handleSubmit();
117
- },
118
- children: [
119
- /* @__PURE__ */ jsx("div", { className: "flex-1 min-h-0 overflow-y-auto overscroll-contain lg:overflow-visible", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-4 lg:gap-8 px-4 lg:px-5 py-4 lg:py-6 pb-60 lg:pb-6", children: [
120
- /* @__PURE__ */ jsx("p", { className: "paragraph-small-regular text-gray-950 text-center max-w-full lg:max-w-[412px]", children: translate.rich("common.account.twoFactor.instructions", {
121
- link: (chunks) => /* @__PURE__ */ jsx(
122
- "a",
117
+ className: "flex-1 min-h-0 flex flex-col",
118
+ onSubmit: (e) => {
119
+ e.preventDefault();
120
+ if (isCodeComplete) handleSubmit();
121
+ },
122
+ children: [
123
+ /* @__PURE__ */ jsx("div", { className: "flex-1 min-h-0 overflow-y-auto overscroll-contain lg:overflow-visible", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-4 lg:gap-8 px-4 lg:px-5 py-4 lg:py-6 pb-60 lg:pb-6", children: [
124
+ /* @__PURE__ */ jsx("p", { className: "paragraph-small-regular text-gray-950 text-center max-w-full lg:max-w-[412px]", children: translate.rich("common.account.twoFactor.instructions", {
125
+ link: (chunks) => /* @__PURE__ */ jsx(
126
+ "a",
127
+ {
128
+ href: "https://support.google.com/accounts/answer/1066447",
129
+ target: "_blank",
130
+ rel: "noopener noreferrer",
131
+ className: "paragraph-small-medium underline",
132
+ children: chunks
133
+ }
134
+ )
135
+ }) }),
136
+ /* @__PURE__ */ jsx("div", { className: "border border-gray-200 rounded-lg overflow-hidden p-2 lg:p-3 flex items-center justify-center w-[136px] h-[136px] lg:w-[203px] lg:h-[203px]", children: generateFailed ? /* @__PURE__ */ jsxs(
137
+ "button",
123
138
  {
124
- href: "https://support.google.com/accounts/answer/1066447",
125
- target: "_blank",
126
- rel: "noopener noreferrer",
127
- className: "paragraph-small-medium underline",
128
- children: chunks
139
+ type: "button",
140
+ onClick: () => retryGenerate(),
141
+ className: "flex flex-col items-center gap-1.5 text-center",
142
+ children: [
143
+ /* @__PURE__ */ jsx(IconRefresh, { size: 20, className: "text-gray-400" }),
144
+ /* @__PURE__ */ jsx("span", { className: "paragraph-xsmall-medium text-gray-500", children: translate("common.account.twoFactor.retry") })
145
+ ]
129
146
  }
130
- )
131
- }) }),
132
- /* @__PURE__ */ jsx("div", { className: "border border-gray-200 rounded-lg overflow-hidden p-2 lg:p-3 flex items-center justify-center w-[136px] h-[136px] lg:w-[203px] lg:h-[203px]", children: generateFailed ? /* @__PURE__ */ jsxs(
133
- "button",
134
- {
135
- type: "button",
136
- onClick: () => retryGenerate(),
137
- className: "flex flex-col items-center gap-1.5 text-center",
138
- children: [
139
- /* @__PURE__ */ jsx(IconRefresh, { size: 20, className: "text-gray-400" }),
140
- /* @__PURE__ */ jsx("span", { className: "paragraph-xsmall-medium text-gray-500", children: translate("common.account.twoFactor.retry") })
141
- ]
142
- }
143
- ) : isGenerating || !qrcode ? /* @__PURE__ */ jsx("div", { className: "skeleton w-full h-full rounded" }) : (
144
- // eslint-disable-next-line @next/next/no-img-element
145
- /* @__PURE__ */ jsx(
146
- "img",
147
+ ) : isGenerating || !qrcode ? /* @__PURE__ */ jsx("div", { className: "skeleton w-full h-full rounded" }) : (
148
+ // eslint-disable-next-line @next/next/no-img-element
149
+ /* @__PURE__ */ jsx(
150
+ "img",
151
+ {
152
+ src: qrcode,
153
+ alt: translate("common.account.twoFactor.qrAlt"),
154
+ className: "w-full h-full"
155
+ }
156
+ )
157
+ ) }),
158
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 w-full", children: [
159
+ /* @__PURE__ */ jsx(Separator, { className: "flex-1" }),
160
+ /* @__PURE__ */ jsx("span", { className: "paragraph-xsmall-medium text-gray-500 opacity-80 whitespace-nowrap", children: translate("common.account.twoFactor.pasteDigits") }),
161
+ /* @__PURE__ */ jsx(Separator, { className: "flex-1" })
162
+ ] }),
163
+ /* @__PURE__ */ jsx("div", { className: "scroll-mt-20", children: /* @__PURE__ */ jsx(InputOTP, { maxLength: 6, pattern: REGEXP_ONLY_DIGITS, value: code, onChange: setCode, children: /* @__PURE__ */ jsx(InputOTPGroup, { className: "gap-2", children: Array.from({ length: 6 }).map((_, i) => /* @__PURE__ */ jsx(
164
+ InputOTPSlot,
147
165
  {
148
- src: qrcode,
149
- alt: translate("common.account.twoFactor.qrAlt"),
150
- className: "w-full h-full"
151
- }
152
- )
153
- ) }),
154
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 w-full", children: [
155
- /* @__PURE__ */ jsx(Separator, { className: "flex-1" }),
156
- /* @__PURE__ */ jsx("span", { className: "paragraph-xsmall-medium text-gray-500 opacity-80 whitespace-nowrap", children: translate("common.account.twoFactor.pasteDigits") }),
157
- /* @__PURE__ */ jsx(Separator, { className: "flex-1" })
158
- ] }),
159
- /* @__PURE__ */ jsx("div", { className: "scroll-mt-20", children: /* @__PURE__ */ jsx(InputOTP, { maxLength: 6, pattern: REGEXP_ONLY_DIGITS, value: code, onChange: setCode, children: /* @__PURE__ */ jsx(InputOTPGroup, { className: "gap-2", children: Array.from({ length: 6 }).map((_, i) => /* @__PURE__ */ jsx(
160
- InputOTPSlot,
161
- {
162
- index: i,
163
- className: "w-11! lg:w-12! h-13! lg:h-14! rounded-lg! text-lg border-gray-200"
164
- },
165
- i
166
- )) }) }) })
167
- ] }) }),
168
- /* @__PURE__ */ jsxs("div", { className: "shrink-0 flex items-center p-4 lg:p-5 border-t border-gray-200 justify-between gap-2 bg-white", children: [
169
- /* @__PURE__ */ jsx(Button, { variant: "secondary", className: "h-10!", type: "button", onClick: handleClose, children: translate("common.actions.cancel") }),
170
- /* @__PURE__ */ jsx(Button, { type: "submit", className: "h-10!", disabled: !isCodeComplete || isConfirming, children: isConfirming ? translate("common.account.twoFactor.activating") : translate("common.account.twoFactor.activate") })
171
- ] })
172
- ]
173
- }
174
- )
175
- ]
176
- }
177
- ) });
166
+ index: i,
167
+ className: "w-11! lg:w-12! h-13! lg:h-14! rounded-lg! text-lg border-gray-200"
168
+ },
169
+ i
170
+ )) }) }) })
171
+ ] }) }),
172
+ /* @__PURE__ */ jsxs("div", { className: "shrink-0 flex items-center p-4 lg:p-5 border-t border-gray-200 justify-between gap-2 bg-white", children: [
173
+ /* @__PURE__ */ jsx(Button, { variant: "secondary", className: "h-10!", type: "button", onClick: handleClose, children: translate("common.actions.cancel") }),
174
+ /* @__PURE__ */ jsx(Button, { type: "submit", className: "h-10!", disabled: !isCodeComplete || isConfirming, children: isConfirming ? translate("common.account.twoFactor.activating") : translate("common.account.twoFactor.activate") })
175
+ ] })
176
+ ]
177
+ }
178
+ )
179
+ ]
180
+ }
181
+ ) }) })
182
+ );
178
183
  }
179
184
  export {
180
185
  TwoFactorAuthModal as default
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/account/TwoFactorAuthModal.tsx"],"sourcesContent":["'use client';\n\nimport { useTranslations } from 'next-intl';\nimport { IconX, IconCopy, IconRefresh } from '@tabler/icons-react';\nimport { Button } from '../ui/buttons/Button';\nimport { Dialog, DialogContent, DialogHeader, DialogTitle } from '../ui/overlay/Dialog';\nimport { Separator } from '../ui/data-display/Separator';\nimport { InputOTP, InputOTPGroup, InputOTPSlot } from '../ui/form/InputOtp';\nimport { REGEXP_ONLY_DIGITS } from 'input-otp';\nimport useTwoFactorAuthForm from './hooks/useTwoFactorAuthForm';\n\ninterface TwoFactorAuthModalProps {\n open: boolean;\n onClose: () => void;\n onSuccess?: () => void;\n}\n\nexport default function TwoFactorAuthModal({ open, onClose, onSuccess }: TwoFactorAuthModalProps) {\n const translate = useTranslations();\n const {\n code,\n setCode,\n isCodeComplete,\n isGenerating,\n isConfirming,\n generateFailed,\n retryGenerate,\n qrcode,\n backupCodes,\n step,\n handleSubmit,\n handleFinalize,\n handleCopyCodes,\n resetForm,\n } = useTwoFactorAuthForm({ onSuccess, open });\n\n const handleClose = () => {\n resetForm();\n onClose();\n };\n\n if (step === 'recovery') {\n return (\n <Dialog open={open} onOpenChange={handleClose}>\n <DialogContent\n showCloseButton={false}\n overlayClassName=\"z-[1010]\"\n className=\"z-[1011] flex flex-col p-0 gap-0 max-w-full sm:max-w-full border-0 rounded-t-2xl rounded-b-none h-[100dvh] top-0 bottom-0 left-0 right-0 translate-x-0 translate-y-0 lg:max-w-[470px] lg:h-auto lg:rounded-lg lg:border lg:top-[50%] lg:left-[50%] lg:right-auto lg:bottom-auto lg:translate-x-[-50%] lg:translate-y-[-50%]\"\n >\n <DialogHeader className=\"sr-only\">\n <DialogTitle>{translate('common.account.twoFactor.recoveryTitle')}</DialogTitle>\n </DialogHeader>\n <div className=\"flex items-center justify-center px-4 py-3 relative border-b border-gray-200 lg:border-b-0\">\n <span className=\"paragraph-medium-semibold text-gray-950 text-center\">\n {translate('common.account.twoFactor.recoveryTitle')}\n </span>\n <Button\n type=\"button\"\n variant=\"ghost\"\n className=\"size-8! p-0 absolute right-4\"\n onClick={handleClose}\n >\n <IconX size={18} />\n </Button>\n </div>\n\n <div className=\"flex flex-col gap-5 lg:gap-6 px-4 lg:px-5 py-5 lg:py-6 flex-1 lg:flex-none\">\n <div className=\"flex flex-col gap-2\">\n <h3 className=\"paragraph-medium-semibold text-gray-950 max-w-[269px]\">\n {translate('common.account.twoFactor.recoveryHeading')}\n </h3>\n <div className=\"paragraph-small-regular text-gray-600\">\n <p>{translate('common.account.twoFactor.recoveryText1')}</p>\n <br />\n <p>{translate('common.account.twoFactor.recoveryText2')}</p>\n </div>\n </div>\n\n <div className=\"bg-gray-50 rounded-lg p-4 flex flex-col gap-4\">\n <div className=\"paragraph-small-medium text-gray-950 whitespace-nowrap\">\n {backupCodes.map((backupCode, i) => (\n <p key={i}>{backupCode}</p>\n ))}\n </div>\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"h-8! w-fit\"\n onClick={handleCopyCodes}\n >\n <IconCopy size={16} />\n {translate('common.account.twoFactor.copyCodes')}\n </Button>\n </div>\n </div>\n\n <div className=\"flex items-center p-4 lg:p-5 border-t border-gray-200 justify-between mt-auto lg:mt-0\">\n <Button variant=\"secondary\" className=\"h-10!\" type=\"button\" onClick={handleClose}>\n {translate('common.actions.cancel')}\n </Button>\n <Button className=\"h-10!\" type=\"button\" onClick={handleFinalize}>\n {translate('common.account.twoFactor.finish')}\n </Button>\n </div>\n </DialogContent>\n </Dialog>\n );\n }\n\n return (\n <Dialog open={open} onOpenChange={handleClose}>\n <DialogContent\n showCloseButton={false}\n overlayClassName=\"z-[1010]\"\n className=\"z-[1011] flex flex-col p-0 gap-0 max-w-full sm:max-w-full border-0 rounded-t-2xl rounded-b-none h-[100dvh] top-0 bottom-0 left-0 right-0 translate-x-0 translate-y-0 lg:max-w-[470px] lg:h-auto lg:max-h-[90vh] lg:rounded-lg lg:border lg:top-[50%] lg:left-[50%] lg:right-auto lg:bottom-auto lg:translate-x-[-50%] lg:translate-y-[-50%]\"\n >\n <DialogHeader className=\"sr-only\">\n <DialogTitle>{translate('common.account.twoFactor.title')}</DialogTitle>\n </DialogHeader>\n <div className=\"shrink-0 flex items-center justify-center px-4 py-3 relative border-b border-gray-200 lg:border-b-0\">\n <span className=\"paragraph-medium-semibold text-gray-950 text-center\">\n {translate('common.account.twoFactor.title')}\n </span>\n <Button\n type=\"button\"\n variant=\"ghost\"\n className=\"size-8! p-0 absolute right-4\"\n onClick={handleClose}\n >\n <IconX size={18} />\n </Button>\n </div>\n\n <form\n className=\"flex-1 min-h-0 flex flex-col\"\n onSubmit={(e) => {\n e.preventDefault();\n if (isCodeComplete) handleSubmit();\n }}\n >\n <div className=\"flex-1 min-h-0 overflow-y-auto overscroll-contain lg:overflow-visible\">\n <div className=\"flex flex-col items-center gap-4 lg:gap-8 px-4 lg:px-5 py-4 lg:py-6 pb-60 lg:pb-6\">\n <p className=\"paragraph-small-regular text-gray-950 text-center max-w-full lg:max-w-[412px]\">\n {translate.rich('common.account.twoFactor.instructions', {\n link: (chunks) => (\n <a\n href=\"https://support.google.com/accounts/answer/1066447\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"paragraph-small-medium underline\"\n >\n {chunks}\n </a>\n ),\n })}\n </p>\n\n <div className=\"border border-gray-200 rounded-lg overflow-hidden p-2 lg:p-3 flex items-center justify-center w-[136px] h-[136px] lg:w-[203px] lg:h-[203px]\">\n {generateFailed ? (\n <button\n type=\"button\"\n onClick={() => retryGenerate()}\n className=\"flex flex-col items-center gap-1.5 text-center\"\n >\n <IconRefresh size={20} className=\"text-gray-400\" />\n <span className=\"paragraph-xsmall-medium text-gray-500\">\n {translate('common.account.twoFactor.retry')}\n </span>\n </button>\n ) : isGenerating || !qrcode ? (\n <div className=\"skeleton w-full h-full rounded\" />\n ) : (\n // eslint-disable-next-line @next/next/no-img-element\n <img\n src={qrcode}\n alt={translate('common.account.twoFactor.qrAlt')}\n className=\"w-full h-full\"\n />\n )}\n </div>\n\n <div className=\"flex items-center gap-3 w-full\">\n <Separator className=\"flex-1\" />\n <span className=\"paragraph-xsmall-medium text-gray-500 opacity-80 whitespace-nowrap\">\n {translate('common.account.twoFactor.pasteDigits')}\n </span>\n <Separator className=\"flex-1\" />\n </div>\n\n <div className=\"scroll-mt-20\">\n <InputOTP maxLength={6} pattern={REGEXP_ONLY_DIGITS} value={code} onChange={setCode}>\n <InputOTPGroup className=\"gap-2\">\n {Array.from({ length: 6 }).map((_, i) => (\n <InputOTPSlot\n key={i}\n index={i}\n className=\"w-11! lg:w-12! h-13! lg:h-14! rounded-lg! text-lg border-gray-200\"\n />\n ))}\n </InputOTPGroup>\n </InputOTP>\n </div>\n </div>\n </div>\n\n <div className=\"shrink-0 flex items-center p-4 lg:p-5 border-t border-gray-200 justify-between gap-2 bg-white\">\n <Button variant=\"secondary\" className=\"h-10!\" type=\"button\" onClick={handleClose}>\n {translate('common.actions.cancel')}\n </Button>\n <Button type=\"submit\" className=\"h-10!\" disabled={!isCodeComplete || isConfirming}>\n {isConfirming\n ? translate('common.account.twoFactor.activating')\n : translate('common.account.twoFactor.activate')}\n </Button>\n </div>\n </form>\n </DialogContent>\n </Dialog>\n );\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/components/account/TwoFactorAuthModal.tsx"],"sourcesContent":["'use client';\n\nimport { useTranslations } from 'next-intl';\nimport { IconX, IconCopy, IconRefresh } from '@tabler/icons-react';\nimport { Button } from '../ui/buttons/Button';\nimport { Dialog, DialogContent, DialogHeader, DialogTitle } from '../ui/overlay/Dialog';\nimport { DialogLayer } from '../ui/overlay/layers';\nimport { Separator } from '../ui/data-display/Separator';\nimport { InputOTP, InputOTPGroup, InputOTPSlot } from '../ui/form/InputOtp';\nimport { REGEXP_ONLY_DIGITS } from 'input-otp';\nimport useTwoFactorAuthForm from './hooks/useTwoFactorAuthForm';\n\ninterface TwoFactorAuthModalProps {\n open: boolean;\n onClose: () => void;\n onSuccess?: () => void;\n}\n\nexport default function TwoFactorAuthModal({ open, onClose, onSuccess }: TwoFactorAuthModalProps) {\n const translate = useTranslations();\n const {\n code,\n setCode,\n isCodeComplete,\n isGenerating,\n isConfirming,\n generateFailed,\n retryGenerate,\n qrcode,\n backupCodes,\n step,\n handleSubmit,\n handleFinalize,\n handleCopyCodes,\n resetForm,\n } = useTwoFactorAuthForm({ onSuccess, open });\n\n const handleClose = () => {\n resetForm();\n onClose();\n };\n\n if (step === 'recovery') {\n return (\n // Abre por cima do modal de configurações da conta, que é irmão na árvore.\n <DialogLayer>\n <Dialog open={open} onOpenChange={handleClose}>\n <DialogContent\n showCloseButton={false}\n className=\"flex flex-col p-0 gap-0 max-w-full sm:max-w-full border-0 rounded-t-2xl rounded-b-none h-[100dvh] top-0 bottom-0 left-0 right-0 translate-x-0 translate-y-0 lg:max-w-[470px] lg:h-auto lg:rounded-lg lg:border lg:top-[50%] lg:left-[50%] lg:right-auto lg:bottom-auto lg:translate-x-[-50%] lg:translate-y-[-50%]\"\n >\n <DialogHeader className=\"sr-only\">\n <DialogTitle>{translate('common.account.twoFactor.recoveryTitle')}</DialogTitle>\n </DialogHeader>\n <div className=\"flex items-center justify-center px-4 py-3 relative border-b border-gray-200 lg:border-b-0\">\n <span className=\"paragraph-medium-semibold text-gray-950 text-center\">\n {translate('common.account.twoFactor.recoveryTitle')}\n </span>\n <Button\n type=\"button\"\n variant=\"ghost\"\n className=\"size-8! p-0 absolute right-4\"\n onClick={handleClose}\n >\n <IconX size={18} />\n </Button>\n </div>\n\n <div className=\"flex flex-col gap-5 lg:gap-6 px-4 lg:px-5 py-5 lg:py-6 flex-1 lg:flex-none\">\n <div className=\"flex flex-col gap-2\">\n <h3 className=\"paragraph-medium-semibold text-gray-950 max-w-[269px]\">\n {translate('common.account.twoFactor.recoveryHeading')}\n </h3>\n <div className=\"paragraph-small-regular text-gray-600\">\n <p>{translate('common.account.twoFactor.recoveryText1')}</p>\n <br />\n <p>{translate('common.account.twoFactor.recoveryText2')}</p>\n </div>\n </div>\n\n <div className=\"bg-gray-50 rounded-lg p-4 flex flex-col gap-4\">\n <div className=\"paragraph-small-medium text-gray-950 whitespace-nowrap\">\n {backupCodes.map((backupCode, i) => (\n <p key={i}>{backupCode}</p>\n ))}\n </div>\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"h-8! w-fit\"\n onClick={handleCopyCodes}\n >\n <IconCopy size={16} />\n {translate('common.account.twoFactor.copyCodes')}\n </Button>\n </div>\n </div>\n\n <div className=\"flex items-center p-4 lg:p-5 border-t border-gray-200 justify-between mt-auto lg:mt-0\">\n <Button variant=\"secondary\" className=\"h-10!\" type=\"button\" onClick={handleClose}>\n {translate('common.actions.cancel')}\n </Button>\n <Button className=\"h-10!\" type=\"button\" onClick={handleFinalize}>\n {translate('common.account.twoFactor.finish')}\n </Button>\n </div>\n </DialogContent>\n </Dialog>\n </DialogLayer>\n );\n }\n\n return (\n // Abre por cima do modal de configurações da conta, que é irmão na árvore.\n <DialogLayer>\n <Dialog open={open} onOpenChange={handleClose}>\n <DialogContent\n showCloseButton={false}\n className=\"flex flex-col p-0 gap-0 max-w-full sm:max-w-full border-0 rounded-t-2xl rounded-b-none h-[100dvh] top-0 bottom-0 left-0 right-0 translate-x-0 translate-y-0 lg:max-w-[470px] lg:h-auto lg:max-h-[90vh] lg:rounded-lg lg:border lg:top-[50%] lg:left-[50%] lg:right-auto lg:bottom-auto lg:translate-x-[-50%] lg:translate-y-[-50%]\"\n >\n <DialogHeader className=\"sr-only\">\n <DialogTitle>{translate('common.account.twoFactor.title')}</DialogTitle>\n </DialogHeader>\n <div className=\"shrink-0 flex items-center justify-center px-4 py-3 relative border-b border-gray-200 lg:border-b-0\">\n <span className=\"paragraph-medium-semibold text-gray-950 text-center\">\n {translate('common.account.twoFactor.title')}\n </span>\n <Button\n type=\"button\"\n variant=\"ghost\"\n className=\"size-8! p-0 absolute right-4\"\n onClick={handleClose}\n >\n <IconX size={18} />\n </Button>\n </div>\n\n <form\n className=\"flex-1 min-h-0 flex flex-col\"\n onSubmit={(e) => {\n e.preventDefault();\n if (isCodeComplete) handleSubmit();\n }}\n >\n <div className=\"flex-1 min-h-0 overflow-y-auto overscroll-contain lg:overflow-visible\">\n <div className=\"flex flex-col items-center gap-4 lg:gap-8 px-4 lg:px-5 py-4 lg:py-6 pb-60 lg:pb-6\">\n <p className=\"paragraph-small-regular text-gray-950 text-center max-w-full lg:max-w-[412px]\">\n {translate.rich('common.account.twoFactor.instructions', {\n link: (chunks) => (\n <a\n href=\"https://support.google.com/accounts/answer/1066447\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"paragraph-small-medium underline\"\n >\n {chunks}\n </a>\n ),\n })}\n </p>\n\n <div className=\"border border-gray-200 rounded-lg overflow-hidden p-2 lg:p-3 flex items-center justify-center w-[136px] h-[136px] lg:w-[203px] lg:h-[203px]\">\n {generateFailed ? (\n <button\n type=\"button\"\n onClick={() => retryGenerate()}\n className=\"flex flex-col items-center gap-1.5 text-center\"\n >\n <IconRefresh size={20} className=\"text-gray-400\" />\n <span className=\"paragraph-xsmall-medium text-gray-500\">\n {translate('common.account.twoFactor.retry')}\n </span>\n </button>\n ) : isGenerating || !qrcode ? (\n <div className=\"skeleton w-full h-full rounded\" />\n ) : (\n // eslint-disable-next-line @next/next/no-img-element\n <img\n src={qrcode}\n alt={translate('common.account.twoFactor.qrAlt')}\n className=\"w-full h-full\"\n />\n )}\n </div>\n\n <div className=\"flex items-center gap-3 w-full\">\n <Separator className=\"flex-1\" />\n <span className=\"paragraph-xsmall-medium text-gray-500 opacity-80 whitespace-nowrap\">\n {translate('common.account.twoFactor.pasteDigits')}\n </span>\n <Separator className=\"flex-1\" />\n </div>\n\n <div className=\"scroll-mt-20\">\n <InputOTP maxLength={6} pattern={REGEXP_ONLY_DIGITS} value={code} onChange={setCode}>\n <InputOTPGroup className=\"gap-2\">\n {Array.from({ length: 6 }).map((_, i) => (\n <InputOTPSlot\n key={i}\n index={i}\n className=\"w-11! lg:w-12! h-13! lg:h-14! rounded-lg! text-lg border-gray-200\"\n />\n ))}\n </InputOTPGroup>\n </InputOTP>\n </div>\n </div>\n </div>\n\n <div className=\"shrink-0 flex items-center p-4 lg:p-5 border-t border-gray-200 justify-between gap-2 bg-white\">\n <Button variant=\"secondary\" className=\"h-10!\" type=\"button\" onClick={handleClose}>\n {translate('common.actions.cancel')}\n </Button>\n <Button type=\"submit\" className=\"h-10!\" disabled={!isCodeComplete || isConfirming}>\n {isConfirming\n ? translate('common.account.twoFactor.activating')\n : translate('common.account.twoFactor.activate')}\n </Button>\n </div>\n </form>\n </DialogContent>\n </Dialog>\n </DialogLayer>\n );\n}\n"],"mappings":"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","names":[]}
@@ -1,16 +1,19 @@
1
1
  "use client";
2
2
  import { Fragment, jsx } from "react/jsx-runtime";
3
+ import { useContext } from "react";
3
4
  import { useModalManager } from "../../store/useModalManager";
5
+ import { DialogDepthContext } from "../ui/overlay/layers";
4
6
  function ModalManager({ registry }) {
5
7
  const { modalStack } = useModalManager();
8
+ const depth = useContext(DialogDepthContext);
6
9
  if (modalStack.length === 0) return null;
7
- return /* @__PURE__ */ jsx(Fragment, { children: modalStack.map((modal) => {
10
+ return /* @__PURE__ */ jsx(Fragment, { children: modalStack.map((modal, index) => {
8
11
  const ModalComponent = registry[modal.key];
9
12
  if (!ModalComponent) {
10
13
  console.warn(`Modal "${modal.key}" not found in registry`);
11
14
  return null;
12
15
  }
13
- return /* @__PURE__ */ jsx(ModalComponent, {}, modal.key);
16
+ return /* @__PURE__ */ jsx(DialogDepthContext.Provider, { value: depth + index, children: /* @__PURE__ */ jsx(ModalComponent, {}) }, modal.key);
14
17
  }) });
15
18
  }
16
19
  export {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/modals/ModalManager.tsx"],"sourcesContent":["'use client';\n\nimport { ComponentType } from 'react';\nimport { useModalManager } from '../../store/useModalManager';\n\ninterface ModalManagerProps {\n registry: Record<string, ComponentType>;\n}\n\nexport function ModalManager({ registry }: ModalManagerProps) {\n const { modalStack } = useModalManager();\n\n if (modalStack.length === 0) return null;\n\n return (\n <>\n {modalStack.map((modal) => {\n const ModalComponent = registry[modal.key];\n\n if (!ModalComponent) {\n console.warn(`Modal \"${modal.key}\" not found in registry`);\n return null;\n }\n\n return <ModalComponent key={modal.key} />;\n })}\n </>\n );\n}\n"],"mappings":";AAeI,mBASW,WATX;AAZJ,SAAS,uBAAuB;AAMzB,SAAS,aAAa,EAAE,SAAS,GAAsB;AAC5D,QAAM,EAAE,WAAW,IAAI,gBAAgB;AAEvC,MAAI,WAAW,WAAW,EAAG,QAAO;AAEpC,SACE,gCACG,qBAAW,IAAI,CAAC,UAAU;AACzB,UAAM,iBAAiB,SAAS,MAAM,GAAG;AAEzC,QAAI,CAAC,gBAAgB;AACnB,cAAQ,KAAK,UAAU,MAAM,GAAG,yBAAyB;AACzD,aAAO;AAAA,IACT;AAEA,WAAO,oBAAC,oBAAoB,MAAM,GAAK;AAAA,EACzC,CAAC,GACH;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../src/components/modals/ModalManager.tsx"],"sourcesContent":["'use client';\n\nimport { ComponentType, useContext } from 'react';\nimport { useModalManager } from '../../store/useModalManager';\nimport { DialogDepthContext } from '../ui/overlay/layers';\n\ninterface ModalManagerProps {\n registry: Record<string, ComponentType>;\n}\n\nexport function ModalManager({ registry }: ModalManagerProps) {\n const { modalStack } = useModalManager();\n const depth = useContext(DialogDepthContext);\n\n if (modalStack.length === 0) return null;\n\n // Modais da pilha nascem irmaos na arvore React: sem isso, todos cairiam na\n // mesma profundidade e na mesma faixa de z-index (ver layers.tsx). A\n // posicao na pilha vira a profundidade, relativa a onde o ModalManager\n // esta montado.\n return (\n <>\n {modalStack.map((modal, index) => {\n const ModalComponent = registry[modal.key];\n\n if (!ModalComponent) {\n console.warn(`Modal \"${modal.key}\" not found in registry`);\n return null;\n }\n\n return (\n <DialogDepthContext.Provider value={depth + index} key={modal.key}>\n <ModalComponent />\n </DialogDepthContext.Provider>\n );\n })}\n </>\n );\n}\n"],"mappings":";AAqBI,mBAWQ,WAXR;AAnBJ,SAAwB,kBAAkB;AAC1C,SAAS,uBAAuB;AAChC,SAAS,0BAA0B;AAM5B,SAAS,aAAa,EAAE,SAAS,GAAsB;AAC5D,QAAM,EAAE,WAAW,IAAI,gBAAgB;AACvC,QAAM,QAAQ,WAAW,kBAAkB;AAE3C,MAAI,WAAW,WAAW,EAAG,QAAO;AAMpC,SACE,gCACG,qBAAW,IAAI,CAAC,OAAO,UAAU;AAChC,UAAM,iBAAiB,SAAS,MAAM,GAAG;AAEzC,QAAI,CAAC,gBAAgB;AACnB,cAAQ,KAAK,UAAU,MAAM,GAAG,yBAAyB;AACzD,aAAO;AAAA,IACT;AAEA,WACE,oBAAC,mBAAmB,UAAnB,EAA4B,OAAO,QAAQ,OAC1C,8BAAC,kBAAe,KADsC,MAAM,GAE9D;AAAA,EAEJ,CAAC,GACH;AAEJ;","names":[]}
@@ -8,6 +8,7 @@ import {
8
8
  DialogHeader,
9
9
  DialogTitle
10
10
  } from "../../ui/overlay/Dialog";
11
+ import { DialogLayer } from "../../ui/overlay/layers";
11
12
  import { Button } from "../../ui/buttons/Button";
12
13
  function ImageTooSmallModal({
13
14
  open,
@@ -20,21 +21,17 @@ function ImageTooSmallModal({
20
21
  }) {
21
22
  const translate = useTranslations();
22
23
  const dimensionText = `${minWidth}x${minHeight}px`;
23
- return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs(
24
- DialogContent,
25
- {
26
- className: "w-full md:w-[480px]! lg:w-[480px]! max-w-[480px]! max-[480px]:w-[calc(100%-32px)] p-0 gap-0 z-[1003]",
27
- overlayClassName: "z-[1002]",
28
- children: [
29
- /* @__PURE__ */ jsx(DialogHeader, { className: "p-5", children: /* @__PURE__ */ jsx(DialogTitle, { className: "text-center text-[16px]!", children: translate("common.imageUpload.tooSmallTitleWithDimension", { dimensionText }) }) }),
30
- /* @__PURE__ */ jsx("div", { className: "px-5 pb-5", children: /* @__PURE__ */ jsx("p", { className: "paragraph-small-regular text-zinc-600 text-center", children: translate("common.imageUpload.tooSmallBodyFileWithDimension", { fileName, dimensionText }) }) }),
31
- /* @__PURE__ */ jsxs(DialogFooter, { className: "flex-row! items-center justify-start! gap-3 p-5 border-t border-zinc-200", children: [
32
- /* @__PURE__ */ jsx(Button, { onClick: onSelectAnother, children: translate("common.imageUpload.sendAnother") }),
33
- /* @__PURE__ */ jsx(Button, { variant: "secondary", onClick: onCancel, children: translate("common.actions.cancel") })
34
- ] })
35
- ]
36
- }
37
- ) });
24
+ return (
25
+ // Abre por cima do modal/uploader que a disparou.
26
+ /* @__PURE__ */ jsx(DialogLayer, { children: /* @__PURE__ */ jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs(DialogContent, { className: "w-full md:w-[480px]! lg:w-[480px]! max-w-[480px]! max-[480px]:w-[calc(100%-32px)] p-0 gap-0", children: [
27
+ /* @__PURE__ */ jsx(DialogHeader, { className: "p-5", children: /* @__PURE__ */ jsx(DialogTitle, { className: "text-center text-[16px]!", children: translate("common.imageUpload.tooSmallTitleWithDimension", { dimensionText }) }) }),
28
+ /* @__PURE__ */ jsx("div", { className: "px-5 pb-5", children: /* @__PURE__ */ jsx("p", { className: "paragraph-small-regular text-zinc-600 text-center", children: translate("common.imageUpload.tooSmallBodyFileWithDimension", { fileName, dimensionText }) }) }),
29
+ /* @__PURE__ */ jsxs(DialogFooter, { className: "flex-row! items-center justify-start! gap-3 p-5 border-t border-zinc-200", children: [
30
+ /* @__PURE__ */ jsx(Button, { onClick: onSelectAnother, children: translate("common.imageUpload.sendAnother") }),
31
+ /* @__PURE__ */ jsx(Button, { variant: "secondary", onClick: onCancel, children: translate("common.actions.cancel") })
32
+ ] })
33
+ ] }) }) })
34
+ );
38
35
  }
39
36
  export {
40
37
  ImageTooSmallModal
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/widgets/ImageUpload/ImageTooSmallModal.tsx"],"sourcesContent":["'use client'\n\nimport { useTranslations } from 'next-intl'\nimport {\n Dialog,\n DialogContent,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n} from '../../ui/overlay/Dialog'\nimport { Button } from '../../ui/buttons/Button'\n\ninterface ImageTooSmallModalProps {\n open: boolean\n onOpenChange: (open: boolean) => void\n fileName: string\n minWidth: number\n minHeight: number\n onSelectAnother: () => void\n onCancel: () => void\n}\n\nexport function ImageTooSmallModal({\n open,\n onOpenChange,\n fileName,\n minWidth,\n minHeight,\n onSelectAnother,\n onCancel,\n}: ImageTooSmallModalProps) {\n const translate = useTranslations()\n const dimensionText = `${minWidth}x${minHeight}px`\n\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent\n className=\"w-full md:w-[480px]! lg:w-[480px]! max-w-[480px]! max-[480px]:w-[calc(100%-32px)] p-0 gap-0 z-[1003]\"\n overlayClassName=\"z-[1002]\"\n >\n <DialogHeader className=\"p-5\">\n <DialogTitle className=\"text-center text-[16px]!\">\n {translate('common.imageUpload.tooSmallTitleWithDimension', { dimensionText })}\n </DialogTitle>\n </DialogHeader>\n\n <div className=\"px-5 pb-5\">\n <p className=\"paragraph-small-regular text-zinc-600 text-center\">\n {translate('common.imageUpload.tooSmallBodyFileWithDimension', { fileName, dimensionText })}\n </p>\n </div>\n\n <DialogFooter className=\"flex-row! items-center justify-start! gap-3 p-5 border-t border-zinc-200\">\n <Button onClick={onSelectAnother}>{translate('common.imageUpload.sendAnother')}</Button>\n <Button variant=\"secondary\" onClick={onCancel}>\n {translate('common.actions.cancel')}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n )\n}\n"],"mappings":";AAyCU,cAWF,YAXE;AAvCV,SAAS,uBAAuB;AAChC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,cAAc;AAYhB,SAAS,mBAAmB;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA4B;AAC1B,QAAM,YAAY,gBAAgB;AAClC,QAAM,gBAAgB,GAAG,QAAQ,IAAI,SAAS;AAE9C,SACE,oBAAC,UAAO,MAAY,cAClB;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV,kBAAiB;AAAA,MAEjB;AAAA,4BAAC,gBAAa,WAAU,OACtB,8BAAC,eAAY,WAAU,4BACpB,oBAAU,iDAAiD,EAAE,cAAc,CAAC,GAC/E,GACF;AAAA,QAEA,oBAAC,SAAI,WAAU,aACb,8BAAC,OAAE,WAAU,qDACV,oBAAU,oDAAoD,EAAE,UAAU,cAAc,CAAC,GAC5F,GACF;AAAA,QAEA,qBAAC,gBAAa,WAAU,4EACtB;AAAA,8BAAC,UAAO,SAAS,iBAAkB,oBAAU,gCAAgC,GAAE;AAAA,UAC/E,oBAAC,UAAO,SAAQ,aAAY,SAAS,UAClC,oBAAU,uBAAuB,GACpC;AAAA,WACF;AAAA;AAAA;AAAA,EACF,GACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../../src/components/widgets/ImageUpload/ImageTooSmallModal.tsx"],"sourcesContent":["'use client'\n\nimport { useTranslations } from 'next-intl'\nimport {\n Dialog,\n DialogContent,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n} from '../../ui/overlay/Dialog'\nimport { DialogLayer } from '../../ui/overlay/layers'\nimport { Button } from '../../ui/buttons/Button'\n\ninterface ImageTooSmallModalProps {\n open: boolean\n onOpenChange: (open: boolean) => void\n fileName: string\n minWidth: number\n minHeight: number\n onSelectAnother: () => void\n onCancel: () => void\n}\n\nexport function ImageTooSmallModal({\n open,\n onOpenChange,\n fileName,\n minWidth,\n minHeight,\n onSelectAnother,\n onCancel,\n}: ImageTooSmallModalProps) {\n const translate = useTranslations()\n const dimensionText = `${minWidth}x${minHeight}px`\n\n return (\n // Abre por cima do modal/uploader que a disparou.\n <DialogLayer>\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className=\"w-full md:w-[480px]! lg:w-[480px]! max-w-[480px]! max-[480px]:w-[calc(100%-32px)] p-0 gap-0\">\n <DialogHeader className=\"p-5\">\n <DialogTitle className=\"text-center text-[16px]!\">\n {translate('common.imageUpload.tooSmallTitleWithDimension', { dimensionText })}\n </DialogTitle>\n </DialogHeader>\n\n <div className=\"px-5 pb-5\">\n <p className=\"paragraph-small-regular text-zinc-600 text-center\">\n {translate('common.imageUpload.tooSmallBodyFileWithDimension', { fileName, dimensionText })}\n </p>\n </div>\n\n <DialogFooter className=\"flex-row! items-center justify-start! gap-3 p-5 border-t border-zinc-200\">\n <Button onClick={onSelectAnother}>{translate('common.imageUpload.sendAnother')}</Button>\n <Button variant=\"secondary\" onClick={onCancel}>\n {translate('common.actions.cancel')}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n </DialogLayer>\n )\n}\n"],"mappings":";AAyCY,cAWF,YAXE;AAvCZ,SAAS,uBAAuB;AAChC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,mBAAmB;AAC5B,SAAS,cAAc;AAYhB,SAAS,mBAAmB;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA4B;AAC1B,QAAM,YAAY,gBAAgB;AAClC,QAAM,gBAAgB,GAAG,QAAQ,IAAI,SAAS;AAE9C;AAAA;AAAA,IAEE,oBAAC,eACC,8BAAC,UAAO,MAAY,cAClB,+BAAC,iBAAc,WAAU,+FACvB;AAAA,0BAAC,gBAAa,WAAU,OACtB,8BAAC,eAAY,WAAU,4BACpB,oBAAU,iDAAiD,EAAE,cAAc,CAAC,GAC/E,GACF;AAAA,MAEA,oBAAC,SAAI,WAAU,aACb,8BAAC,OAAE,WAAU,qDACV,oBAAU,oDAAoD,EAAE,UAAU,cAAc,CAAC,GAC5F,GACF;AAAA,MAEA,qBAAC,gBAAa,WAAU,4EACtB;AAAA,4BAAC,UAAO,SAAS,iBAAkB,oBAAU,gCAAgC,GAAE;AAAA,QAC/E,oBAAC,UAAO,SAAQ,aAAY,SAAS,UAClC,oBAAU,uBAAuB,GACpC;AAAA,SACF;AAAA,OACF,GACF,GACF;AAAA;AAEJ;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@greatapps/common",
3
- "version": "1.1.777",
3
+ "version": "1.1.778",
4
4
  "description": "Shared library for GreatApps frontend applications",
5
5
  "main": "./dist/index.mjs",
6
6
  "types": "./src/index.ts",
@@ -10,6 +10,7 @@ import {
10
10
  DialogHeader,
11
11
  DialogTitle,
12
12
  } from '../ui/overlay/Dialog';
13
+ import { DialogLayer } from '../ui/overlay/layers';
13
14
  import { InputOTP, InputOTPGroup, InputOTPSlot } from '../ui/form/InputOtp';
14
15
  import { REGEXP_ONLY_DIGITS } from 'input-otp';
15
16
  import useDisableTwoFactorAuthForm from './hooks/useDisableTwoFactorAuthForm';
@@ -30,63 +31,66 @@ export default function DisableTwoFactorAuthModal({
30
31
  useDisableTwoFactorAuthForm({ onClose, onSuccess });
31
32
 
32
33
  return (
33
- <Dialog open={open} onOpenChange={handleClose}>
34
- <DialogContent overlayClassName="z-[1010]" className="z-[1011] flex flex-col p-0 gap-0 max-w-full sm:max-w-full border-0 rounded-t-2xl rounded-b-none h-dvh top-0 bottom-0 left-0 right-0 translate-x-0 translate-y-0 lg:max-w-117.5 lg:h-auto lg:rounded-lg lg:border lg:top-[50%] lg:left-[50%] lg:right-auto lg:bottom-auto lg:translate-x-[-50%] lg:translate-y-[-50%]">
35
- <form
36
- onSubmit={(e) => {
37
- e.preventDefault();
38
- handleSubmit();
39
- }}
40
- className="flex flex-col flex-1 lg:flex-none"
41
- >
42
- <div className="flex flex-col gap-4 lg:gap-5 p-4 lg:p-5 flex-1 lg:flex-none">
43
- <div className="flex items-center justify-center w-fit bg-gray-50 rounded-lg p-2">
44
- <IconShieldCheck size={20} className="text-gray-600" />
45
- </div>
46
- <DialogHeader className="p-0 gap-2">
47
- <DialogTitle className="paragraph-medium-semibold text-gray-950">
48
- {translate('common.account.twoFactor.disableTitle')}
49
- </DialogTitle>
50
- <DialogDescription className="paragraph-small-regular text-gray-600">
51
- {translate('common.account.twoFactor.disableDescription')}
52
- </DialogDescription>
53
- </DialogHeader>
34
+ // Abre por cima do modal de configurações da conta, que é irmão na árvore.
35
+ <DialogLayer>
36
+ <Dialog open={open} onOpenChange={handleClose}>
37
+ <DialogContent className="flex flex-col p-0 gap-0 max-w-full sm:max-w-full border-0 rounded-t-2xl rounded-b-none h-dvh top-0 bottom-0 left-0 right-0 translate-x-0 translate-y-0 lg:max-w-117.5 lg:h-auto lg:rounded-lg lg:border lg:top-[50%] lg:left-[50%] lg:right-auto lg:bottom-auto lg:translate-x-[-50%] lg:translate-y-[-50%]">
38
+ <form
39
+ onSubmit={(e) => {
40
+ e.preventDefault();
41
+ handleSubmit();
42
+ }}
43
+ className="flex flex-col flex-1 lg:flex-none"
44
+ >
45
+ <div className="flex flex-col gap-4 lg:gap-5 p-4 lg:p-5 flex-1 lg:flex-none">
46
+ <div className="flex items-center justify-center w-fit bg-gray-50 rounded-lg p-2">
47
+ <IconShieldCheck size={20} className="text-gray-600" />
48
+ </div>
49
+ <DialogHeader className="p-0 gap-2">
50
+ <DialogTitle className="paragraph-medium-semibold text-gray-950">
51
+ {translate('common.account.twoFactor.disableTitle')}
52
+ </DialogTitle>
53
+ <DialogDescription className="paragraph-small-regular text-gray-600">
54
+ {translate('common.account.twoFactor.disableDescription')}
55
+ </DialogDescription>
56
+ </DialogHeader>
54
57
 
55
- <div className="flex flex-col gap-2">
56
- <span className="paragraph-small-medium text-gray-700">
57
- {translate('common.account.twoFactor.authenticatorCode')}
58
- </span>
59
- <InputOTP maxLength={6} pattern={REGEXP_ONLY_DIGITS} value={code} onChange={setCode}>
60
- <InputOTPGroup className="gap-2">
61
- {Array.from({ length: 6 }).map((_, i) => (
62
- <InputOTPSlot
63
- key={i}
64
- index={i}
65
- className="w-11! lg:w-12! h-13! lg:h-14! rounded-lg! text-lg border-gray-200"
66
- />
67
- ))}
68
- </InputOTPGroup>
69
- </InputOTP>
58
+ <div className="flex flex-col gap-2">
59
+ <span className="paragraph-small-medium text-gray-700">
60
+ {translate('common.account.twoFactor.authenticatorCode')}
61
+ </span>
62
+ <InputOTP maxLength={6} pattern={REGEXP_ONLY_DIGITS} value={code} onChange={setCode}>
63
+ <InputOTPGroup className="gap-2">
64
+ {Array.from({ length: 6 }).map((_, i) => (
65
+ <InputOTPSlot
66
+ key={i}
67
+ index={i}
68
+ className="w-11! lg:w-12! h-13! lg:h-14! rounded-lg! text-lg border-gray-200"
69
+ />
70
+ ))}
71
+ </InputOTPGroup>
72
+ </InputOTP>
73
+ </div>
70
74
  </div>
71
- </div>
72
75
 
73
- <div className="flex flex-row items-center gap-2 p-4 lg:p-5 border-t border-gray-200 mt-auto lg:mt-0">
74
- <Button className="h-10! flex-1" disabled={!isValid || isLoading} type="submit">
75
- {isLoading
76
- ? translate('common.account.twoFactor.disabling')
77
- : translate('common.account.twoFactor.disable')}
78
- </Button>
79
- <Button
80
- variant="secondary"
81
- className="h-10! flex-1"
82
- type="button"
83
- onClick={handleClose}
84
- >
85
- {translate('common.actions.cancel')}
86
- </Button>
87
- </div>
88
- </form>
89
- </DialogContent>
90
- </Dialog>
76
+ <div className="flex flex-row items-center gap-2 p-4 lg:p-5 border-t border-gray-200 mt-auto lg:mt-0">
77
+ <Button className="h-10! flex-1" disabled={!isValid || isLoading} type="submit">
78
+ {isLoading
79
+ ? translate('common.account.twoFactor.disabling')
80
+ : translate('common.account.twoFactor.disable')}
81
+ </Button>
82
+ <Button
83
+ variant="secondary"
84
+ className="h-10! flex-1"
85
+ type="button"
86
+ onClick={handleClose}
87
+ >
88
+ {translate('common.actions.cancel')}
89
+ </Button>
90
+ </div>
91
+ </form>
92
+ </DialogContent>
93
+ </Dialog>
94
+ </DialogLayer>
91
95
  );
92
96
  }
@@ -4,6 +4,7 @@ import { useTranslations } from 'next-intl';
4
4
  import { IconX, IconCopy, IconRefresh } from '@tabler/icons-react';
5
5
  import { Button } from '../ui/buttons/Button';
6
6
  import { Dialog, DialogContent, DialogHeader, DialogTitle } from '../ui/overlay/Dialog';
7
+ import { DialogLayer } from '../ui/overlay/layers';
7
8
  import { Separator } from '../ui/data-display/Separator';
8
9
  import { InputOTP, InputOTPGroup, InputOTPSlot } from '../ui/form/InputOtp';
9
10
  import { REGEXP_ONLY_DIGITS } from 'input-otp';
@@ -41,18 +42,88 @@ export default function TwoFactorAuthModal({ open, onClose, onSuccess }: TwoFact
41
42
 
42
43
  if (step === 'recovery') {
43
44
  return (
45
+ // Abre por cima do modal de configurações da conta, que é irmão na árvore.
46
+ <DialogLayer>
47
+ <Dialog open={open} onOpenChange={handleClose}>
48
+ <DialogContent
49
+ showCloseButton={false}
50
+ className="flex flex-col p-0 gap-0 max-w-full sm:max-w-full border-0 rounded-t-2xl rounded-b-none h-[100dvh] top-0 bottom-0 left-0 right-0 translate-x-0 translate-y-0 lg:max-w-[470px] lg:h-auto lg:rounded-lg lg:border lg:top-[50%] lg:left-[50%] lg:right-auto lg:bottom-auto lg:translate-x-[-50%] lg:translate-y-[-50%]"
51
+ >
52
+ <DialogHeader className="sr-only">
53
+ <DialogTitle>{translate('common.account.twoFactor.recoveryTitle')}</DialogTitle>
54
+ </DialogHeader>
55
+ <div className="flex items-center justify-center px-4 py-3 relative border-b border-gray-200 lg:border-b-0">
56
+ <span className="paragraph-medium-semibold text-gray-950 text-center">
57
+ {translate('common.account.twoFactor.recoveryTitle')}
58
+ </span>
59
+ <Button
60
+ type="button"
61
+ variant="ghost"
62
+ className="size-8! p-0 absolute right-4"
63
+ onClick={handleClose}
64
+ >
65
+ <IconX size={18} />
66
+ </Button>
67
+ </div>
68
+
69
+ <div className="flex flex-col gap-5 lg:gap-6 px-4 lg:px-5 py-5 lg:py-6 flex-1 lg:flex-none">
70
+ <div className="flex flex-col gap-2">
71
+ <h3 className="paragraph-medium-semibold text-gray-950 max-w-[269px]">
72
+ {translate('common.account.twoFactor.recoveryHeading')}
73
+ </h3>
74
+ <div className="paragraph-small-regular text-gray-600">
75
+ <p>{translate('common.account.twoFactor.recoveryText1')}</p>
76
+ <br />
77
+ <p>{translate('common.account.twoFactor.recoveryText2')}</p>
78
+ </div>
79
+ </div>
80
+
81
+ <div className="bg-gray-50 rounded-lg p-4 flex flex-col gap-4">
82
+ <div className="paragraph-small-medium text-gray-950 whitespace-nowrap">
83
+ {backupCodes.map((backupCode, i) => (
84
+ <p key={i}>{backupCode}</p>
85
+ ))}
86
+ </div>
87
+ <Button
88
+ type="button"
89
+ variant="secondary"
90
+ className="h-8! w-fit"
91
+ onClick={handleCopyCodes}
92
+ >
93
+ <IconCopy size={16} />
94
+ {translate('common.account.twoFactor.copyCodes')}
95
+ </Button>
96
+ </div>
97
+ </div>
98
+
99
+ <div className="flex items-center p-4 lg:p-5 border-t border-gray-200 justify-between mt-auto lg:mt-0">
100
+ <Button variant="secondary" className="h-10!" type="button" onClick={handleClose}>
101
+ {translate('common.actions.cancel')}
102
+ </Button>
103
+ <Button className="h-10!" type="button" onClick={handleFinalize}>
104
+ {translate('common.account.twoFactor.finish')}
105
+ </Button>
106
+ </div>
107
+ </DialogContent>
108
+ </Dialog>
109
+ </DialogLayer>
110
+ );
111
+ }
112
+
113
+ return (
114
+ // Abre por cima do modal de configurações da conta, que é irmão na árvore.
115
+ <DialogLayer>
44
116
  <Dialog open={open} onOpenChange={handleClose}>
45
117
  <DialogContent
46
118
  showCloseButton={false}
47
- overlayClassName="z-[1010]"
48
- className="z-[1011] flex flex-col p-0 gap-0 max-w-full sm:max-w-full border-0 rounded-t-2xl rounded-b-none h-[100dvh] top-0 bottom-0 left-0 right-0 translate-x-0 translate-y-0 lg:max-w-[470px] lg:h-auto lg:rounded-lg lg:border lg:top-[50%] lg:left-[50%] lg:right-auto lg:bottom-auto lg:translate-x-[-50%] lg:translate-y-[-50%]"
119
+ className="flex flex-col p-0 gap-0 max-w-full sm:max-w-full border-0 rounded-t-2xl rounded-b-none h-[100dvh] top-0 bottom-0 left-0 right-0 translate-x-0 translate-y-0 lg:max-w-[470px] lg:h-auto lg:max-h-[90vh] lg:rounded-lg lg:border lg:top-[50%] lg:left-[50%] lg:right-auto lg:bottom-auto lg:translate-x-[-50%] lg:translate-y-[-50%]"
49
120
  >
50
121
  <DialogHeader className="sr-only">
51
- <DialogTitle>{translate('common.account.twoFactor.recoveryTitle')}</DialogTitle>
122
+ <DialogTitle>{translate('common.account.twoFactor.title')}</DialogTitle>
52
123
  </DialogHeader>
53
- <div className="flex items-center justify-center px-4 py-3 relative border-b border-gray-200 lg:border-b-0">
124
+ <div className="shrink-0 flex items-center justify-center px-4 py-3 relative border-b border-gray-200 lg:border-b-0">
54
125
  <span className="paragraph-medium-semibold text-gray-950 text-center">
55
- {translate('common.account.twoFactor.recoveryTitle')}
126
+ {translate('common.account.twoFactor.title')}
56
127
  </span>
57
128
  <Button
58
129
  type="button"
@@ -64,157 +135,91 @@ export default function TwoFactorAuthModal({ open, onClose, onSuccess }: TwoFact
64
135
  </Button>
65
136
  </div>
66
137
 
67
- <div className="flex flex-col gap-5 lg:gap-6 px-4 lg:px-5 py-5 lg:py-6 flex-1 lg:flex-none">
68
- <div className="flex flex-col gap-2">
69
- <h3 className="paragraph-medium-semibold text-gray-950 max-w-[269px]">
70
- {translate('common.account.twoFactor.recoveryHeading')}
71
- </h3>
72
- <div className="paragraph-small-regular text-gray-600">
73
- <p>{translate('common.account.twoFactor.recoveryText1')}</p>
74
- <br />
75
- <p>{translate('common.account.twoFactor.recoveryText2')}</p>
76
- </div>
77
- </div>
78
-
79
- <div className="bg-gray-50 rounded-lg p-4 flex flex-col gap-4">
80
- <div className="paragraph-small-medium text-gray-950 whitespace-nowrap">
81
- {backupCodes.map((backupCode, i) => (
82
- <p key={i}>{backupCode}</p>
83
- ))}
84
- </div>
85
- <Button
86
- type="button"
87
- variant="secondary"
88
- className="h-8! w-fit"
89
- onClick={handleCopyCodes}
90
- >
91
- <IconCopy size={16} />
92
- {translate('common.account.twoFactor.copyCodes')}
93
- </Button>
94
- </div>
95
- </div>
96
-
97
- <div className="flex items-center p-4 lg:p-5 border-t border-gray-200 justify-between mt-auto lg:mt-0">
98
- <Button variant="secondary" className="h-10!" type="button" onClick={handleClose}>
99
- {translate('common.actions.cancel')}
100
- </Button>
101
- <Button className="h-10!" type="button" onClick={handleFinalize}>
102
- {translate('common.account.twoFactor.finish')}
103
- </Button>
104
- </div>
105
- </DialogContent>
106
- </Dialog>
107
- );
108
- }
109
-
110
- return (
111
- <Dialog open={open} onOpenChange={handleClose}>
112
- <DialogContent
113
- showCloseButton={false}
114
- overlayClassName="z-[1010]"
115
- className="z-[1011] flex flex-col p-0 gap-0 max-w-full sm:max-w-full border-0 rounded-t-2xl rounded-b-none h-[100dvh] top-0 bottom-0 left-0 right-0 translate-x-0 translate-y-0 lg:max-w-[470px] lg:h-auto lg:max-h-[90vh] lg:rounded-lg lg:border lg:top-[50%] lg:left-[50%] lg:right-auto lg:bottom-auto lg:translate-x-[-50%] lg:translate-y-[-50%]"
116
- >
117
- <DialogHeader className="sr-only">
118
- <DialogTitle>{translate('common.account.twoFactor.title')}</DialogTitle>
119
- </DialogHeader>
120
- <div className="shrink-0 flex items-center justify-center px-4 py-3 relative border-b border-gray-200 lg:border-b-0">
121
- <span className="paragraph-medium-semibold text-gray-950 text-center">
122
- {translate('common.account.twoFactor.title')}
123
- </span>
124
- <Button
125
- type="button"
126
- variant="ghost"
127
- className="size-8! p-0 absolute right-4"
128
- onClick={handleClose}
138
+ <form
139
+ className="flex-1 min-h-0 flex flex-col"
140
+ onSubmit={(e) => {
141
+ e.preventDefault();
142
+ if (isCodeComplete) handleSubmit();
143
+ }}
129
144
  >
130
- <IconX size={18} />
131
- </Button>
132
- </div>
145
+ <div className="flex-1 min-h-0 overflow-y-auto overscroll-contain lg:overflow-visible">
146
+ <div className="flex flex-col items-center gap-4 lg:gap-8 px-4 lg:px-5 py-4 lg:py-6 pb-60 lg:pb-6">
147
+ <p className="paragraph-small-regular text-gray-950 text-center max-w-full lg:max-w-[412px]">
148
+ {translate.rich('common.account.twoFactor.instructions', {
149
+ link: (chunks) => (
150
+ <a
151
+ href="https://support.google.com/accounts/answer/1066447"
152
+ target="_blank"
153
+ rel="noopener noreferrer"
154
+ className="paragraph-small-medium underline"
155
+ >
156
+ {chunks}
157
+ </a>
158
+ ),
159
+ })}
160
+ </p>
133
161
 
134
- <form
135
- className="flex-1 min-h-0 flex flex-col"
136
- onSubmit={(e) => {
137
- e.preventDefault();
138
- if (isCodeComplete) handleSubmit();
139
- }}
140
- >
141
- <div className="flex-1 min-h-0 overflow-y-auto overscroll-contain lg:overflow-visible">
142
- <div className="flex flex-col items-center gap-4 lg:gap-8 px-4 lg:px-5 py-4 lg:py-6 pb-60 lg:pb-6">
143
- <p className="paragraph-small-regular text-gray-950 text-center max-w-full lg:max-w-[412px]">
144
- {translate.rich('common.account.twoFactor.instructions', {
145
- link: (chunks) => (
146
- <a
147
- href="https://support.google.com/accounts/answer/1066447"
148
- target="_blank"
149
- rel="noopener noreferrer"
150
- className="paragraph-small-medium underline"
162
+ <div className="border border-gray-200 rounded-lg overflow-hidden p-2 lg:p-3 flex items-center justify-center w-[136px] h-[136px] lg:w-[203px] lg:h-[203px]">
163
+ {generateFailed ? (
164
+ <button
165
+ type="button"
166
+ onClick={() => retryGenerate()}
167
+ className="flex flex-col items-center gap-1.5 text-center"
151
168
  >
152
- {chunks}
153
- </a>
154
- ),
155
- })}
156
- </p>
157
-
158
- <div className="border border-gray-200 rounded-lg overflow-hidden p-2 lg:p-3 flex items-center justify-center w-[136px] h-[136px] lg:w-[203px] lg:h-[203px]">
159
- {generateFailed ? (
160
- <button
161
- type="button"
162
- onClick={() => retryGenerate()}
163
- className="flex flex-col items-center gap-1.5 text-center"
164
- >
165
- <IconRefresh size={20} className="text-gray-400" />
166
- <span className="paragraph-xsmall-medium text-gray-500">
167
- {translate('common.account.twoFactor.retry')}
168
- </span>
169
- </button>
170
- ) : isGenerating || !qrcode ? (
171
- <div className="skeleton w-full h-full rounded" />
172
- ) : (
173
- // eslint-disable-next-line @next/next/no-img-element
174
- <img
175
- src={qrcode}
176
- alt={translate('common.account.twoFactor.qrAlt')}
177
- className="w-full h-full"
178
- />
179
- )}
180
- </div>
169
+ <IconRefresh size={20} className="text-gray-400" />
170
+ <span className="paragraph-xsmall-medium text-gray-500">
171
+ {translate('common.account.twoFactor.retry')}
172
+ </span>
173
+ </button>
174
+ ) : isGenerating || !qrcode ? (
175
+ <div className="skeleton w-full h-full rounded" />
176
+ ) : (
177
+ // eslint-disable-next-line @next/next/no-img-element
178
+ <img
179
+ src={qrcode}
180
+ alt={translate('common.account.twoFactor.qrAlt')}
181
+ className="w-full h-full"
182
+ />
183
+ )}
184
+ </div>
181
185
 
182
- <div className="flex items-center gap-3 w-full">
183
- <Separator className="flex-1" />
184
- <span className="paragraph-xsmall-medium text-gray-500 opacity-80 whitespace-nowrap">
185
- {translate('common.account.twoFactor.pasteDigits')}
186
- </span>
187
- <Separator className="flex-1" />
188
- </div>
186
+ <div className="flex items-center gap-3 w-full">
187
+ <Separator className="flex-1" />
188
+ <span className="paragraph-xsmall-medium text-gray-500 opacity-80 whitespace-nowrap">
189
+ {translate('common.account.twoFactor.pasteDigits')}
190
+ </span>
191
+ <Separator className="flex-1" />
192
+ </div>
189
193
 
190
- <div className="scroll-mt-20">
191
- <InputOTP maxLength={6} pattern={REGEXP_ONLY_DIGITS} value={code} onChange={setCode}>
192
- <InputOTPGroup className="gap-2">
193
- {Array.from({ length: 6 }).map((_, i) => (
194
- <InputOTPSlot
195
- key={i}
196
- index={i}
197
- className="w-11! lg:w-12! h-13! lg:h-14! rounded-lg! text-lg border-gray-200"
198
- />
199
- ))}
200
- </InputOTPGroup>
201
- </InputOTP>
194
+ <div className="scroll-mt-20">
195
+ <InputOTP maxLength={6} pattern={REGEXP_ONLY_DIGITS} value={code} onChange={setCode}>
196
+ <InputOTPGroup className="gap-2">
197
+ {Array.from({ length: 6 }).map((_, i) => (
198
+ <InputOTPSlot
199
+ key={i}
200
+ index={i}
201
+ className="w-11! lg:w-12! h-13! lg:h-14! rounded-lg! text-lg border-gray-200"
202
+ />
203
+ ))}
204
+ </InputOTPGroup>
205
+ </InputOTP>
206
+ </div>
202
207
  </div>
203
208
  </div>
204
- </div>
205
209
 
206
- <div className="shrink-0 flex items-center p-4 lg:p-5 border-t border-gray-200 justify-between gap-2 bg-white">
207
- <Button variant="secondary" className="h-10!" type="button" onClick={handleClose}>
208
- {translate('common.actions.cancel')}
209
- </Button>
210
- <Button type="submit" className="h-10!" disabled={!isCodeComplete || isConfirming}>
211
- {isConfirming
212
- ? translate('common.account.twoFactor.activating')
213
- : translate('common.account.twoFactor.activate')}
214
- </Button>
215
- </div>
216
- </form>
217
- </DialogContent>
218
- </Dialog>
210
+ <div className="shrink-0 flex items-center p-4 lg:p-5 border-t border-gray-200 justify-between gap-2 bg-white">
211
+ <Button variant="secondary" className="h-10!" type="button" onClick={handleClose}>
212
+ {translate('common.actions.cancel')}
213
+ </Button>
214
+ <Button type="submit" className="h-10!" disabled={!isCodeComplete || isConfirming}>
215
+ {isConfirming
216
+ ? translate('common.account.twoFactor.activating')
217
+ : translate('common.account.twoFactor.activate')}
218
+ </Button>
219
+ </div>
220
+ </form>
221
+ </DialogContent>
222
+ </Dialog>
223
+ </DialogLayer>
219
224
  );
220
225
  }
@@ -1,7 +1,8 @@
1
1
  'use client';
2
2
 
3
- import { ComponentType } from 'react';
3
+ import { ComponentType, useContext } from 'react';
4
4
  import { useModalManager } from '../../store/useModalManager';
5
+ import { DialogDepthContext } from '../ui/overlay/layers';
5
6
 
6
7
  interface ModalManagerProps {
7
8
  registry: Record<string, ComponentType>;
@@ -9,12 +10,17 @@ interface ModalManagerProps {
9
10
 
10
11
  export function ModalManager({ registry }: ModalManagerProps) {
11
12
  const { modalStack } = useModalManager();
13
+ const depth = useContext(DialogDepthContext);
12
14
 
13
15
  if (modalStack.length === 0) return null;
14
16
 
17
+ // Modais da pilha nascem irmaos na arvore React: sem isso, todos cairiam na
18
+ // mesma profundidade e na mesma faixa de z-index (ver layers.tsx). A
19
+ // posicao na pilha vira a profundidade, relativa a onde o ModalManager
20
+ // esta montado.
15
21
  return (
16
22
  <>
17
- {modalStack.map((modal) => {
23
+ {modalStack.map((modal, index) => {
18
24
  const ModalComponent = registry[modal.key];
19
25
 
20
26
  if (!ModalComponent) {
@@ -22,7 +28,11 @@ export function ModalManager({ registry }: ModalManagerProps) {
22
28
  return null;
23
29
  }
24
30
 
25
- return <ModalComponent key={modal.key} />;
31
+ return (
32
+ <DialogDepthContext.Provider value={depth + index} key={modal.key}>
33
+ <ModalComponent />
34
+ </DialogDepthContext.Provider>
35
+ );
26
36
  })}
27
37
  </>
28
38
  );
@@ -8,6 +8,7 @@ import {
8
8
  DialogHeader,
9
9
  DialogTitle,
10
10
  } from '../../ui/overlay/Dialog'
11
+ import { DialogLayer } from '../../ui/overlay/layers'
11
12
  import { Button } from '../../ui/buttons/Button'
12
13
 
13
14
  interface ImageTooSmallModalProps {
@@ -33,30 +34,30 @@ export function ImageTooSmallModal({
33
34
  const dimensionText = `${minWidth}x${minHeight}px`
34
35
 
35
36
  return (
36
- <Dialog open={open} onOpenChange={onOpenChange}>
37
- <DialogContent
38
- className="w-full md:w-[480px]! lg:w-[480px]! max-w-[480px]! max-[480px]:w-[calc(100%-32px)] p-0 gap-0 z-[1003]"
39
- overlayClassName="z-[1002]"
40
- >
41
- <DialogHeader className="p-5">
42
- <DialogTitle className="text-center text-[16px]!">
43
- {translate('common.imageUpload.tooSmallTitleWithDimension', { dimensionText })}
44
- </DialogTitle>
45
- </DialogHeader>
37
+ // Abre por cima do modal/uploader que a disparou.
38
+ <DialogLayer>
39
+ <Dialog open={open} onOpenChange={onOpenChange}>
40
+ <DialogContent className="w-full md:w-[480px]! lg:w-[480px]! max-w-[480px]! max-[480px]:w-[calc(100%-32px)] p-0 gap-0">
41
+ <DialogHeader className="p-5">
42
+ <DialogTitle className="text-center text-[16px]!">
43
+ {translate('common.imageUpload.tooSmallTitleWithDimension', { dimensionText })}
44
+ </DialogTitle>
45
+ </DialogHeader>
46
46
 
47
- <div className="px-5 pb-5">
48
- <p className="paragraph-small-regular text-zinc-600 text-center">
49
- {translate('common.imageUpload.tooSmallBodyFileWithDimension', { fileName, dimensionText })}
50
- </p>
51
- </div>
47
+ <div className="px-5 pb-5">
48
+ <p className="paragraph-small-regular text-zinc-600 text-center">
49
+ {translate('common.imageUpload.tooSmallBodyFileWithDimension', { fileName, dimensionText })}
50
+ </p>
51
+ </div>
52
52
 
53
- <DialogFooter className="flex-row! items-center justify-start! gap-3 p-5 border-t border-zinc-200">
54
- <Button onClick={onSelectAnother}>{translate('common.imageUpload.sendAnother')}</Button>
55
- <Button variant="secondary" onClick={onCancel}>
56
- {translate('common.actions.cancel')}
57
- </Button>
58
- </DialogFooter>
59
- </DialogContent>
60
- </Dialog>
53
+ <DialogFooter className="flex-row! items-center justify-start! gap-3 p-5 border-t border-zinc-200">
54
+ <Button onClick={onSelectAnother}>{translate('common.imageUpload.sendAnother')}</Button>
55
+ <Button variant="secondary" onClick={onCancel}>
56
+ {translate('common.actions.cancel')}
57
+ </Button>
58
+ </DialogFooter>
59
+ </DialogContent>
60
+ </Dialog>
61
+ </DialogLayer>
61
62
  )
62
63
  }