@greatapps/common 1.1.788 → 1.1.789
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/account/AccountModals.mjs +3 -6
- package/dist/components/account/AccountModals.mjs.map +1 -1
- package/dist/components/account/DisableTwoFactorAuthModal.mjs +2 -3
- package/dist/components/account/DisableTwoFactorAuthModal.mjs.map +1 -1
- package/dist/components/account/TwoFactorAuthModal.mjs +4 -5
- package/dist/components/account/TwoFactorAuthModal.mjs.map +1 -1
- package/dist/components/account/sections/MyProfileSection.mjs +2 -5
- package/dist/components/account/sections/MyProfileSection.mjs.map +1 -1
- package/dist/components/layouts/UsersSelectorPopover.mjs +1 -1
- package/dist/components/layouts/UsersSelectorPopover.mjs.map +1 -1
- package/dist/components/modals/ModalManager.mjs +2 -5
- package/dist/components/modals/ModalManager.mjs.map +1 -1
- package/dist/components/modals/promo/AiCreditsOfferModal/AiCreditsOfferModal.mjs +2 -3
- package/dist/components/modals/promo/AiCreditsOfferModal/AiCreditsOfferModal.mjs.map +1 -1
- package/dist/components/ui/overlay/Dialog.mjs +6 -7
- package/dist/components/ui/overlay/Dialog.mjs.map +1 -1
- package/dist/components/ui/overlay/Popover.mjs +3 -3
- package/dist/components/ui/overlay/Popover.mjs.map +1 -1
- package/dist/components/ui/overlay/Sheet.mjs +6 -6
- package/dist/components/ui/overlay/Sheet.mjs.map +1 -1
- package/dist/components/ui/overlay/layers.mjs +44 -18
- package/dist/components/ui/overlay/layers.mjs.map +1 -1
- package/dist/components/widgets/ImageUpload/ImageTooSmallModal.mjs +2 -3
- package/dist/components/widgets/ImageUpload/ImageTooSmallModal.mjs.map +1 -1
- package/dist/components/widgets/ImageUpload/ImageUpload.mjs +2 -4
- package/dist/components/widgets/ImageUpload/ImageUpload.mjs.map +1 -1
- package/dist/index.mjs +3 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +8 -7
- package/src/components/account/AccountModals.tsx +3 -9
- package/src/components/account/DisableTwoFactorAuthModal.tsx +55 -58
- package/src/components/account/TwoFactorAuthModal.tsx +147 -152
- package/src/components/account/sections/MyProfileSection.tsx +2 -6
- package/src/components/layouts/UsersSelectorPopover.tsx +1 -6
- package/src/components/modals/ModalManager.tsx +3 -9
- package/src/components/modals/promo/AiCreditsOfferModal/AiCreditsOfferModal.tsx +8 -12
- package/src/components/ui/overlay/Dialog.tsx +33 -39
- package/src/components/ui/overlay/Popover.tsx +16 -15
- package/src/components/ui/overlay/Sheet.tsx +50 -56
- package/src/components/ui/overlay/layers.tsx +45 -73
- package/src/components/widgets/ImageUpload/ImageTooSmallModal.tsx +20 -23
- package/src/components/widgets/ImageUpload/ImageUpload.tsx +11 -15
- package/src/index.ts +1 -1
|
@@ -4,7 +4,6 @@ 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';
|
|
8
7
|
import { Separator } from '../ui/data-display/Separator';
|
|
9
8
|
import { InputOTP, InputOTPGroup, InputOTPSlot } from '../ui/form/InputOtp';
|
|
10
9
|
import { REGEXP_ONLY_DIGITS } from 'input-otp';
|
|
@@ -42,86 +41,17 @@ export default function TwoFactorAuthModal({ open, onClose, onSuccess }: TwoFact
|
|
|
42
41
|
|
|
43
42
|
if (step === 'recovery') {
|
|
44
43
|
return (
|
|
45
|
-
<DialogLayer>
|
|
46
|
-
<Dialog open={open} onOpenChange={handleClose}>
|
|
47
|
-
<DialogContent
|
|
48
|
-
showCloseButton={false}
|
|
49
|
-
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%]"
|
|
50
|
-
>
|
|
51
|
-
<DialogHeader className="sr-only">
|
|
52
|
-
<DialogTitle>{translate('common.account.twoFactor.recoveryTitle')}</DialogTitle>
|
|
53
|
-
</DialogHeader>
|
|
54
|
-
<div className="flex items-center justify-center px-4 py-3 relative border-b border-gray-200 lg:border-b-0">
|
|
55
|
-
<span className="paragraph-medium-semibold text-gray-950 text-center">
|
|
56
|
-
{translate('common.account.twoFactor.recoveryTitle')}
|
|
57
|
-
</span>
|
|
58
|
-
<Button
|
|
59
|
-
type="button"
|
|
60
|
-
variant="ghost"
|
|
61
|
-
className="size-8! p-0 absolute right-4"
|
|
62
|
-
onClick={handleClose}
|
|
63
|
-
>
|
|
64
|
-
<IconX size={18} />
|
|
65
|
-
</Button>
|
|
66
|
-
</div>
|
|
67
|
-
|
|
68
|
-
<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">
|
|
69
|
-
<div className="flex flex-col gap-2">
|
|
70
|
-
<h3 className="paragraph-medium-semibold text-gray-950 max-w-[269px]">
|
|
71
|
-
{translate('common.account.twoFactor.recoveryHeading')}
|
|
72
|
-
</h3>
|
|
73
|
-
<div className="paragraph-small-regular text-gray-600">
|
|
74
|
-
<p>{translate('common.account.twoFactor.recoveryText1')}</p>
|
|
75
|
-
<br />
|
|
76
|
-
<p>{translate('common.account.twoFactor.recoveryText2')}</p>
|
|
77
|
-
</div>
|
|
78
|
-
</div>
|
|
79
|
-
|
|
80
|
-
<div className="bg-gray-50 rounded-lg p-4 flex flex-col gap-4">
|
|
81
|
-
<div className="paragraph-small-medium text-gray-950 whitespace-nowrap">
|
|
82
|
-
{backupCodes.map((backupCode, i) => (
|
|
83
|
-
<p key={i}>{backupCode}</p>
|
|
84
|
-
))}
|
|
85
|
-
</div>
|
|
86
|
-
<Button
|
|
87
|
-
type="button"
|
|
88
|
-
variant="secondary"
|
|
89
|
-
className="h-8! w-fit"
|
|
90
|
-
onClick={handleCopyCodes}
|
|
91
|
-
>
|
|
92
|
-
<IconCopy size={16} />
|
|
93
|
-
{translate('common.account.twoFactor.copyCodes')}
|
|
94
|
-
</Button>
|
|
95
|
-
</div>
|
|
96
|
-
</div>
|
|
97
|
-
|
|
98
|
-
<div className="flex items-center p-4 lg:p-5 border-t border-gray-200 justify-between mt-auto lg:mt-0">
|
|
99
|
-
<Button variant="secondary" className="h-10!" type="button" onClick={handleClose}>
|
|
100
|
-
{translate('common.actions.cancel')}
|
|
101
|
-
</Button>
|
|
102
|
-
<Button className="h-10!" type="button" onClick={handleFinalize}>
|
|
103
|
-
{translate('common.account.twoFactor.finish')}
|
|
104
|
-
</Button>
|
|
105
|
-
</div>
|
|
106
|
-
</DialogContent>
|
|
107
|
-
</Dialog>
|
|
108
|
-
</DialogLayer>
|
|
109
|
-
);
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
return (
|
|
113
|
-
<DialogLayer>
|
|
114
44
|
<Dialog open={open} onOpenChange={handleClose}>
|
|
115
45
|
<DialogContent
|
|
116
46
|
showCloseButton={false}
|
|
117
|
-
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:
|
|
47
|
+
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%]"
|
|
118
48
|
>
|
|
119
49
|
<DialogHeader className="sr-only">
|
|
120
|
-
<DialogTitle>{translate('common.account.twoFactor.
|
|
50
|
+
<DialogTitle>{translate('common.account.twoFactor.recoveryTitle')}</DialogTitle>
|
|
121
51
|
</DialogHeader>
|
|
122
|
-
<div className="
|
|
52
|
+
<div className="flex items-center justify-center px-4 py-3 relative border-b border-gray-200 lg:border-b-0">
|
|
123
53
|
<span className="paragraph-medium-semibold text-gray-950 text-center">
|
|
124
|
-
{translate('common.account.twoFactor.
|
|
54
|
+
{translate('common.account.twoFactor.recoveryTitle')}
|
|
125
55
|
</span>
|
|
126
56
|
<Button
|
|
127
57
|
type="button"
|
|
@@ -133,91 +63,156 @@ export default function TwoFactorAuthModal({ open, onClose, onSuccess }: TwoFact
|
|
|
133
63
|
</Button>
|
|
134
64
|
</div>
|
|
135
65
|
|
|
136
|
-
<
|
|
137
|
-
className="flex
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
66
|
+
<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">
|
|
67
|
+
<div className="flex flex-col gap-2">
|
|
68
|
+
<h3 className="paragraph-medium-semibold text-gray-950 max-w-[269px]">
|
|
69
|
+
{translate('common.account.twoFactor.recoveryHeading')}
|
|
70
|
+
</h3>
|
|
71
|
+
<div className="paragraph-small-regular text-gray-600">
|
|
72
|
+
<p>{translate('common.account.twoFactor.recoveryText1')}</p>
|
|
73
|
+
<br />
|
|
74
|
+
<p>{translate('common.account.twoFactor.recoveryText2')}</p>
|
|
75
|
+
</div>
|
|
76
|
+
</div>
|
|
77
|
+
|
|
78
|
+
<div className="bg-gray-50 rounded-lg p-4 flex flex-col gap-4">
|
|
79
|
+
<div className="paragraph-small-medium text-gray-950 whitespace-nowrap">
|
|
80
|
+
{backupCodes.map((backupCode, i) => (
|
|
81
|
+
<p key={i}>{backupCode}</p>
|
|
82
|
+
))}
|
|
83
|
+
</div>
|
|
84
|
+
<Button
|
|
85
|
+
type="button"
|
|
86
|
+
variant="secondary"
|
|
87
|
+
className="h-8! w-fit"
|
|
88
|
+
onClick={handleCopyCodes}
|
|
89
|
+
>
|
|
90
|
+
<IconCopy size={16} />
|
|
91
|
+
{translate('common.account.twoFactor.copyCodes')}
|
|
92
|
+
</Button>
|
|
93
|
+
</div>
|
|
94
|
+
</div>
|
|
95
|
+
|
|
96
|
+
<div className="flex items-center p-4 lg:p-5 border-t border-gray-200 justify-between mt-auto lg:mt-0">
|
|
97
|
+
<Button variant="secondary" className="h-10!" type="button" onClick={handleClose}>
|
|
98
|
+
{translate('common.actions.cancel')}
|
|
99
|
+
</Button>
|
|
100
|
+
<Button className="h-10!" type="button" onClick={handleFinalize}>
|
|
101
|
+
{translate('common.account.twoFactor.finish')}
|
|
102
|
+
</Button>
|
|
103
|
+
</div>
|
|
104
|
+
</DialogContent>
|
|
105
|
+
</Dialog>
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return (
|
|
110
|
+
<Dialog open={open} onOpenChange={handleClose}>
|
|
111
|
+
<DialogContent
|
|
112
|
+
showCloseButton={false}
|
|
113
|
+
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%]"
|
|
114
|
+
>
|
|
115
|
+
<DialogHeader className="sr-only">
|
|
116
|
+
<DialogTitle>{translate('common.account.twoFactor.title')}</DialogTitle>
|
|
117
|
+
</DialogHeader>
|
|
118
|
+
<div className="shrink-0 flex items-center justify-center px-4 py-3 relative border-b border-gray-200 lg:border-b-0">
|
|
119
|
+
<span className="paragraph-medium-semibold text-gray-950 text-center">
|
|
120
|
+
{translate('common.account.twoFactor.title')}
|
|
121
|
+
</span>
|
|
122
|
+
<Button
|
|
123
|
+
type="button"
|
|
124
|
+
variant="ghost"
|
|
125
|
+
className="size-8! p-0 absolute right-4"
|
|
126
|
+
onClick={handleClose}
|
|
142
127
|
>
|
|
143
|
-
<
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
{translate.rich('common.account.twoFactor.instructions', {
|
|
147
|
-
link: (chunks) => (
|
|
148
|
-
<a
|
|
149
|
-
href="https://support.google.com/accounts/answer/1066447"
|
|
150
|
-
target="_blank"
|
|
151
|
-
rel="noopener noreferrer"
|
|
152
|
-
className="paragraph-small-medium underline"
|
|
153
|
-
>
|
|
154
|
-
{chunks}
|
|
155
|
-
</a>
|
|
156
|
-
),
|
|
157
|
-
})}
|
|
158
|
-
</p>
|
|
128
|
+
<IconX size={18} />
|
|
129
|
+
</Button>
|
|
130
|
+
</div>
|
|
159
131
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
132
|
+
<form
|
|
133
|
+
className="flex-1 min-h-0 flex flex-col"
|
|
134
|
+
onSubmit={(e) => {
|
|
135
|
+
e.preventDefault();
|
|
136
|
+
if (isCodeComplete) handleSubmit();
|
|
137
|
+
}}
|
|
138
|
+
>
|
|
139
|
+
<div className="flex-1 min-h-0 overflow-y-auto overscroll-contain lg:overflow-visible">
|
|
140
|
+
<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">
|
|
141
|
+
<p className="paragraph-small-regular text-gray-950 text-center max-w-full lg:max-w-[412px]">
|
|
142
|
+
{translate.rich('common.account.twoFactor.instructions', {
|
|
143
|
+
link: (chunks) => (
|
|
144
|
+
<a
|
|
145
|
+
href="https://support.google.com/accounts/answer/1066447"
|
|
146
|
+
target="_blank"
|
|
147
|
+
rel="noopener noreferrer"
|
|
148
|
+
className="paragraph-small-medium underline"
|
|
166
149
|
>
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
) : isGenerating || !qrcode ? (
|
|
173
|
-
<div className="skeleton w-full h-full rounded" />
|
|
174
|
-
) : (
|
|
175
|
-
// eslint-disable-next-line @next/next/no-img-element
|
|
176
|
-
<img
|
|
177
|
-
src={qrcode}
|
|
178
|
-
alt={translate('common.account.twoFactor.qrAlt')}
|
|
179
|
-
className="w-full h-full"
|
|
180
|
-
/>
|
|
181
|
-
)}
|
|
182
|
-
</div>
|
|
150
|
+
{chunks}
|
|
151
|
+
</a>
|
|
152
|
+
),
|
|
153
|
+
})}
|
|
154
|
+
</p>
|
|
183
155
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
<
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
156
|
+
<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]">
|
|
157
|
+
{generateFailed ? (
|
|
158
|
+
<button
|
|
159
|
+
type="button"
|
|
160
|
+
onClick={() => retryGenerate()}
|
|
161
|
+
className="flex flex-col items-center gap-1.5 text-center"
|
|
162
|
+
>
|
|
163
|
+
<IconRefresh size={20} className="text-gray-400" />
|
|
164
|
+
<span className="paragraph-xsmall-medium text-gray-500">
|
|
165
|
+
{translate('common.account.twoFactor.retry')}
|
|
166
|
+
</span>
|
|
167
|
+
</button>
|
|
168
|
+
) : isGenerating || !qrcode ? (
|
|
169
|
+
<div className="skeleton w-full h-full rounded" />
|
|
170
|
+
) : (
|
|
171
|
+
// eslint-disable-next-line @next/next/no-img-element
|
|
172
|
+
<img
|
|
173
|
+
src={qrcode}
|
|
174
|
+
alt={translate('common.account.twoFactor.qrAlt')}
|
|
175
|
+
className="w-full h-full"
|
|
176
|
+
/>
|
|
177
|
+
)}
|
|
178
|
+
</div>
|
|
191
179
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
index={i}
|
|
199
|
-
className="w-11! lg:w-12! h-13! lg:h-14! rounded-lg! text-lg border-gray-200"
|
|
200
|
-
/>
|
|
201
|
-
))}
|
|
202
|
-
</InputOTPGroup>
|
|
203
|
-
</InputOTP>
|
|
204
|
-
</div>
|
|
180
|
+
<div className="flex items-center gap-3 w-full">
|
|
181
|
+
<Separator className="flex-1" />
|
|
182
|
+
<span className="paragraph-xsmall-medium text-gray-500 opacity-80 whitespace-nowrap">
|
|
183
|
+
{translate('common.account.twoFactor.pasteDigits')}
|
|
184
|
+
</span>
|
|
185
|
+
<Separator className="flex-1" />
|
|
205
186
|
</div>
|
|
206
|
-
</div>
|
|
207
187
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
188
|
+
<div className="scroll-mt-20">
|
|
189
|
+
<InputOTP maxLength={6} pattern={REGEXP_ONLY_DIGITS} value={code} onChange={setCode}>
|
|
190
|
+
<InputOTPGroup className="gap-2">
|
|
191
|
+
{Array.from({ length: 6 }).map((_, i) => (
|
|
192
|
+
<InputOTPSlot
|
|
193
|
+
key={i}
|
|
194
|
+
index={i}
|
|
195
|
+
className="w-11! lg:w-12! h-13! lg:h-14! rounded-lg! text-lg border-gray-200"
|
|
196
|
+
/>
|
|
197
|
+
))}
|
|
198
|
+
</InputOTPGroup>
|
|
199
|
+
</InputOTP>
|
|
200
|
+
</div>
|
|
217
201
|
</div>
|
|
218
|
-
</
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
202
|
+
</div>
|
|
203
|
+
|
|
204
|
+
<div className="shrink-0 flex items-center p-4 lg:p-5 border-t border-gray-200 justify-between gap-2 bg-white">
|
|
205
|
+
<Button variant="secondary" className="h-10!" type="button" onClick={handleClose}>
|
|
206
|
+
{translate('common.actions.cancel')}
|
|
207
|
+
</Button>
|
|
208
|
+
<Button type="submit" className="h-10!" disabled={!isCodeComplete || isConfirming}>
|
|
209
|
+
{isConfirming
|
|
210
|
+
? translate('common.account.twoFactor.activating')
|
|
211
|
+
: translate('common.account.twoFactor.activate')}
|
|
212
|
+
</Button>
|
|
213
|
+
</div>
|
|
214
|
+
</form>
|
|
215
|
+
</DialogContent>
|
|
216
|
+
</Dialog>
|
|
222
217
|
);
|
|
223
218
|
}
|
|
@@ -20,7 +20,6 @@ import { useUpdateAccountUser } from '../../../modules/accounts/hooks/useAccount
|
|
|
20
20
|
import { GENDER_OPTIONS } from '../constants';
|
|
21
21
|
import { ChangePhoneModal } from './ChangePhoneModal';
|
|
22
22
|
import { ChangeEmailModal } from './ChangeEmailModal';
|
|
23
|
-
import { DialogLayer } from '../../ui/overlay/layers';
|
|
24
23
|
|
|
25
24
|
interface MyProfileSectionProps {
|
|
26
25
|
onClose: () => void;
|
|
@@ -270,11 +269,8 @@ export function MyProfileSection({ onClose, storageUrl }: MyProfileSectionProps)
|
|
|
270
269
|
</div>
|
|
271
270
|
</form>
|
|
272
271
|
|
|
273
|
-
{
|
|
274
|
-
<
|
|
275
|
-
<ChangePhoneModal open={changePhoneOpen} onClose={() => setChangePhoneOpen(false)} />
|
|
276
|
-
<ChangeEmailModal open={changeEmailOpen} onClose={() => setChangeEmailOpen(false)} />
|
|
277
|
-
</DialogLayer>
|
|
272
|
+
<ChangePhoneModal open={changePhoneOpen} onClose={() => setChangePhoneOpen(false)} />
|
|
273
|
+
<ChangeEmailModal open={changeEmailOpen} onClose={() => setChangeEmailOpen(false)} />
|
|
278
274
|
</>
|
|
279
275
|
);
|
|
280
276
|
}
|
|
@@ -201,12 +201,7 @@ export function UsersSelectorPopover({
|
|
|
201
201
|
/>
|
|
202
202
|
</div>
|
|
203
203
|
</TooltipTrigger>
|
|
204
|
-
|
|
205
|
-
`PopoverContent`, e a escala de faixas so modela
|
|
206
|
-
aninhamento de modal. Sem o z explicito o tooltip
|
|
207
|
-
fica na faixa do popover que o hospeda e some
|
|
208
|
-
atras dele. */}
|
|
209
|
-
<TooltipContent className="z-[1002]">
|
|
204
|
+
<TooltipContent>
|
|
210
205
|
{inProject ? translate('common.layout.usersSelector.removeFromProject') : translate('common.layout.usersSelector.addToProject')}
|
|
211
206
|
</TooltipContent>
|
|
212
207
|
</Tooltip>
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import { ComponentType
|
|
3
|
+
import { ComponentType } from 'react';
|
|
4
4
|
import { useModalManager } from '../../store/useModalManager';
|
|
5
|
-
import { DialogDepthContext } from '../ui/overlay/layers';
|
|
6
5
|
|
|
7
6
|
interface ModalManagerProps {
|
|
8
7
|
registry: Record<string, ComponentType>;
|
|
@@ -10,13 +9,12 @@ interface ModalManagerProps {
|
|
|
10
9
|
|
|
11
10
|
export function ModalManager({ registry }: ModalManagerProps) {
|
|
12
11
|
const { modalStack } = useModalManager();
|
|
13
|
-
const depth = useContext(DialogDepthContext);
|
|
14
12
|
|
|
15
13
|
if (modalStack.length === 0) return null;
|
|
16
14
|
|
|
17
15
|
return (
|
|
18
16
|
<>
|
|
19
|
-
{modalStack.map((modal
|
|
17
|
+
{modalStack.map((modal) => {
|
|
20
18
|
const ModalComponent = registry[modal.key];
|
|
21
19
|
|
|
22
20
|
if (!ModalComponent) {
|
|
@@ -24,11 +22,7 @@ export function ModalManager({ registry }: ModalManagerProps) {
|
|
|
24
22
|
return null;
|
|
25
23
|
}
|
|
26
24
|
|
|
27
|
-
return
|
|
28
|
-
<DialogDepthContext.Provider value={depth + index} key={modal.key}>
|
|
29
|
-
<ModalComponent />
|
|
30
|
-
</DialogDepthContext.Provider>
|
|
31
|
-
);
|
|
25
|
+
return <ModalComponent key={modal.key} />;
|
|
32
26
|
})}
|
|
33
27
|
</>
|
|
34
28
|
);
|
|
@@ -26,7 +26,6 @@ import { readOfferStageCookie, writeOfferStageCookie } from '../../../../modules
|
|
|
26
26
|
import { useAiCreditsOfferModal } from '../../../../store/useAiCreditsOfferModal';
|
|
27
27
|
import { useModalManager } from '../../../../store/useModalManager';
|
|
28
28
|
import { LoseOfferDialog } from './components/LoseOfferDialog';
|
|
29
|
-
import { DialogLayer } from '../../../ui/overlay/layers';
|
|
30
29
|
import { OfferIllustration } from './components/OfferIllustration';
|
|
31
30
|
import { OfferPaymentField } from './components/OfferPaymentField';
|
|
32
31
|
|
|
@@ -389,17 +388,14 @@ export default function AiCreditsOfferModal() {
|
|
|
389
388
|
</DialogContent>
|
|
390
389
|
</Dialog>
|
|
391
390
|
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
onLose={dismiss}
|
|
401
|
-
/>
|
|
402
|
-
</DialogLayer>
|
|
391
|
+
<LoseOfferDialog
|
|
392
|
+
open={confirmingExit}
|
|
393
|
+
discountLabel={discountLabel}
|
|
394
|
+
creditsLabel={creditsLabel}
|
|
395
|
+
fullPriceLabel={fullPrice != null ? formatCurrencyNumber(fullPrice) : ''}
|
|
396
|
+
onKeep={() => setConfirmingExit(false)}
|
|
397
|
+
onLose={dismiss}
|
|
398
|
+
/>
|
|
403
399
|
</>
|
|
404
400
|
);
|
|
405
401
|
}
|
|
@@ -4,21 +4,12 @@ import * as React from "react";
|
|
|
4
4
|
import * as DialogPrimitive from "@radix-ui/react-dialog";
|
|
5
5
|
import { IconX } from '@tabler/icons-react';
|
|
6
6
|
import { cn } from "../../../infra/utils/clsx";
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
// Cada `Dialog` aninhado sobe uma faixa de z-index, para que o overlay do modal
|
|
10
|
-
// de cima cubra o conteudo do modal de baixo. A escala (e os dropdowns e
|
|
11
|
-
// tooltips que precisam acompanhar) vive em `./layers`.
|
|
7
|
+
import { OverlayLayerContext, useDialogLayer, useOverlayLayer } from "./layers";
|
|
12
8
|
|
|
13
9
|
function Dialog({
|
|
14
10
|
...props
|
|
15
11
|
}: React.ComponentProps<typeof DialogPrimitive.Root>) {
|
|
16
|
-
|
|
17
|
-
return (
|
|
18
|
-
<DialogDepthContext.Provider value={depth + 1}>
|
|
19
|
-
<DialogPrimitive.Root data-slot="dialog" {...props} />
|
|
20
|
-
</DialogDepthContext.Provider>
|
|
21
|
-
);
|
|
12
|
+
return <DialogPrimitive.Root data-slot="dialog" {...props} />;
|
|
22
13
|
}
|
|
23
14
|
|
|
24
15
|
function DialogTrigger({
|
|
@@ -64,40 +55,43 @@ function DialogContent({
|
|
|
64
55
|
overlayClassName,
|
|
65
56
|
hideOverlay = false,
|
|
66
57
|
...props
|
|
67
|
-
}: React.
|
|
58
|
+
}: React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content> & {
|
|
68
59
|
showCloseButton?: boolean;
|
|
69
60
|
overlayClassName?: string;
|
|
70
61
|
hideOverlay?: boolean;
|
|
71
62
|
}) {
|
|
72
|
-
const layer =
|
|
63
|
+
const { layer, presenceRef } = useOverlayLayer();
|
|
73
64
|
return (
|
|
74
|
-
<
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
65
|
+
<OverlayLayerContext.Provider value={layer}>
|
|
66
|
+
<DialogPortal data-slot="dialog-portal">
|
|
67
|
+
{!hideOverlay && <DialogOverlay className={overlayClassName} />}
|
|
68
|
+
<DialogPrimitive.Content
|
|
69
|
+
ref={presenceRef}
|
|
70
|
+
data-slot="dialog-content"
|
|
71
|
+
className={cn(
|
|
72
|
+
"bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg",
|
|
73
|
+
layer.content,
|
|
74
|
+
className,
|
|
75
|
+
)}
|
|
76
|
+
{...props}
|
|
77
|
+
>
|
|
78
|
+
{children}
|
|
79
|
+
{showCloseButton && (
|
|
80
|
+
<div className="absolute top-0.5 right-0">
|
|
81
|
+
<div className="p-4">
|
|
82
|
+
<DialogPrimitive.Close
|
|
83
|
+
data-slot="dialog-close"
|
|
84
|
+
className="hover:cursor-pointer flex size-8 items-center justify-center rounded-lg p-2 text-gray-500 transition-colors hover:bg-gray-100 hover:text-gray-950 focus:outline-none"
|
|
85
|
+
>
|
|
86
|
+
<IconX className="size-[18px]" />
|
|
87
|
+
<span className="sr-only">Close</span>
|
|
88
|
+
</DialogPrimitive.Close>
|
|
89
|
+
</div>
|
|
96
90
|
</div>
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
</
|
|
100
|
-
</
|
|
91
|
+
)}
|
|
92
|
+
</DialogPrimitive.Content>
|
|
93
|
+
</DialogPortal>
|
|
94
|
+
</OverlayLayerContext.Provider>
|
|
101
95
|
);
|
|
102
96
|
}
|
|
103
97
|
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import * as React from "react"
|
|
6
6
|
import * as PopoverPrimitive from "@radix-ui/react-popover"
|
|
7
7
|
import { cn } from "../../../infra/utils/clsx"
|
|
8
|
-
import { useDialogLayer } from "./layers"
|
|
8
|
+
import { OVERLAY_LAYERS, OverlayLayerContext, ROOT_LAYER, useDialogLayer } from "./layers"
|
|
9
9
|
|
|
10
10
|
function Popover({
|
|
11
11
|
...props
|
|
@@ -25,22 +25,23 @@ function PopoverContent({
|
|
|
25
25
|
sideOffset = 4,
|
|
26
26
|
...props
|
|
27
27
|
}: React.ComponentProps<typeof PopoverPrimitive.Content>) {
|
|
28
|
-
// Portaliza para o body, entao disputa z com o conteudo do modal que o abriu.
|
|
29
28
|
const layer = useDialogLayer()
|
|
30
29
|
return (
|
|
31
|
-
<
|
|
32
|
-
<PopoverPrimitive.
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
30
|
+
<OverlayLayerContext.Provider value={layer === ROOT_LAYER ? OVERLAY_LAYERS[0] : layer}>
|
|
31
|
+
<PopoverPrimitive.Portal>
|
|
32
|
+
<PopoverPrimitive.Content
|
|
33
|
+
data-slot="popover-content"
|
|
34
|
+
align={align}
|
|
35
|
+
sideOffset={sideOffset}
|
|
36
|
+
className={cn(
|
|
37
|
+
"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 w-72 origin-(--radix-popover-content-transform-origin) rounded-md border p-4 shadow-md outline-hidden",
|
|
38
|
+
layer.popover,
|
|
39
|
+
className
|
|
40
|
+
)}
|
|
41
|
+
{...props}
|
|
42
|
+
/>
|
|
43
|
+
</PopoverPrimitive.Portal>
|
|
44
|
+
</OverlayLayerContext.Provider>
|
|
44
45
|
)
|
|
45
46
|
}
|
|
46
47
|
|