@greatapps/common 1.1.167 → 1.1.169
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/ConfirmDeleteAccountModal.mjs.map +1 -1
- package/dist/components/account/DeleteAccountModal.mjs.map +1 -1
- package/dist/components/account/IsntPossibleDeleteAccountModal.mjs.map +1 -1
- package/dist/components/account/hooks/useTwoFactorAuthForm.mjs.map +1 -1
- package/dist/components/layouts/AppMobileNavBar.mjs.map +1 -1
- package/dist/components/layouts/AppNavBar.mjs.map +1 -1
- package/dist/components/layouts/NavBar.mjs +29 -1
- package/dist/components/layouts/NavBar.mjs.map +1 -1
- package/dist/components/layouts/UsersSelectorPopover.mjs +9 -12
- package/dist/components/layouts/UsersSelectorPopover.mjs.map +1 -1
- package/dist/components/navigation/AppNavigation.mjs +1 -1
- package/dist/components/navigation/AppNavigation.mjs.map +1 -1
- package/dist/components/navigation/CancelledSubscriptionBanner.mjs +59 -0
- package/dist/components/navigation/CancelledSubscriptionBanner.mjs.map +1 -0
- package/dist/components/navigation/NavItemsContext.mjs.map +1 -1
- package/dist/components/navigation/shells/TabsMobileShell.mjs.map +1 -1
- package/dist/components/pages/notifications/Notifications.mjs.map +1 -1
- package/dist/components/ui/buttons/Button.mjs.map +1 -1
- package/dist/components/ui/buttons/CancelButton.mjs.map +1 -1
- package/dist/components/ui/buttons/CopyButton.mjs.map +1 -1
- package/dist/components/ui/data-display/Accordion.mjs.map +1 -1
- package/dist/components/ui/data-display/Badge.mjs.map +1 -1
- package/dist/components/ui/data-display/Card.mjs.map +1 -1
- package/dist/components/ui/data-display/Pagination.mjs.map +1 -1
- package/dist/components/ui/data-display/ScrollArea.mjs.map +1 -1
- package/dist/components/ui/data-display/Separator.mjs.map +1 -1
- package/dist/components/ui/data-display/Table.mjs.map +1 -1
- package/dist/components/ui/data-display/Tabs.mjs.map +1 -1
- package/dist/components/ui/feedback/CircularProgress.mjs.map +1 -1
- package/dist/components/ui/feedback/DefaultCircularProgress.mjs.map +1 -1
- package/dist/components/ui/feedback/LoadingOverlay.mjs.map +1 -1
- package/dist/components/ui/feedback/Progress.mjs.map +1 -1
- package/dist/components/ui/feedback/Toast.mjs.map +1 -1
- package/dist/components/ui/form/Calendar.mjs.map +1 -1
- package/dist/components/ui/form/Checkbox.mjs.map +1 -1
- package/dist/components/ui/form/DatePicker.mjs.map +1 -1
- package/dist/components/ui/form/DateRangePicker.mjs.map +1 -1
- package/dist/components/ui/form/Input.mjs.map +1 -1
- package/dist/components/ui/form/InputOtp.mjs.map +1 -1
- package/dist/components/ui/form/RadioGroup.mjs.map +1 -1
- package/dist/components/ui/form/Select.mjs +1 -1
- package/dist/components/ui/form/Select.mjs.map +1 -1
- package/dist/components/ui/form/Switch.mjs.map +1 -1
- package/dist/components/ui/form/Textarea.mjs.map +1 -1
- package/dist/components/ui/overlay/Command.mjs.map +1 -1
- package/dist/components/ui/overlay/Dialog.mjs.map +1 -1
- package/dist/components/ui/overlay/Popover.mjs.map +1 -1
- package/dist/components/ui/overlay/Sheet.mjs.map +1 -1
- package/dist/components/ui/overlay/Tooltip.mjs.map +1 -1
- package/dist/hooks/copy-to-clipboard.hook.mjs.map +1 -1
- package/dist/index.mjs +28 -24
- package/dist/index.mjs.map +1 -1
- package/dist/middleware.mjs.map +1 -1
- package/dist/modules/accounts/actions/account-management.action.mjs.map +1 -1
- package/dist/modules/accounts/actions/find-current-account.action.mjs.map +1 -1
- package/dist/modules/accounts/actions/list-currencies.action.mjs.map +1 -1
- package/dist/modules/accounts/actions/list-timezones.action.mjs.map +1 -1
- package/dist/modules/accounts/hooks/current-account.hook.mjs.map +1 -1
- package/dist/modules/accounts/hooks/useAccountManagement.mjs.map +1 -1
- package/dist/modules/accounts/hooks/useCurrencies.mjs.map +1 -1
- package/dist/modules/accounts/hooks/useTimezones.mjs.map +1 -1
- package/dist/modules/auth/hooks/login.hook.mjs.map +1 -1
- package/dist/modules/auth/hooks/logout.hook.mjs.map +1 -1
- package/dist/modules/auth/hooks/register.hook.mjs.map +1 -1
- package/dist/modules/auth/services/auth.service.mjs +1 -1
- package/dist/modules/auth/services/auth.service.mjs.map +1 -1
- package/dist/modules/ia-credits/actions/list-ia-credits.action.mjs.map +1 -1
- package/dist/modules/projects/actions/add-project-user.action.mjs.map +1 -1
- package/dist/modules/projects/actions/list-available-users.action.mjs.map +1 -1
- package/dist/modules/projects/actions/list-project-users.action.mjs.map +1 -1
- package/dist/modules/projects/actions/remove-project-user.action.mjs.map +1 -1
- package/dist/modules/projects/hooks/list-available-users.hook.mjs.map +1 -1
- package/dist/modules/projects/hooks/list-project-users.hook.mjs.map +1 -1
- package/dist/modules/subscriptions/actions/list-subscriptions.action.mjs.map +1 -1
- package/dist/modules/subscriptions/hooks/find-active-subscription.hook.mjs.map +1 -1
- package/dist/modules/subscriptions/hooks/list-subscriptions.hook.mjs.map +1 -1
- package/dist/modules/users/action/find-user-by-id.action.mjs.map +1 -1
- package/dist/modules/users/action/list-messages.action.mjs.map +1 -1
- package/dist/modules/users/action/mark-all-messages-as-read.action.mjs.map +1 -1
- package/dist/modules/users/action/mark-message-as-read.action.mjs.map +1 -1
- package/dist/modules/users/hooks/messages.hook.mjs.map +1 -1
- package/dist/modules/whitelabel/actions/find-whitelabel-styles.action.mjs.map +1 -1
- package/dist/modules/whitelabel/actions/find-whitelabel.action.mjs.map +1 -1
- package/dist/modules/whitelabel/services/whitelabel-styles.service.mjs.map +1 -1
- package/dist/providers/whitelabel.provider.mjs.map +1 -1
- package/dist/utils/safeServerAction.mjs.map +1 -1
- package/dist/utils/withAction.mjs.map +1 -1
- package/package.json +90 -90
- package/src/components/account/ConfirmDeleteAccountModal.tsx +55 -55
- package/src/components/account/DeleteAccountModal.tsx +130 -130
- package/src/components/account/IsntPossibleDeleteAccountModal.tsx +49 -49
- package/src/components/account/hooks/useTwoFactorAuthForm.tsx +101 -101
- package/src/components/layouts/AppMobileNavBar.tsx +125 -125
- package/src/components/layouts/AppNavBar.tsx +57 -57
- package/src/components/layouts/NavBar.tsx +139 -139
- package/src/components/navigation/CancelledSubscriptionBanner.tsx +69 -69
- package/src/components/navigation/NavItemsContext.ts +20 -20
- package/src/components/navigation/shells/TabsMobileShell.tsx +72 -72
- package/src/components/pages/notifications/Notifications.tsx +160 -160
- package/src/components/ui/buttons/Button.tsx +57 -57
- package/src/components/ui/buttons/CancelButton.tsx +14 -14
- package/src/components/ui/buttons/CopyButton.tsx +54 -54
- package/src/components/ui/data-display/Accordion.tsx +81 -81
- package/src/components/ui/data-display/Badge.tsx +47 -47
- package/src/components/ui/data-display/Card.tsx +93 -93
- package/src/components/ui/data-display/Pagination.tsx +126 -126
- package/src/components/ui/data-display/ScrollArea.tsx +59 -59
- package/src/components/ui/data-display/Separator.tsx +29 -29
- package/src/components/ui/data-display/Table.tsx +117 -117
- package/src/components/ui/data-display/Tabs.tsx +67 -67
- package/src/components/ui/feedback/CircularProgress.tsx +75 -75
- package/src/components/ui/feedback/DefaultCircularProgress.tsx +53 -53
- package/src/components/ui/feedback/LoadingOverlay.tsx +31 -31
- package/src/components/ui/feedback/Progress.tsx +40 -40
- package/src/components/ui/feedback/Toast.tsx +101 -101
- package/src/components/ui/form/Calendar.tsx +228 -228
- package/src/components/ui/form/Checkbox.tsx +31 -31
- package/src/components/ui/form/DatePicker.tsx +97 -97
- package/src/components/ui/form/DateRangePicker.tsx +108 -108
- package/src/components/ui/form/Input.tsx +20 -20
- package/src/components/ui/form/InputOtp.tsx +80 -80
- package/src/components/ui/form/RadioGroup.tsx +45 -45
- package/src/components/ui/form/Select.tsx +200 -200
- package/src/components/ui/form/Switch.tsx +32 -32
- package/src/components/ui/form/Textarea.tsx +19 -19
- package/src/components/ui/overlay/Command.tsx +185 -185
- package/src/components/ui/overlay/Dialog.tsx +151 -151
- package/src/components/ui/overlay/Popover.tsx +49 -49
- package/src/components/ui/overlay/Sheet.tsx +159 -159
- package/src/components/ui/overlay/Tooltip.tsx +62 -62
- package/src/hooks/copy-to-clipboard.hook.tsx +67 -67
- package/src/index.ts +351 -348
- package/src/middleware.ts +4 -4
- package/src/modules/accounts/actions/account-management.action.ts +90 -90
- package/src/modules/accounts/actions/find-current-account.action.ts +9 -9
- package/src/modules/accounts/actions/list-currencies.action.ts +8 -8
- package/src/modules/accounts/actions/list-timezones.action.ts +8 -8
- package/src/modules/accounts/hooks/current-account.hook.tsx +22 -22
- package/src/modules/accounts/hooks/useAccountManagement.ts +85 -85
- package/src/modules/accounts/hooks/useCurrencies.ts +15 -15
- package/src/modules/accounts/hooks/useTimezones.ts +15 -15
- package/src/modules/accounts/types.ts +214 -214
- package/src/modules/auth/hooks/login.hook.tsx +13 -13
- package/src/modules/auth/hooks/logout.hook.tsx +11 -11
- package/src/modules/auth/hooks/register.hook.tsx +11 -11
- package/src/modules/ia-credits/actions/list-ia-credits.action.ts +8 -8
- package/src/modules/projects/actions/add-project-user.action.ts +9 -9
- package/src/modules/projects/actions/list-available-users.action.ts +9 -9
- package/src/modules/projects/actions/list-project-users.action.ts +9 -9
- package/src/modules/projects/actions/remove-project-user.action.ts +9 -9
- package/src/modules/projects/hooks/list-available-users.hook.ts +33 -33
- package/src/modules/projects/hooks/list-project-users.hook.ts +33 -33
- package/src/modules/subscriptions/actions/list-subscriptions.action.ts +9 -9
- package/src/modules/subscriptions/hooks/find-active-subscription.hook.ts +19 -19
- package/src/modules/subscriptions/hooks/list-subscriptions.hook.ts +17 -17
- package/src/modules/users/action/find-user-by-id.action.ts +8 -8
- package/src/modules/users/action/list-messages.action.ts +12 -12
- package/src/modules/users/action/mark-all-messages-as-read.action.ts +8 -8
- package/src/modules/users/action/mark-message-as-read.action.ts +8 -8
- package/src/modules/users/hooks/messages.hook.ts +60 -60
- package/src/modules/whitelabel/actions/find-whitelabel-styles.action.ts +14 -14
- package/src/modules/whitelabel/actions/find-whitelabel.action.ts +23 -23
- package/src/modules/whitelabel/services/whitelabel-styles.service.ts +98 -98
- package/src/modules/whitelabel/styles-schema.ts +37 -37
- package/src/providers/whitelabel.provider.tsx +46 -46
- package/src/utils/safeServerAction.ts +21 -21
- package/src/utils/withAction.ts +13 -13
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/account/ConfirmDeleteAccountModal.tsx"],"sourcesContent":["'use client';\
|
|
1
|
+
{"version":3,"sources":["../../../src/components/account/ConfirmDeleteAccountModal.tsx"],"sourcesContent":["'use client';\n\nimport { TriangleAlert } from 'lucide-react';\nimport { toast } from 'sonner';\nimport { Dialog, DialogContent, DialogHeader, DialogTitle } from '../ui/overlay/Dialog';\nimport { Button } from '../ui/buttons/Button';\nimport { Toast } from '../ui/feedback/Toast';\nimport { useAccountModals } from '../../store/useAccountModals';\n\nexport default function ConfirmDeleteAccountModal() {\n const { activeModal, pagesCount, close } = useAccountModals();\n const open = activeModal === 'confirmDelete';\n\n const handleConfirm = () => {\n toast.custom((t) => (\n <Toast variant=\"success\" message=\"Conta excluída com sucesso\" toastId={t} />\n ));\n close();\n };\n\n return (\n <Dialog open={open} onOpenChange={close}>\n <DialogContent className=\"flex flex-col p-0 gap-0 max-w-[calc(100%-2rem)]! w-full rounded-lg border sm:max-w-[400px]! lg:max-w-[470px]! lg:top-[50%]! lg:left-[50%]! lg:right-auto! lg:bottom-auto! lg:translate-x-[-50%]! lg:translate-y-[-50%]!\">\n <div className=\"flex flex-col gap-5 p-4 lg:p-5\">\n <DialogHeader className=\"p-0\">\n <DialogTitle className=\"paragraph-medium-semibold text-gray-950\">\n Uma pena te ver ir!\n </DialogTitle>\n </DialogHeader>\n\n <div className=\"bg-red-50 p-4 lg:p-5 rounded-lg flex items-center gap-4\">\n <TriangleAlert size={20} className=\"text-red-500 shrink-0\" strokeWidth={2} />\n <p className=\"paragraph-small-regular text-gray-600\">\n Todas suas{' '}\n <span className=\"font-semibold text-gray-950\">{pagesCount} páginas</span>{' '}\n serão deletadas permanentemente. Essa ação é{' '}\n <span className=\"font-semibold text-gray-950\">irreversível!</span>\n </p>\n </div>\n </div>\n\n <div className=\"h-px bg-gray-200\" />\n\n <div className=\"flex items-center gap-2 p-4 lg:p-5\">\n <Button className=\"h-10 flex-1\" onClick={close}>\n Manter minha conta\n </Button>\n <Button variant=\"secondary\" className=\"h-10! flex-1\" onClick={handleConfirm}>\n Excluir mesmo assim\n </Button>\n </div>\n </DialogContent>\n </Dialog>\n );\n}\n"],"mappings":";AAeM,cAmBQ,YAnBR;AAbN,SAAS,qBAAqB;AAC9B,SAAS,aAAa;AACtB,SAAS,QAAQ,eAAe,cAAc,mBAAmB;AACjE,SAAS,cAAc;AACvB,SAAS,aAAa;AACtB,SAAS,wBAAwB;AAElB,SAAR,4BAA6C;AAClD,QAAM,EAAE,aAAa,YAAY,MAAM,IAAI,iBAAiB;AAC5D,QAAM,OAAO,gBAAgB;AAE7B,QAAM,gBAAgB,MAAM;AAC1B,UAAM,OAAO,CAAC,MACZ,oBAAC,SAAM,SAAQ,WAAU,SAAQ,iCAA6B,SAAS,GAAG,CAC3E;AACD,UAAM;AAAA,EACR;AAEA,SACE,oBAAC,UAAO,MAAY,cAAc,OAChC,+BAAC,iBAAc,WAAU,2NACvB;AAAA,yBAAC,SAAI,WAAU,kCACb;AAAA,0BAAC,gBAAa,WAAU,OACtB,8BAAC,eAAY,WAAU,2CAA0C,iCAEjE,GACF;AAAA,MAEA,qBAAC,SAAI,WAAU,2DACb;AAAA,4BAAC,iBAAc,MAAM,IAAI,WAAU,yBAAwB,aAAa,GAAG;AAAA,QAC3E,qBAAC,OAAE,WAAU,yCAAwC;AAAA;AAAA,UACxC;AAAA,UACX,qBAAC,UAAK,WAAU,+BAA+B;AAAA;AAAA,YAAW;AAAA,aAAQ;AAAA,UAAQ;AAAA,UAAI;AAAA,UACjC;AAAA,UAC7C,oBAAC,UAAK,WAAU,+BAA8B,8BAAa;AAAA,WAC7D;AAAA,SACF;AAAA,OACF;AAAA,IAEA,oBAAC,SAAI,WAAU,oBAAmB;AAAA,IAElC,qBAAC,SAAI,WAAU,sCACb;AAAA,0BAAC,UAAO,WAAU,eAAc,SAAS,OAAO,gCAEhD;AAAA,MACA,oBAAC,UAAO,SAAQ,aAAY,WAAU,gBAAe,SAAS,eAAe,iCAE7E;AAAA,OACF;AAAA,KACF,GACF;AAEJ;","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/account/DeleteAccountModal.tsx"],"sourcesContent":["'use client';\
|
|
1
|
+
{"version":3,"sources":["../../../src/components/account/DeleteAccountModal.tsx"],"sourcesContent":["'use client';\n\nimport { useState, useCallback } from 'react';\nimport { Lock, TriangleAlert } from 'lucide-react';\nimport { toast } from 'sonner';\nimport { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from '../ui/overlay/Dialog';\nimport { Button } from '../ui/buttons/Button';\nimport { FormField } from '../ui/form/FormField';\nimport { SelectField } from '../ui/form/SelectField';\nimport { TextAreaField } from '../ui/form/TextAreaField';\nimport { Toast } from '../ui/feedback/Toast';\nimport usePasswordVisibility from '../../hooks/usePasswordVisibility';\nimport { useAccountModals } from '../../store/useAccountModals';\nimport { AccountSectionType } from '../../enums/AccountSectionType';\n\nconst REASON_OPTIONS = [\n { value: 'sem-funcao', label: 'A ferramenta não possui uma função que eu preciso' },\n { value: 'problemas', label: 'Encontrei problemas técnicos ou erros no sistema' },\n { value: 'suporte', label: 'Tive problemas com o suporte ou atendimento' },\n { value: 'demora', label: 'As atualizações demoram mais do que o esperado' },\n { value: 'temporario', label: 'O cancelamento é temporário' },\n { value: 'outro', label: 'Outro motivo' },\n];\n\nexport default function DeleteAccountModal() {\n const { activeModal, pagesCount, openConfigurations, openConfirmDelete, close } = useAccountModals();\n const open = activeModal === 'deleteAccount';\n\n const [reason, setReason] = useState('');\n const [description, setDescription] = useState('');\n const [password, setPassword] = useState('');\n const { showPassword, togglePassword } = usePasswordVisibility();\n\n const isFormValid = Boolean(reason && description && password);\n\n const resetForm = useCallback(() => {\n setReason('');\n setDescription('');\n setPassword('');\n }, []);\n\n const handleClose = () => {\n resetForm();\n openConfigurations(AccountSectionType.SECURITY);\n };\n\n const handleDelete = (e: React.FormEvent) => {\n e.preventDefault();\n if (!isFormValid) {\n toast.custom((t) => (\n <Toast variant=\"error\" message=\"Preencha todos os campos obrigatórios\" toastId={t} />\n ));\n return;\n }\n resetForm();\n openConfirmDelete(pagesCount);\n };\n\n return (\n <Dialog open={open} onOpenChange={handleClose}>\n <DialogContent className=\"flex flex-col p-0 gap-0 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-lg! 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%]! overflow-y-auto\">\n <form onSubmit={handleDelete} className=\"flex flex-col flex-1 lg:flex-none\">\n <div className=\"flex flex-col gap-6 p-4 lg:p-6 flex-1 lg:flex-none\">\n <DialogHeader className=\"p-0\">\n <div className=\"flex items-center justify-center w-fit bg-red-50 rounded-lg p-2.5 mb-5\">\n <TriangleAlert size={20} className=\"text-red-500\" />\n </div>\n <DialogTitle>Excluir conta</DialogTitle>\n <DialogDescription className=\"paragraph-small-regular\">\n Esta ação é <span className=\"font-semibold text-gray-950\">irreversível</span>. Ao\n confirmar, sua conta e todos os seus dados serão excluídos.\n </DialogDescription>\n </DialogHeader>\n\n <SelectField\n label=\"Motivo do cancelamento\"\n required\n placeholder=\"Selecione\"\n options={REASON_OPTIONS}\n value={reason}\n onChange={(value) => setReason(value as string)}\n className=\"h-10!\"\n />\n\n <div>\n <TextAreaField\n label=\"Descreva o que levou a tomar essa decisão\"\n required\n placeholder=\"Explique sua decisão...\"\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n rows={4}\n maxLength={400}\n />\n <span className=\"paragraph-xsmall-medium text-gray-600 text-left mt-1 block\">\n {description.length}/400 caracteres\n </span>\n </div>\n\n <FormField\n className=\"text-gray-600\"\n label=\"Senha\"\n type=\"password\"\n placeholder=\"Informe sua senha\"\n leftIcon={Lock}\n value={password}\n onChange={(e) => setPassword(e.target.value)}\n classnameContainer=\"h-10!\"\n showPassword={showPassword}\n onTogglePassword={togglePassword}\n />\n </div>\n\n <div className=\"flex flex-row items-center gap-2 p-4 lg:p-6 border-t border-gray-200 bg-white mt-auto lg:mt-0\">\n <Button\n variant=\"default\"\n className=\"h-10 flex-1 bg-gray-950 text-white hover:bg-gray-800\"\n type=\"submit\"\n >\n Excluir conta\n </Button>\n <Button variant=\"secondary\" className=\"h-10 flex-1\" type=\"button\" onClick={handleClose}>\n Fechar\n </Button>\n </div>\n </form>\n </DialogContent>\n </Dialog>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/account/IsntPossibleDeleteAccountModal.tsx"],"sourcesContent":["'use client';\
|
|
1
|
+
{"version":3,"sources":["../../../src/components/account/IsntPossibleDeleteAccountModal.tsx"],"sourcesContent":["'use client';\n\nimport { TriangleAlert } from 'lucide-react';\nimport { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from '../ui/overlay/Dialog';\nimport { Button } from '../ui/buttons/Button';\nimport { useAccountModals } from '../../store/useAccountModals';\n\nexport default function IsntPossibleDeleteAccountModal() {\n const { activeModal, close, config } = useAccountModals();\n const { onGoToSubscription } = config;\n const open = activeModal === 'isntPossibleDelete';\n\n return (\n <Dialog open={open} onOpenChange={close}>\n <DialogContent className=\"max-w-[calc(100%-2rem)]! w-full rounded-lg border sm:max-w-[400px]! lg:max-w-[470px]! lg:top-[50%]! lg:left-[50%]! lg:right-auto! lg:bottom-auto! lg:translate-x-[-50%]! lg:translate-y-[-50%]!\">\n <div className=\"flex flex-col gap-5\">\n <div className=\"flex items-center justify-center w-fit bg-red-50 rounded-lg p-2.5\">\n <TriangleAlert size={20} className=\"text-red-500\" />\n </div>\n <DialogHeader className=\"p-0 gap-2\">\n <DialogTitle className=\"paragraph-medium-semibold text-gray-950\">\n Não é possível excluir a conta\n </DialogTitle>\n <DialogDescription className=\"paragraph-small-regular text-gray-600\">\n Você tem uma assinatura ativa. Para excluir sua conta,{' '}\n <span className=\"font-semibold text-gray-950\">primeiro cancele a assinatura</span> na\n página Assinatura e depois tente novamente.\n </DialogDescription>\n </DialogHeader>\n </div>\n\n <div className=\"h-px bg-gray-200 -mx-6\" />\n\n <div className=\"flex flex-row items-center gap-2\">\n <Button className=\"h-10 flex-1\" onClick={close}>\n Ok, entendi\n </Button>\n <Button\n variant=\"secondary\"\n className=\"h-10 flex-1\"\n onClick={onGoToSubscription ?? close}\n >\n Ir para assinatura\n </Button>\n </div>\n </DialogContent>\n </Dialog>\n );\n}\n"],"mappings":";AAiBY,cAMA,YANA;AAfZ,SAAS,qBAAqB;AAC9B,SAAS,QAAQ,eAAe,mBAAmB,cAAc,mBAAmB;AACpF,SAAS,cAAc;AACvB,SAAS,wBAAwB;AAElB,SAAR,iCAAkD;AACvD,QAAM,EAAE,aAAa,OAAO,OAAO,IAAI,iBAAiB;AACxD,QAAM,EAAE,mBAAmB,IAAI;AAC/B,QAAM,OAAO,gBAAgB;AAE7B,SACE,oBAAC,UAAO,MAAY,cAAc,OAChC,+BAAC,iBAAc,WAAU,mMACvB;AAAA,yBAAC,SAAI,WAAU,uBACb;AAAA,0BAAC,SAAI,WAAU,qEACb,8BAAC,iBAAc,MAAM,IAAI,WAAU,gBAAe,GACpD;AAAA,MACA,qBAAC,gBAAa,WAAU,aACtB;AAAA,4BAAC,eAAY,WAAU,2CAA0C,qDAEjE;AAAA,QACA,qBAAC,qBAAkB,WAAU,yCAAwC;AAAA;AAAA,UACZ;AAAA,UACvD,oBAAC,UAAK,WAAU,+BAA8B,2CAA6B;AAAA,UAAO;AAAA,WAEpF;AAAA,SACF;AAAA,OACF;AAAA,IAEA,oBAAC,SAAI,WAAU,0BAAyB;AAAA,IAExC,qBAAC,SAAI,WAAU,oCACb;AAAA,0BAAC,UAAO,WAAU,eAAc,SAAS,OAAO,yBAEhD;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC,SAAQ;AAAA,UACR,WAAU;AAAA,UACV,SAAS,sBAAsB;AAAA,UAChC;AAAA;AAAA,MAED;AAAA,OACF;AAAA,KACF,GACF;AAEJ;","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/components/account/hooks/useTwoFactorAuthForm.tsx"],"sourcesContent":["'use client';\
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/account/hooks/useTwoFactorAuthForm.tsx"],"sourcesContent":["'use client';\n\nimport { useState, useCallback, useEffect } from 'react';\nimport { useMutation } from '@tanstack/react-query';\nimport { toast } from 'sonner';\nimport { Toast } from '../../ui/feedback/Toast';\nimport { copyToClipboard } from '../../../utils/browser/clipboard';\nimport {\n generateTwoFactorAction,\n confirmTwoFactorAction,\n} from '../../../modules/accounts/actions/account-management.action';\nimport { withAction } from '../../../utils/withAction';\n\ntype Step = 'code' | 'recovery';\n\ninterface UseTwoFactorAuthFormProps {\n onSuccess?: () => void;\n open?: boolean;\n}\n\nexport default function useTwoFactorAuthForm({ onSuccess, open }: UseTwoFactorAuthFormProps = {}) {\n const [code, setCode] = useState('');\n const [step, setStep] = useState<Step>('code');\n\n const generateMutation = useMutation({\n mutationFn: withAction(generateTwoFactorAction),\n onError: () => {\n toast.custom((t) => (\n <Toast variant=\"error\" message=\"Erro ao gerar QR Code. Tente novamente.\" toastId={t} />\n ));\n },\n });\n\n const confirmMutation = useMutation({\n mutationFn: withAction(confirmTwoFactorAction),\n onSuccess: () => {\n setStep('recovery');\n },\n onError: () => {\n toast.custom((t) => (\n <Toast variant=\"error\" message=\"Erro ao confirmar código. Tente novamente.\" toastId={t} />\n ));\n },\n });\n\n const { mutate: triggerGenerate } = generateMutation;\n\n useEffect(() => {\n if (open) {\n triggerGenerate();\n }\n }, [open, triggerGenerate]);\n\n const generateFailed = generateMutation.isError;\n\n const isCodeComplete = code.length === 6;\n\n const handleSubmit = () => {\n if (!isCodeComplete) return;\n confirmMutation.mutate(code);\n };\n\n const handleFinalize = () => {\n onSuccess?.();\n setTimeout(resetForm, 300);\n };\n\n const handleCopyCodes = useCallback(async () => {\n const codes = generateMutation.data?.backupCodes ?? [];\n const success = await copyToClipboard(codes.join('\\n'));\n if (success) {\n toast.custom((t) => (\n <Toast variant=\"success\" message=\"Códigos copiados com sucesso\" toastId={t} />\n ));\n }\n }, [generateMutation.data]);\n\n const resetForm = () => {\n setCode('');\n setStep('code');\n generateMutation.reset();\n confirmMutation.reset();\n };\n\n return {\n code,\n setCode,\n isCodeComplete,\n isGenerating: generateMutation.isPending,\n isConfirming: confirmMutation.isPending,\n generateFailed,\n retryGenerate: triggerGenerate,\n qrcode: generateMutation.data?.qrcode,\n backupCodes: generateMutation.data?.backupCodes ?? [],\n step,\n handleSubmit,\n handleFinalize,\n handleCopyCodes,\n resetForm,\n };\n}\n"],"mappings":";AA4BQ;AA1BR,SAAS,UAAU,aAAa,iBAAiB;AACjD,SAAS,mBAAmB;AAC5B,SAAS,aAAa;AACtB,SAAS,aAAa;AACtB,SAAS,uBAAuB;AAChC;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP,SAAS,kBAAkB;AASZ,SAAR,qBAAsC,EAAE,WAAW,KAAK,IAA+B,CAAC,GAAG;AAChG,QAAM,CAAC,MAAM,OAAO,IAAI,SAAS,EAAE;AACnC,QAAM,CAAC,MAAM,OAAO,IAAI,SAAe,MAAM;AAE7C,QAAM,mBAAmB,YAAY;AAAA,IACnC,YAAY,WAAW,uBAAuB;AAAA,IAC9C,SAAS,MAAM;AACb,YAAM,OAAO,CAAC,MACZ,oBAAC,SAAM,SAAQ,SAAQ,SAAQ,2CAA0C,SAAS,GAAG,CACtF;AAAA,IACH;AAAA,EACF,CAAC;AAED,QAAM,kBAAkB,YAAY;AAAA,IAClC,YAAY,WAAW,sBAAsB;AAAA,IAC7C,WAAW,MAAM;AACf,cAAQ,UAAU;AAAA,IACpB;AAAA,IACA,SAAS,MAAM;AACb,YAAM,OAAO,CAAC,MACZ,oBAAC,SAAM,SAAQ,SAAQ,SAAQ,iDAA6C,SAAS,GAAG,CACzF;AAAA,IACH;AAAA,EACF,CAAC;AAED,QAAM,EAAE,QAAQ,gBAAgB,IAAI;AAEpC,YAAU,MAAM;AACd,QAAI,MAAM;AACR,sBAAgB;AAAA,IAClB;AAAA,EACF,GAAG,CAAC,MAAM,eAAe,CAAC;AAE1B,QAAM,iBAAiB,iBAAiB;AAExC,QAAM,iBAAiB,KAAK,WAAW;AAEvC,QAAM,eAAe,MAAM;AACzB,QAAI,CAAC,eAAgB;AACrB,oBAAgB,OAAO,IAAI;AAAA,EAC7B;AAEA,QAAM,iBAAiB,MAAM;AAC3B,gBAAY;AACZ,eAAW,WAAW,GAAG;AAAA,EAC3B;AAEA,QAAM,kBAAkB,YAAY,YAAY;AAC9C,UAAM,QAAQ,iBAAiB,MAAM,eAAe,CAAC;AACrD,UAAM,UAAU,MAAM,gBAAgB,MAAM,KAAK,IAAI,CAAC;AACtD,QAAI,SAAS;AACX,YAAM,OAAO,CAAC,MACZ,oBAAC,SAAM,SAAQ,WAAU,SAAQ,mCAA+B,SAAS,GAAG,CAC7E;AAAA,IACH;AAAA,EACF,GAAG,CAAC,iBAAiB,IAAI,CAAC;AAE1B,QAAM,YAAY,MAAM;AACtB,YAAQ,EAAE;AACV,YAAQ,MAAM;AACd,qBAAiB,MAAM;AACvB,oBAAgB,MAAM;AAAA,EACxB;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,cAAc,iBAAiB;AAAA,IAC/B,cAAc,gBAAgB;AAAA,IAC9B;AAAA,IACA,eAAe;AAAA,IACf,QAAQ,iBAAiB,MAAM;AAAA,IAC/B,aAAa,iBAAiB,MAAM,eAAe,CAAC;AAAA,IACpD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/layouts/AppMobileNavBar.tsx"],"sourcesContent":["\"use client\";\
|
|
1
|
+
{"version":3,"sources":["../../../src/components/layouts/AppMobileNavBar.tsx"],"sourcesContent":["\"use client\";\n\nimport { ReactNode } from \"react\";\nimport Image from \"next/image\";\nimport { ProfilePopover } from \"./ProfilePopover\";\nimport { useAccountModals } from \"../../store/useAccountModals\";\nimport type { ProfileMenuItem } from \"./ProfilePopover\";\nimport { Tooltip, TooltipContent, TooltipTrigger } from \"../ui/overlay/Tooltip\";\n\nexport interface AppMobileNavBarProps {\n /** Which app is currently active — controls which icon gets the indicator */\n activeApp?: \"gapps\" | \"gpages\";\n /** Called when the GreatApps logo is clicked */\n onLogoClick?: () => void;\n /** Called when the app icon (e.g. GreatPages) is clicked */\n onAppIconClick?: () => void;\n /** Extra slot rendered after the app icon (e.g. project selector) */\n extraLeftSlot?: ReactNode;\n /** Required: the right-side action element (toggle button, sheet button, etc.) */\n rightActionSlot: ReactNode;\n menuItems?: ProfileMenuItem[];\n onCreditsClick?: () => void;\n}\n\nexport function AppMobileNavBar({\n activeApp,\n onLogoClick,\n onAppIconClick,\n extraLeftSlot,\n rightActionSlot,\n menuItems = [],\n onCreditsClick,\n}: AppMobileNavBarProps) {\n const { openConfigurations } = useAccountModals();\n\n const isGpagesActive = activeApp === \"gpages\";\n const isGappsActive = activeApp === \"gapps\";\n\n return (\n <div className=\"fixed top-0 left-0 right-0 flex md:hidden items-center justify-between p-4 bg-white z-50 border-b border-gray-200\">\n <div className=\"flex items-center gap-1.5\">\n <Tooltip>\n <TooltipTrigger asChild>\n <div\n className={`relative size-10 flex items-center justify-center rounded-lg transition-colors ${onLogoClick ? \"cursor-pointer hover:bg-gray-100\" : \"\"}`}\n onClick={onLogoClick}\n >\n <Image\n src=\"/icons/great-icon.svg\"\n alt=\"GreatApps\"\n width={28}\n height={28}\n />\n {isGappsActive && (\n <div className=\"absolute bottom-[-17px] left-1/2 -translate-x-1/2 w-5 h-[3px] bg-gray-950 rounded-t-xl\" />\n )}\n </div>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\">GreatApps</TooltipContent>\n </Tooltip>\n <div className=\"relative\">\n <Tooltip>\n <TooltipTrigger asChild>\n {isGpagesActive ? (\n <div\n className=\"size-10 rounded-xl cursor-pointer p-[2px]\"\n style={{\n border: \"1.5px solid rgba(153,234,255,0.75)\",\n background: \"white\",\n boxShadow:\n \"0 0 8px rgba(153,234,255,0.5), 0 0 18px rgba(153,234,255,0.2)\",\n }}\n onClick={onAppIconClick}\n >\n <div\n className=\"w-full h-full rounded-lg flex items-center justify-center\"\n style={{\n background:\n \"radial-gradient(circle at center, rgba(255,255,255,0.95) 0%, rgba(153,234,255,0.45) 100%)\",\n }}\n >\n <Image\n src=\"/icons/icon-navbar.svg\"\n alt=\"GreatPages\"\n width={24}\n height={24}\n />\n </div>\n </div>\n ) : (\n <div\n className={`size-10 flex items-center justify-center rounded-lg transition-colors duration-300 bg-gray-100 ${onAppIconClick ? \"cursor-pointer hover:opacity-80\" : \"\"}`}\n onClick={onAppIconClick}\n >\n <Image\n src=\"/icons/icon-navbar.svg\"\n alt=\"GreatPages\"\n width={24}\n height={24}\n />\n </div>\n )}\n </TooltipTrigger>\n <TooltipContent side=\"bottom\">GreatPages</TooltipContent>\n </Tooltip>\n {isGpagesActive && (\n <div className=\"absolute -bottom-[17px] left-1/2 -translate-x-1/2 w-5 h-[3px] rounded-t-xl\" style={{ backgroundColor: \"#6ADCFF\" }} />\n )}\n </div>\n {extraLeftSlot}\n </div>\n <div className=\"flex items-center gap-1.5\">\n <ProfilePopover\n side=\"bottom\"\n align=\"end\"\n contentClassName=\"\"\n onEditProfile={() => openConfigurations()}\n onCreditsClick={onCreditsClick}\n menuItems={menuItems}\n />\n {rightActionSlot}\n </div>\n </div>\n );\n}\n"],"mappings":";AA2CY,SAIE,KAJF;AAxCZ,OAAO,WAAW;AAClB,SAAS,sBAAsB;AAC/B,SAAS,wBAAwB;AAEjC,SAAS,SAAS,gBAAgB,sBAAsB;AAiBjD,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAY,CAAC;AAAA,EACb;AACF,GAAyB;AACvB,QAAM,EAAE,mBAAmB,IAAI,iBAAiB;AAEhD,QAAM,iBAAiB,cAAc;AACrC,QAAM,gBAAgB,cAAc;AAEpC,SACE,qBAAC,SAAI,WAAU,qHACb;AAAA,yBAAC,SAAI,WAAU,6BACb;AAAA,2BAAC,WACC;AAAA,4BAAC,kBAAe,SAAO,MACrB;AAAA,UAAC;AAAA;AAAA,YACC,WAAW,kFAAkF,cAAc,qCAAqC,EAAE;AAAA,YAClJ,SAAS;AAAA,YAET;AAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,KAAI;AAAA,kBACJ,KAAI;AAAA,kBACJ,OAAO;AAAA,kBACP,QAAQ;AAAA;AAAA,cACV;AAAA,cACC,iBACC,oBAAC,SAAI,WAAU,0FAAyF;AAAA;AAAA;AAAA,QAE5G,GACF;AAAA,QACA,oBAAC,kBAAe,MAAK,UAAS,uBAAS;AAAA,SACzC;AAAA,MACA,qBAAC,SAAI,WAAU,YACb;AAAA,6BAAC,WACC;AAAA,8BAAC,kBAAe,SAAO,MACpB,2BACC;AAAA,YAAC;AAAA;AAAA,cACC,WAAU;AAAA,cACV,OAAO;AAAA,gBACL,QAAQ;AAAA,gBACR,YAAY;AAAA,gBACZ,WACE;AAAA,cACJ;AAAA,cACA,SAAS;AAAA,cAET;AAAA,gBAAC;AAAA;AAAA,kBACC,WAAU;AAAA,kBACV,OAAO;AAAA,oBACL,YACE;AAAA,kBACJ;AAAA,kBAEA;AAAA,oBAAC;AAAA;AAAA,sBACC,KAAI;AAAA,sBACJ,KAAI;AAAA,sBACJ,OAAO;AAAA,sBACP,QAAQ;AAAA;AAAA,kBACV;AAAA;AAAA,cACF;AAAA;AAAA,UACF,IAEA;AAAA,YAAC;AAAA;AAAA,cACC,WAAW,kGAAkG,iBAAiB,oCAAoC,EAAE;AAAA,cACpK,SAAS;AAAA,cAET;AAAA,gBAAC;AAAA;AAAA,kBACC,KAAI;AAAA,kBACJ,KAAI;AAAA,kBACJ,OAAO;AAAA,kBACP,QAAQ;AAAA;AAAA,cACV;AAAA;AAAA,UACF,GAEJ;AAAA,UACA,oBAAC,kBAAe,MAAK,UAAS,wBAAU;AAAA,WAC1C;AAAA,QACC,kBACC,oBAAC,SAAI,WAAU,8EAA6E,OAAO,EAAE,iBAAiB,UAAU,GAAG;AAAA,SAEvI;AAAA,MACC;AAAA,OACH;AAAA,IACA,qBAAC,SAAI,WAAU,6BACb;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,OAAM;AAAA,UACN,kBAAiB;AAAA,UACjB,eAAe,MAAM,mBAAmB;AAAA,UACxC;AAAA,UACA;AAAA;AAAA,MACF;AAAA,MACC;AAAA,OACH;AAAA,KACF;AAEJ;","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/layouts/AppNavBar.tsx"],"sourcesContent":["\"use client\";\
|
|
1
|
+
{"version":3,"sources":["../../../src/components/layouts/AppNavBar.tsx"],"sourcesContent":["\"use client\";\n\nimport { useRouter } from \"next/navigation\";\nimport { NavBar } from \"./NavBar\";\nimport { ProfilePopover } from \"./ProfilePopover\";\nimport { NotificationsPopover } from \"./NotificationsPopover\";\nimport { useAccountModals } from \"../../store/useAccountModals\";\nimport type { ProfileMenuItem } from \"./ProfilePopover\";\n\nexport interface AppNavBarProps {\n onLogoClick?: () => void;\n /** Which app is currently active — controls which icon gets the indicator */\n activeApp?: \"gapps\" | \"gpages\";\n appIconHref?: string;\n showExpandButton?: boolean;\n onExpandClick?: () => void;\n menuItems?: ProfileMenuItem[];\n onCreditsClick?: () => void;\n onNotificationsViewAll?: () => void;\n logoutRedirect?: string;\n}\n\nexport function AppNavBar({\n onLogoClick,\n activeApp,\n appIconHref = \"/\",\n showExpandButton = false,\n onExpandClick,\n menuItems = [],\n onCreditsClick,\n onNotificationsViewAll,\n logoutRedirect,\n}: AppNavBarProps) {\n const router = useRouter();\n const { openConfigurations } = useAccountModals();\n\n const handleLogoClick = onLogoClick ?? (() => router.push(\"/\"));\n const handleAppIconClick = () => router.push(appIconHref);\n\n return (\n <NavBar\n onLogoClick={handleLogoClick}\n onAppIconClick={handleAppIconClick}\n activeApp={activeApp}\n showExpandButton={showExpandButton}\n onExpandClick={onExpandClick}\n >\n <NotificationsPopover onViewAll={onNotificationsViewAll} />\n <ProfilePopover\n onEditProfile={() => openConfigurations()}\n onCreditsClick={onCreditsClick}\n menuItems={menuItems}\n logoutRedirect={logoutRedirect}\n />\n </NavBar>\n );\n}\n"],"mappings":";AAwCI,SAOE,KAPF;AAtCJ,SAAS,iBAAiB;AAC1B,SAAS,cAAc;AACvB,SAAS,sBAAsB;AAC/B,SAAS,4BAA4B;AACrC,SAAS,wBAAwB;AAgB1B,SAAS,UAAU;AAAA,EACxB;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd,mBAAmB;AAAA,EACnB;AAAA,EACA,YAAY,CAAC;AAAA,EACb;AAAA,EACA;AAAA,EACA;AACF,GAAmB;AACjB,QAAM,SAAS,UAAU;AACzB,QAAM,EAAE,mBAAmB,IAAI,iBAAiB;AAEhD,QAAM,kBAAkB,gBAAgB,MAAM,OAAO,KAAK,GAAG;AAC7D,QAAM,qBAAqB,MAAM,OAAO,KAAK,WAAW;AAExD,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAa;AAAA,MACb,gBAAgB;AAAA,MAChB;AAAA,MACA;AAAA,MACA;AAAA,MAEA;AAAA,4BAAC,wBAAqB,WAAW,wBAAwB;AAAA,QACzD;AAAA,UAAC;AAAA;AAAA,YACC,eAAe,MAAM,mBAAmB;AAAA,YACxC;AAAA,YACA;AAAA,YACA;AAAA;AAAA,QACF;AAAA;AAAA;AAAA,EACF;AAEJ;","names":[]}
|
|
@@ -70,7 +70,35 @@ function NavBar({
|
|
|
70
70
|
] }),
|
|
71
71
|
/* @__PURE__ */ jsx("div", { className: "flex flex-col gap-2", children: /* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
72
72
|
/* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
73
|
-
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, onClick: onAppIconClick, children:
|
|
73
|
+
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, onClick: onAppIconClick, children: activeApp === "gpages" ? /* @__PURE__ */ jsx(
|
|
74
|
+
"div",
|
|
75
|
+
{
|
|
76
|
+
className: "size-10 rounded-xl cursor-pointer p-[2px]",
|
|
77
|
+
style: {
|
|
78
|
+
border: "1.5px solid rgba(153,234,255,0.75)",
|
|
79
|
+
background: "white",
|
|
80
|
+
boxShadow: "0 0 8px rgba(153,234,255,0.5), 0 0 18px rgba(153,234,255,0.2)"
|
|
81
|
+
},
|
|
82
|
+
children: /* @__PURE__ */ jsx(
|
|
83
|
+
"div",
|
|
84
|
+
{
|
|
85
|
+
className: "w-full h-full rounded-lg flex items-center justify-center",
|
|
86
|
+
style: {
|
|
87
|
+
background: "radial-gradient(circle at center, rgba(255,255,255,0.95) 0%, rgba(153,234,255,0.45) 100%)"
|
|
88
|
+
},
|
|
89
|
+
children: /* @__PURE__ */ jsx(
|
|
90
|
+
Image,
|
|
91
|
+
{
|
|
92
|
+
src: "/icons/icon-navbar.svg",
|
|
93
|
+
alt: "GreatPages",
|
|
94
|
+
width: 24,
|
|
95
|
+
height: 24
|
|
96
|
+
}
|
|
97
|
+
)
|
|
98
|
+
}
|
|
99
|
+
)
|
|
100
|
+
}
|
|
101
|
+
) : /* @__PURE__ */ jsx("div", { className: "size-10 flex items-center justify-center rounded-lg cursor-pointer hover:bg-gray-100 transition-colors duration-300", children: /* @__PURE__ */ jsx(
|
|
74
102
|
Image,
|
|
75
103
|
{
|
|
76
104
|
src: "/icons/icon-navbar.svg",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/layouts/NavBar.tsx"],"sourcesContent":["\"use client\";\
|
|
1
|
+
{"version":3,"sources":["../../../src/components/layouts/NavBar.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport Image from \"next/image\";\nimport { ChevronRight } from \"lucide-react\";\nimport { Separator } from \"../ui/data-display/Separator\";\nimport { Tooltip, TooltipContent, TooltipTrigger } from \"../ui/overlay/Tooltip\";\nimport { cn } from \"../../infra/utils/clsx\";\n\ntype NavBarProps = {\n onLogoClick: () => void;\n onAppIconClick?: () => void;\n activeApp?: \"gapps\" | \"gpages\";\n showExpandButton?: boolean;\n onExpandClick?: () => void;\n children?: React.ReactNode;\n className?: string;\n};\n\nfunction NavBar({\n onLogoClick,\n onAppIconClick,\n activeApp,\n showExpandButton = false,\n onExpandClick,\n children,\n className,\n}: NavBarProps) {\n return (\n <div\n className={cn(\n \"hidden md:flex flex-col justify-between h-screen p-4 border-r border-gray-200 overflow-visible z-40 bg-white\",\n className,\n )}\n >\n <div className=\"flex flex-col gap-4 items-center mt-[6.5px]\">\n {/* GreatApps logo */}\n <div className=\"relative\">\n <Tooltip>\n <TooltipTrigger\n className=\"cursor-pointer\"\n asChild\n onClick={onLogoClick}\n >\n <Image\n src=\"/icons/great-icon.svg\"\n alt=\"Great Icon\"\n width={28}\n height={28}\n />\n </TooltipTrigger>\n <TooltipContent side=\"right\">GreatApps</TooltipContent>\n </Tooltip>\n <div\n className={cn(\n \"absolute -left-[22px] top-1/2 -translate-y-1/2 w-[3px] h-5 bg-gray-950 rounded-r-xl transition-opacity duration-300\",\n activeApp === \"gapps\" ? \"opacity-100\" : \"opacity-0\",\n )}\n />\n </div>\n\n <div className=\"relative w-full mt-[7.5px]\">\n <Separator />\n {showExpandButton && (\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n onClick={onExpandClick}\n className=\"lg:hidden absolute top-1/2 -translate-y-1/2 right-0 translate-x-[calc(50%+1rem)] size-8 flex items-center justify-center rounded-full border border-gray-200 bg-white hover:bg-gray-100 cursor-pointer transition-colors z-10\"\n >\n <ChevronRight size={16} className=\"text-gray-500\" />\n </button>\n </TooltipTrigger>\n <TooltipContent side=\"right\">Expandir menu</TooltipContent>\n </Tooltip>\n )}\n </div>\n\n {/* GreatPages icon */}\n <div className=\"flex flex-col gap-2\">\n <div className=\"relative\">\n <Tooltip>\n <TooltipTrigger asChild onClick={onAppIconClick}>\n {activeApp === \"gpages\" ? (\n <div\n className=\"size-10 rounded-xl cursor-pointer p-[2px]\"\n style={{\n border: \"1.5px solid rgba(153,234,255,0.75)\",\n background: \"white\",\n boxShadow:\n \"0 0 8px rgba(153,234,255,0.5), 0 0 18px rgba(153,234,255,0.2)\",\n }}\n >\n <div\n className=\"w-full h-full rounded-lg flex items-center justify-center\"\n style={{\n background:\n \"radial-gradient(circle at center, rgba(255,255,255,0.95) 0%, rgba(153,234,255,0.45) 100%)\",\n }}\n >\n <Image\n src=\"/icons/icon-navbar.svg\"\n alt=\"GreatPages\"\n width={24}\n height={24}\n />\n </div>\n </div>\n ) : (\n <div className=\"size-10 flex items-center justify-center rounded-lg cursor-pointer hover:bg-gray-100 transition-colors duration-300\">\n <Image\n src=\"/icons/icon-navbar.svg\"\n alt=\"GreatPages\"\n width={28}\n height={28}\n />\n </div>\n )}\n </TooltipTrigger>\n <TooltipContent side=\"right\">GreatPages</TooltipContent>\n </Tooltip>\n <div\n className={cn(\n \"absolute -left-[22px] top-1/2 -translate-y-1/2 w-[3px] h-5 rounded-r-xl transition-opacity duration-300\",\n activeApp === \"gpages\" ? \"opacity-100\" : \"opacity-0\",\n )}\n style={{ backgroundColor: \"#6ADCFF\" }}\n />\n </div>\n </div>\n </div>\n\n <div className=\"flex flex-col items-center gap-2\">{children}</div>\n </div>\n );\n}\n\nexport { NavBar };\nexport type { NavBarProps };\n"],"mappings":";AAsCU,SAMI,KANJ;AAnCV,OAAO,WAAW;AAClB,SAAS,oBAAoB;AAC7B,SAAS,iBAAiB;AAC1B,SAAS,SAAS,gBAAgB,sBAAsB;AACxD,SAAS,UAAU;AAYnB,SAAS,OAAO;AAAA,EACd;AAAA,EACA;AAAA,EACA;AAAA,EACA,mBAAmB;AAAA,EACnB;AAAA,EACA;AAAA,EACA;AACF,GAAgB;AACd,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MAEA;AAAA,6BAAC,SAAI,WAAU,+CAEb;AAAA,+BAAC,SAAI,WAAU,YACb;AAAA,iCAAC,WACC;AAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,WAAU;AAAA,kBACV,SAAO;AAAA,kBACP,SAAS;AAAA,kBAET;AAAA,oBAAC;AAAA;AAAA,sBACC,KAAI;AAAA,sBACJ,KAAI;AAAA,sBACJ,OAAO;AAAA,sBACP,QAAQ;AAAA;AAAA,kBACV;AAAA;AAAA,cACF;AAAA,cACA,oBAAC,kBAAe,MAAK,SAAQ,uBAAS;AAAA,eACxC;AAAA,YACA;AAAA,cAAC;AAAA;AAAA,gBACC,WAAW;AAAA,kBACT;AAAA,kBACA,cAAc,UAAU,gBAAgB;AAAA,gBAC1C;AAAA;AAAA,YACF;AAAA,aACF;AAAA,UAEA,qBAAC,SAAI,WAAU,8BACb;AAAA,gCAAC,aAAU;AAAA,YACV,oBACC,qBAAC,WACC;AAAA,kCAAC,kBAAe,SAAO,MACrB;AAAA,gBAAC;AAAA;AAAA,kBACC,SAAS;AAAA,kBACT,WAAU;AAAA,kBAEV,8BAAC,gBAAa,MAAM,IAAI,WAAU,iBAAgB;AAAA;AAAA,cACpD,GACF;AAAA,cACA,oBAAC,kBAAe,MAAK,SAAQ,2BAAa;AAAA,eAC5C;AAAA,aAEJ;AAAA,UAGA,oBAAC,SAAI,WAAU,uBACb,+BAAC,SAAI,WAAU,YACb;AAAA,iCAAC,WACC;AAAA,kCAAC,kBAAe,SAAO,MAAC,SAAS,gBAC9B,wBAAc,WACb;AAAA,gBAAC;AAAA;AAAA,kBACC,WAAU;AAAA,kBACV,OAAO;AAAA,oBACL,QAAQ;AAAA,oBACR,YAAY;AAAA,oBACZ,WACE;AAAA,kBACJ;AAAA,kBAEA;AAAA,oBAAC;AAAA;AAAA,sBACC,WAAU;AAAA,sBACV,OAAO;AAAA,wBACL,YACE;AAAA,sBACJ;AAAA,sBAEA;AAAA,wBAAC;AAAA;AAAA,0BACC,KAAI;AAAA,0BACJ,KAAI;AAAA,0BACJ,OAAO;AAAA,0BACP,QAAQ;AAAA;AAAA,sBACV;AAAA;AAAA,kBACF;AAAA;AAAA,cACF,IAEA,oBAAC,SAAI,WAAU,uHACb;AAAA,gBAAC;AAAA;AAAA,kBACC,KAAI;AAAA,kBACJ,KAAI;AAAA,kBACJ,OAAO;AAAA,kBACP,QAAQ;AAAA;AAAA,cACV,GACF,GAEJ;AAAA,cACA,oBAAC,kBAAe,MAAK,SAAQ,wBAAU;AAAA,eACzC;AAAA,YACA;AAAA,cAAC;AAAA;AAAA,gBACC,WAAW;AAAA,kBACT;AAAA,kBACA,cAAc,WAAW,gBAAgB;AAAA,gBAC3C;AAAA,gBACA,OAAO,EAAE,iBAAiB,UAAU;AAAA;AAAA,YACtC;AAAA,aACF,GACF;AAAA,WACF;AAAA,QAEA,oBAAC,SAAI,WAAU,oCAAoC,UAAS;AAAA;AAAA;AAAA,EAC9D;AAEJ;","names":[]}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useEffect, useState } from "react";
|
|
4
4
|
import { Plus, Settings, User, Users } from "lucide-react";
|
|
5
|
-
import
|
|
5
|
+
import { UserAvatar } from "../ui/data-display/UserAvatar";
|
|
6
6
|
import { useQueryClient, useMutation } from "@tanstack/react-query";
|
|
7
7
|
import { Popover, PopoverContent, PopoverTrigger } from "../ui/overlay/Popover";
|
|
8
8
|
import { Button } from "../ui/buttons/Button";
|
|
@@ -14,7 +14,6 @@ import { useListProjectUsers, LIST_PROJECT_USERS_BASE_KEY } from "../../modules/
|
|
|
14
14
|
import { useListAvailableUsers, LIST_AVAILABLE_USERS_BASE_KEY } from "../../modules/projects/hooks/list-available-users.hook";
|
|
15
15
|
import { addProjectUserAction } from "../../modules/projects/actions/add-project-user.action";
|
|
16
16
|
import { removeProjectUserAction } from "../../modules/projects/actions/remove-project-user.action";
|
|
17
|
-
const DEFAULT_AVATAR = "/images/Logomark.png";
|
|
18
17
|
function UserItemSkeleton() {
|
|
19
18
|
return /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-2 py-1.5 gap-2", children: [
|
|
20
19
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 flex-1", children: [
|
|
@@ -64,14 +63,14 @@ function UsersSelectorPopover({
|
|
|
64
63
|
...inProject.map((u) => ({
|
|
65
64
|
id: u.id_user,
|
|
66
65
|
name: u.name,
|
|
67
|
-
|
|
66
|
+
photo: u.photo ?? null,
|
|
68
67
|
checked: true,
|
|
69
68
|
removable: u.profile !== "owner" && u.profile !== "admin"
|
|
70
69
|
})),
|
|
71
70
|
...notInProject.map((u) => ({
|
|
72
71
|
id: u.id,
|
|
73
72
|
name: u.name,
|
|
74
|
-
|
|
73
|
+
photo: u.photo ?? null,
|
|
75
74
|
checked: false,
|
|
76
75
|
removable: true
|
|
77
76
|
}))
|
|
@@ -135,7 +134,7 @@ function UsersSelectorPopover({
|
|
|
135
134
|
children: /* @__PURE__ */ jsx(Settings, { size: 18 })
|
|
136
135
|
}
|
|
137
136
|
) }),
|
|
138
|
-
/* @__PURE__ */ jsx(TooltipContent, { children: "Visualizar todos usu\xE1rios" })
|
|
137
|
+
/* @__PURE__ */ jsx(TooltipContent, { className: "z-[1002]", children: "Visualizar todos usu\xE1rios" })
|
|
139
138
|
] })
|
|
140
139
|
] })
|
|
141
140
|
] }),
|
|
@@ -180,13 +179,11 @@ function UsersSelectorPopover({
|
|
|
180
179
|
children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between w-full", children: [
|
|
181
180
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
182
181
|
/* @__PURE__ */ jsx(
|
|
183
|
-
|
|
182
|
+
UserAvatar,
|
|
184
183
|
{
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
height: 32,
|
|
189
|
-
className: "rounded-full"
|
|
184
|
+
photo: user.photo,
|
|
185
|
+
name: user.name ?? void 0,
|
|
186
|
+
size: 32
|
|
190
187
|
}
|
|
191
188
|
),
|
|
192
189
|
user.name
|
|
@@ -208,7 +205,7 @@ function UsersSelectorPopover({
|
|
|
208
205
|
)
|
|
209
206
|
}
|
|
210
207
|
),
|
|
211
|
-
/* @__PURE__ */ jsx(TooltipContent, { children: user.checked ? "Remover do projeto" : "Adicionar ao projeto" })
|
|
208
|
+
/* @__PURE__ */ jsx(TooltipContent, { className: "z-[1002]", children: user.checked ? "Remover do projeto" : "Adicionar ao projeto" })
|
|
212
209
|
] })
|
|
213
210
|
] })
|
|
214
211
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/layouts/UsersSelectorPopover.tsx"],"sourcesContent":["'use client';\r\n\r\n\"use client\"\r\n\r\nimport { useEffect, useState } from 'react';\r\nimport { Plus, Settings, User, Users } from 'lucide-react';\r\nimport Image from 'next/image';\r\nimport { useQueryClient, useMutation } from '@tanstack/react-query';\r\nimport { Popover, PopoverContent, PopoverTrigger } from '../ui/overlay/Popover';\r\nimport { Button } from '../ui/buttons/Button';\r\nimport { Command, CommandEmpty, CommandInput, CommandItem, CommandList } from '../ui/overlay/Command';\r\nimport { Checkbox } from '../ui/form/Checkbox';\r\nimport { Tooltip, TooltipContent, TooltipTrigger } from '../ui/overlay/Tooltip';\r\nimport { cn } from '../../infra/utils/clsx';\r\nimport { useListProjectUsers, LIST_PROJECT_USERS_BASE_KEY } from '../../modules/projects/hooks/list-project-users.hook';\r\nimport { useListAvailableUsers, LIST_AVAILABLE_USERS_BASE_KEY } from '../../modules/projects/hooks/list-available-users.hook';\r\nimport { addProjectUserAction } from '../../modules/projects/actions/add-project-user.action';\r\nimport { removeProjectUserAction } from '../../modules/projects/actions/remove-project-user.action';\r\n\r\nconst DEFAULT_AVATAR = '/images/Logomark.png';\r\n\r\nexport interface UsersSelectorPopoverProps {\r\n projectId?: number;\r\n side?: 'top' | 'bottom' | 'left' | 'right';\r\n align?: 'start' | 'center' | 'end';\r\n contentClassName?: string;\r\n}\r\n\r\nfunction UserItemSkeleton() {\r\n return (\r\n <div className=\"flex items-center justify-between px-2 py-1.5 gap-2\">\r\n <div className=\"flex items-center gap-2 flex-1\">\r\n <div className=\"skeleton size-8 rounded-full shrink-0\" />\r\n <div className=\"skeleton h-3.5 w-28 rounded\" />\r\n </div>\r\n <div className=\"skeleton size-4 rounded shrink-0\" />\r\n </div>\r\n );\r\n}\r\n\r\nconst GAPPS_URL = process.env.NEXT_PUBLIC_GREAT_APPS ?? '';\r\n\r\nexport function UsersSelectorPopover({\r\n projectId,\r\n side,\r\n align,\r\n contentClassName,\r\n}: UsersSelectorPopoverProps) {\r\n const queryClient = useQueryClient();\r\n const [open, setOpen] = useState(false);\r\n const [hoveredId, setHoveredId] = useState<number | null>(null);\r\n const [searchInput, setSearchInput] = useState('');\r\n const [search, setSearch] = useState('');\r\n\r\n const id = projectId ?? 0;\r\n\r\n useEffect(() => {\r\n const timer = setTimeout(() => setSearch(searchInput), 300);\r\n return () => clearTimeout(timer);\r\n }, [searchInput]);\r\n\r\n const projectUsers = useListProjectUsers(id, search);\r\n const availableUsers = useListAvailableUsers(id, search);\r\n\r\n const inProject = projectUsers.data?.pages.flatMap((p) => p.data) ?? [];\r\n const notInProject = availableUsers.data?.pages.flatMap((p) => p.data) ?? [];\r\n const isLoading = projectUsers.isLoading || availableUsers.isLoading;\r\n const isFetchingMore = projectUsers.isFetchingNextPage || availableUsers.isFetchingNextPage;\r\n const totalInProject = projectUsers.data?.pages[0]?.total ?? inProject.length;\r\n\r\n const invalidate = () => {\r\n queryClient.invalidateQueries({ queryKey: LIST_PROJECT_USERS_BASE_KEY(id) });\r\n queryClient.invalidateQueries({ queryKey: LIST_AVAILABLE_USERS_BASE_KEY(id) });\r\n };\r\n\r\n const addMutation = useMutation({\r\n mutationFn: (userId: number) => addProjectUserAction({ projectId: id, users: [userId] }),\r\n onSuccess: invalidate,\r\n });\r\n\r\n const removeMutation = useMutation({\r\n mutationFn: (userId: number) => removeProjectUserAction({ projectId: id, users: [userId] }),\r\n onSuccess: invalidate,\r\n });\r\n\r\n const allUsers = [\r\n ...inProject.map((u) => ({\r\n id: u.id_user,\r\n name: u.name,\r\n avatar: u.photo ?? DEFAULT_AVATAR,\r\n checked: true as const,\r\n removable: u.profile !== 'owner' && u.profile !== 'admin',\r\n })),\r\n ...notInProject.map((u) => ({\r\n id: u.id,\r\n name: u.name,\r\n avatar: u.photo ?? DEFAULT_AVATAR,\r\n checked: false as const,\r\n removable: true,\r\n })),\r\n ];\r\n\r\n const toggleUser = (id: number, checked: boolean, removable: boolean) => {\r\n if (checked) {\r\n if (!removable) return;\r\n removeMutation.mutate(id);\r\n } else {\r\n addMutation.mutate(id);\r\n }\r\n };\r\n\r\n const handleScroll = (e: React.UIEvent<HTMLDivElement>) => {\r\n const target = e.currentTarget;\r\n const nearBottom = target.scrollTop + target.clientHeight >= target.scrollHeight - 50;\r\n if (!nearBottom) return;\r\n if (projectUsers.hasNextPage && !projectUsers.isFetchingNextPage) {\r\n projectUsers.fetchNextPage();\r\n } else if (availableUsers.hasNextPage && !availableUsers.isFetchingNextPage) {\r\n availableUsers.fetchNextPage();\r\n }\r\n };\r\n\r\n return (\r\n <Popover open={open} onOpenChange={setOpen}>\r\n <PopoverTrigger className=\"cursor-pointer\">\r\n <div className=\"flex items-center gap-2 text-gray-950 px-3 py-2 border border-gray-200 rounded-full hover:border-gray-950\">\r\n <span className=\"paragraph-small-semibold\">{totalInProject}</span>\r\n <User size={16} />\r\n </div>\r\n </PopoverTrigger>\r\n\r\n <PopoverContent\r\n className={cn(\r\n 'absolute right-[-88px] w-[273px] p-0 bg-white rounded-2xl shadow-md border border-gray-200',\r\n contentClassName\r\n )}\r\n side={side}\r\n align={align}\r\n sideOffset={8}\r\n >\r\n <div className=\"flex flex-col p-3 gap-2\">\r\n <div className=\"flex items-center justify-between\">\r\n <span className=\"paragraph-small-semibold\">Usuários</span>\r\n <div className=\"flex items-center gap-1.5\">\r\n <Button\r\n variant=\"secondary\"\r\n className=\"h-8 paragraph-small-semibold text-gray-950\"\r\n onClick={() => window.open(`${GAPPS_URL}/my-teams?createNew=true`, '_blank')}\r\n >\r\n <Plus size={16} />\r\n Adicionar\r\n </Button>\r\n <Tooltip>\r\n <TooltipTrigger asChild>\r\n <Button\r\n variant=\"secondary\"\r\n className=\"p-0 size-8\"\r\n onClick={() => window.open(`${GAPPS_URL}/my-teams`, '_blank')}\r\n >\r\n <Settings size={18} />\r\n </Button>\r\n </TooltipTrigger>\r\n <TooltipContent>Visualizar todos usuários</TooltipContent>\r\n </Tooltip>\r\n </div>\r\n </div>\r\n\r\n <Command shouldFilter={false} className=\"gap-2\" value=\"\">\r\n <CommandInput\r\n placeholder=\"Busque aqui\"\r\n value={searchInput}\r\n onValueChange={setSearchInput}\r\n />\r\n <CommandList\r\n className=\"custom-scrollbar paragraph-small-medium text-gray-600 h-[162px]\"\r\n onScroll={handleScroll}\r\n >\r\n {isLoading ? (\r\n <>\r\n <UserItemSkeleton />\r\n <UserItemSkeleton />\r\n <UserItemSkeleton />\r\n </>\r\n ) : allUsers.length === 0 ? (\r\n <div className=\"flex flex-col items-center justify-center gap-2 h-full text-gray-400 py-4\">\r\n <Users size={28} className=\"text-gray-300\" />\r\n <span className=\"paragraph-small-medium text-center text-gray-500\">\r\n Nenhum usuário neste projeto.\r\n <br />\r\n Adicione um usuário para começar.\r\n </span>\r\n </div>\r\n ) : (\r\n <>\r\n <CommandEmpty>Nenhum resultado encontrado.</CommandEmpty>\r\n {allUsers.map((user) => (\r\n <CommandItem\r\n key={user.id}\r\n value={user.name || String(user.id)}\r\n autoFocus={false}\r\n onPointerEnter={() => setHoveredId(user.id)}\r\n onPointerLeave={() => setHoveredId(null)}\r\n onFocus={() => setHoveredId(user.id)}\r\n onBlur={() => setHoveredId(null)}\r\n onSelect={() => toggleUser(user.id, user.checked, user.removable)}\r\n className={user.removable ? 'cursor-pointer' : 'cursor-default'}\r\n >\r\n <div className=\"flex items-center justify-between w-full\">\r\n <div className=\"flex items-center gap-2\">\r\n <Image\r\n alt=\"Avatar\"\r\n src={user.avatar}\r\n width={32}\r\n height={32}\r\n className=\"rounded-full\"\r\n />\r\n {user.name}\r\n </div>\r\n <Tooltip open={user.removable && hoveredId === user.id}>\r\n <TooltipTrigger\r\n onClick={(e) => e.stopPropagation()}\r\n onPointerDown={(e) => e.stopPropagation()}\r\n >\r\n <Checkbox\r\n checked={user.checked}\r\n disabled={!user.removable}\r\n onCheckedChange={() => toggleUser(user.id, user.checked, user.removable)}\r\n className={user.removable && hoveredId === user.id ? 'border-gray-950' : ''}\r\n />\r\n </TooltipTrigger>\r\n <TooltipContent>\r\n {user.checked ? 'Remover do projeto' : 'Adicionar ao projeto'}\r\n </TooltipContent>\r\n </Tooltip>\r\n </div>\r\n </CommandItem>\r\n ))}\r\n {isFetchingMore && (\r\n <>\r\n <UserItemSkeleton />\r\n <UserItemSkeleton />\r\n </>\r\n )}\r\n </>\r\n )}\r\n </CommandList>\r\n </Command>\r\n </div>\r\n </PopoverContent>\r\n </Popover>\r\n );\r\n}\r\n"],"mappings":"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","names":["id"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/components/layouts/UsersSelectorPopover.tsx"],"sourcesContent":["'use client';\r\n\r\n\"use client\"\r\n\r\nimport { useEffect, useState } from 'react';\r\nimport { Plus, Settings, User, Users } from 'lucide-react';\r\nimport { UserAvatar } from '../ui/data-display/UserAvatar';\r\nimport { useQueryClient, useMutation } from '@tanstack/react-query';\r\nimport { Popover, PopoverContent, PopoverTrigger } from '../ui/overlay/Popover';\r\nimport { Button } from '../ui/buttons/Button';\r\nimport { Command, CommandEmpty, CommandInput, CommandItem, CommandList } from '../ui/overlay/Command';\r\nimport { Checkbox } from '../ui/form/Checkbox';\r\nimport { Tooltip, TooltipContent, TooltipTrigger } from '../ui/overlay/Tooltip';\r\nimport { cn } from '../../infra/utils/clsx';\r\nimport { useListProjectUsers, LIST_PROJECT_USERS_BASE_KEY } from '../../modules/projects/hooks/list-project-users.hook';\r\nimport { useListAvailableUsers, LIST_AVAILABLE_USERS_BASE_KEY } from '../../modules/projects/hooks/list-available-users.hook';\r\nimport { addProjectUserAction } from '../../modules/projects/actions/add-project-user.action';\r\nimport { removeProjectUserAction } from '../../modules/projects/actions/remove-project-user.action';\r\n\r\n\r\nexport interface UsersSelectorPopoverProps {\r\n projectId?: number;\r\n side?: 'top' | 'bottom' | 'left' | 'right';\r\n align?: 'start' | 'center' | 'end';\r\n contentClassName?: string;\r\n}\r\n\r\nfunction UserItemSkeleton() {\r\n return (\r\n <div className=\"flex items-center justify-between px-2 py-1.5 gap-2\">\r\n <div className=\"flex items-center gap-2 flex-1\">\r\n <div className=\"skeleton size-8 rounded-full shrink-0\" />\r\n <div className=\"skeleton h-3.5 w-28 rounded\" />\r\n </div>\r\n <div className=\"skeleton size-4 rounded shrink-0\" />\r\n </div>\r\n );\r\n}\r\n\r\nconst GAPPS_URL = process.env.NEXT_PUBLIC_GREAT_APPS ?? '';\r\n\r\nexport function UsersSelectorPopover({\r\n projectId,\r\n side,\r\n align,\r\n contentClassName,\r\n}: UsersSelectorPopoverProps) {\r\n const queryClient = useQueryClient();\r\n const [open, setOpen] = useState(false);\r\n const [hoveredId, setHoveredId] = useState<number | null>(null);\r\n const [searchInput, setSearchInput] = useState('');\r\n const [search, setSearch] = useState('');\r\n\r\n const id = projectId ?? 0;\r\n\r\n useEffect(() => {\r\n const timer = setTimeout(() => setSearch(searchInput), 300);\r\n return () => clearTimeout(timer);\r\n }, [searchInput]);\r\n\r\n const projectUsers = useListProjectUsers(id, search);\r\n const availableUsers = useListAvailableUsers(id, search);\r\n\r\n const inProject = projectUsers.data?.pages.flatMap((p) => p.data) ?? [];\r\n const notInProject = availableUsers.data?.pages.flatMap((p) => p.data) ?? [];\r\n const isLoading = projectUsers.isLoading || availableUsers.isLoading;\r\n const isFetchingMore = projectUsers.isFetchingNextPage || availableUsers.isFetchingNextPage;\r\n const totalInProject = projectUsers.data?.pages[0]?.total ?? inProject.length;\r\n\r\n const invalidate = () => {\r\n queryClient.invalidateQueries({ queryKey: LIST_PROJECT_USERS_BASE_KEY(id) });\r\n queryClient.invalidateQueries({ queryKey: LIST_AVAILABLE_USERS_BASE_KEY(id) });\r\n };\r\n\r\n const addMutation = useMutation({\r\n mutationFn: (userId: number) => addProjectUserAction({ projectId: id, users: [userId] }),\r\n onSuccess: invalidate,\r\n });\r\n\r\n const removeMutation = useMutation({\r\n mutationFn: (userId: number) => removeProjectUserAction({ projectId: id, users: [userId] }),\r\n onSuccess: invalidate,\r\n });\r\n\r\n const allUsers = [\r\n ...inProject.map((u) => ({\r\n id: u.id_user,\r\n name: u.name,\r\n photo: u.photo ?? null,\r\n checked: true as const,\r\n removable: u.profile !== 'owner' && u.profile !== 'admin',\r\n })),\r\n ...notInProject.map((u) => ({\r\n id: u.id,\r\n name: u.name,\r\n photo: u.photo ?? null,\r\n checked: false as const,\r\n removable: true,\r\n })),\r\n ];\r\n\r\n const toggleUser = (id: number, checked: boolean, removable: boolean) => {\r\n if (checked) {\r\n if (!removable) return;\r\n removeMutation.mutate(id);\r\n } else {\r\n addMutation.mutate(id);\r\n }\r\n };\r\n\r\n const handleScroll = (e: React.UIEvent<HTMLDivElement>) => {\r\n const target = e.currentTarget;\r\n const nearBottom = target.scrollTop + target.clientHeight >= target.scrollHeight - 50;\r\n if (!nearBottom) return;\r\n if (projectUsers.hasNextPage && !projectUsers.isFetchingNextPage) {\r\n projectUsers.fetchNextPage();\r\n } else if (availableUsers.hasNextPage && !availableUsers.isFetchingNextPage) {\r\n availableUsers.fetchNextPage();\r\n }\r\n };\r\n\r\n return (\r\n <Popover open={open} onOpenChange={setOpen}>\r\n <PopoverTrigger className=\"cursor-pointer\">\r\n <div className=\"flex items-center gap-2 text-gray-950 px-3 py-2 border border-gray-200 rounded-full hover:border-gray-950\">\r\n <span className=\"paragraph-small-semibold\">{totalInProject}</span>\r\n <User size={16} />\r\n </div>\r\n </PopoverTrigger>\r\n\r\n <PopoverContent\r\n className={cn(\r\n 'absolute right-[-88px] w-[273px] p-0 bg-white rounded-2xl shadow-md border border-gray-200',\r\n contentClassName\r\n )}\r\n side={side}\r\n align={align}\r\n sideOffset={8}\r\n >\r\n <div className=\"flex flex-col p-3 gap-2\">\r\n <div className=\"flex items-center justify-between\">\r\n <span className=\"paragraph-small-semibold\">Usuários</span>\r\n <div className=\"flex items-center gap-1.5\">\r\n <Button\r\n variant=\"secondary\"\r\n className=\"h-8 paragraph-small-semibold text-gray-950\"\r\n onClick={() => window.open(`${GAPPS_URL}/my-teams?createNew=true`, '_blank')}\r\n >\r\n <Plus size={16} />\r\n Adicionar\r\n </Button>\r\n <Tooltip>\r\n <TooltipTrigger asChild>\r\n <Button\r\n variant=\"secondary\"\r\n className=\"p-0 size-8\"\r\n onClick={() => window.open(`${GAPPS_URL}/my-teams`, '_blank')}\r\n >\r\n <Settings size={18} />\r\n </Button>\r\n </TooltipTrigger>\r\n <TooltipContent className=\"z-[1002]\">Visualizar todos usuários</TooltipContent>\r\n </Tooltip>\r\n </div>\r\n </div>\r\n\r\n <Command shouldFilter={false} className=\"gap-2\" value=\"\">\r\n <CommandInput\r\n placeholder=\"Busque aqui\"\r\n value={searchInput}\r\n onValueChange={setSearchInput}\r\n />\r\n <CommandList\r\n className=\"custom-scrollbar paragraph-small-medium text-gray-600 h-[162px]\"\r\n onScroll={handleScroll}\r\n >\r\n {isLoading ? (\r\n <>\r\n <UserItemSkeleton />\r\n <UserItemSkeleton />\r\n <UserItemSkeleton />\r\n </>\r\n ) : allUsers.length === 0 ? (\r\n <div className=\"flex flex-col items-center justify-center gap-2 h-full text-gray-400 py-4\">\r\n <Users size={28} className=\"text-gray-300\" />\r\n <span className=\"paragraph-small-medium text-center text-gray-500\">\r\n Nenhum usuário neste projeto.\r\n <br />\r\n Adicione um usuário para começar.\r\n </span>\r\n </div>\r\n ) : (\r\n <>\r\n <CommandEmpty>Nenhum resultado encontrado.</CommandEmpty>\r\n {allUsers.map((user) => (\r\n <CommandItem\r\n key={user.id}\r\n value={user.name || String(user.id)}\r\n autoFocus={false}\r\n onPointerEnter={() => setHoveredId(user.id)}\r\n onPointerLeave={() => setHoveredId(null)}\r\n onFocus={() => setHoveredId(user.id)}\r\n onBlur={() => setHoveredId(null)}\r\n onSelect={() => toggleUser(user.id, user.checked, user.removable)}\r\n className={user.removable ? 'cursor-pointer' : 'cursor-default'}\r\n >\r\n <div className=\"flex items-center justify-between w-full\">\r\n <div className=\"flex items-center gap-2\">\r\n <UserAvatar\r\n photo={user.photo}\r\n name={user.name ?? undefined}\r\n size={32}\r\n />\r\n {user.name}\r\n </div>\r\n <Tooltip open={user.removable && hoveredId === user.id}>\r\n <TooltipTrigger\r\n onClick={(e) => e.stopPropagation()}\r\n onPointerDown={(e) => e.stopPropagation()}\r\n >\r\n <Checkbox\r\n checked={user.checked}\r\n disabled={!user.removable}\r\n onCheckedChange={() => toggleUser(user.id, user.checked, user.removable)}\r\n className={user.removable && hoveredId === user.id ? 'border-gray-950' : ''}\r\n />\r\n </TooltipTrigger>\r\n <TooltipContent className=\"z-[1002]\">\r\n {user.checked ? 'Remover do projeto' : 'Adicionar ao projeto'}\r\n </TooltipContent>\r\n </Tooltip>\r\n </div>\r\n </CommandItem>\r\n ))}\r\n {isFetchingMore && (\r\n <>\r\n <UserItemSkeleton />\r\n <UserItemSkeleton />\r\n </>\r\n )}\r\n </>\r\n )}\r\n </CommandList>\r\n </Command>\r\n </div>\r\n </PopoverContent>\r\n </Popover>\r\n );\r\n}\r\n"],"mappings":";AA8BM,SAmJU,UAlJR,KADF;AA1BN,SAAS,WAAW,gBAAgB;AACpC,SAAS,MAAM,UAAU,MAAM,aAAa;AAC5C,SAAS,kBAAkB;AAC3B,SAAS,gBAAgB,mBAAmB;AAC5C,SAAS,SAAS,gBAAgB,sBAAsB;AACxD,SAAS,cAAc;AACvB,SAAS,SAAS,cAAc,cAAc,aAAa,mBAAmB;AAC9E,SAAS,gBAAgB;AACzB,SAAS,SAAS,gBAAgB,sBAAsB;AACxD,SAAS,UAAU;AACnB,SAAS,qBAAqB,mCAAmC;AACjE,SAAS,uBAAuB,qCAAqC;AACrE,SAAS,4BAA4B;AACrC,SAAS,+BAA+B;AAUxC,SAAS,mBAAmB;AAC1B,SACE,qBAAC,SAAI,WAAU,uDACb;AAAA,yBAAC,SAAI,WAAU,kCACb;AAAA,0BAAC,SAAI,WAAU,yCAAwC;AAAA,MACvD,oBAAC,SAAI,WAAU,+BAA8B;AAAA,OAC/C;AAAA,IACA,oBAAC,SAAI,WAAU,oCAAmC;AAAA,KACpD;AAEJ;AAEA,MAAM,YAAY,QAAQ,IAAI,0BAA0B;AAEjD,SAAS,qBAAqB;AAAA,EACnC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA8B;AAC5B,QAAM,cAAc,eAAe;AACnC,QAAM,CAAC,MAAM,OAAO,IAAI,SAAS,KAAK;AACtC,QAAM,CAAC,WAAW,YAAY,IAAI,SAAwB,IAAI;AAC9D,QAAM,CAAC,aAAa,cAAc,IAAI,SAAS,EAAE;AACjD,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAS,EAAE;AAEvC,QAAM,KAAK,aAAa;AAExB,YAAU,MAAM;AACd,UAAM,QAAQ,WAAW,MAAM,UAAU,WAAW,GAAG,GAAG;AAC1D,WAAO,MAAM,aAAa,KAAK;AAAA,EACjC,GAAG,CAAC,WAAW,CAAC;AAEhB,QAAM,eAAe,oBAAoB,IAAI,MAAM;AACnD,QAAM,iBAAiB,sBAAsB,IAAI,MAAM;AAEvD,QAAM,YAAY,aAAa,MAAM,MAAM,QAAQ,CAAC,MAAM,EAAE,IAAI,KAAK,CAAC;AACtE,QAAM,eAAe,eAAe,MAAM,MAAM,QAAQ,CAAC,MAAM,EAAE,IAAI,KAAK,CAAC;AAC3E,QAAM,YAAY,aAAa,aAAa,eAAe;AAC3D,QAAM,iBAAiB,aAAa,sBAAsB,eAAe;AACzE,QAAM,iBAAiB,aAAa,MAAM,MAAM,CAAC,GAAG,SAAS,UAAU;AAEvE,QAAM,aAAa,MAAM;AACvB,gBAAY,kBAAkB,EAAE,UAAU,4BAA4B,EAAE,EAAE,CAAC;AAC3E,gBAAY,kBAAkB,EAAE,UAAU,8BAA8B,EAAE,EAAE,CAAC;AAAA,EAC/E;AAEA,QAAM,cAAc,YAAY;AAAA,IAC9B,YAAY,CAAC,WAAmB,qBAAqB,EAAE,WAAW,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;AAAA,IACvF,WAAW;AAAA,EACb,CAAC;AAED,QAAM,iBAAiB,YAAY;AAAA,IACjC,YAAY,CAAC,WAAmB,wBAAwB,EAAE,WAAW,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;AAAA,IAC1F,WAAW;AAAA,EACb,CAAC;AAED,QAAM,WAAW;AAAA,IACf,GAAG,UAAU,IAAI,CAAC,OAAO;AAAA,MACvB,IAAI,EAAE;AAAA,MACN,MAAM,EAAE;AAAA,MACR,OAAO,EAAE,SAAS;AAAA,MAClB,SAAS;AAAA,MACT,WAAW,EAAE,YAAY,WAAW,EAAE,YAAY;AAAA,IACpD,EAAE;AAAA,IACF,GAAG,aAAa,IAAI,CAAC,OAAO;AAAA,MAC1B,IAAI,EAAE;AAAA,MACN,MAAM,EAAE;AAAA,MACR,OAAO,EAAE,SAAS;AAAA,MAClB,SAAS;AAAA,MACT,WAAW;AAAA,IACb,EAAE;AAAA,EACJ;AAEA,QAAM,aAAa,CAACA,KAAY,SAAkB,cAAuB;AACvE,QAAI,SAAS;AACX,UAAI,CAAC,UAAW;AAChB,qBAAe,OAAOA,GAAE;AAAA,IAC1B,OAAO;AACL,kBAAY,OAAOA,GAAE;AAAA,IACvB;AAAA,EACF;AAEA,QAAM,eAAe,CAAC,MAAqC;AACzD,UAAM,SAAS,EAAE;AACjB,UAAM,aAAa,OAAO,YAAY,OAAO,gBAAgB,OAAO,eAAe;AACnF,QAAI,CAAC,WAAY;AACjB,QAAI,aAAa,eAAe,CAAC,aAAa,oBAAoB;AAChE,mBAAa,cAAc;AAAA,IAC7B,WAAW,eAAe,eAAe,CAAC,eAAe,oBAAoB;AAC3E,qBAAe,cAAc;AAAA,IAC/B;AAAA,EACF;AAEA,SACE,qBAAC,WAAQ,MAAY,cAAc,SACjC;AAAA,wBAAC,kBAAe,WAAU,kBACxB,+BAAC,SAAI,WAAU,6GACb;AAAA,0BAAC,UAAK,WAAU,4BAA4B,0BAAe;AAAA,MAC3D,oBAAC,QAAK,MAAM,IAAI;AAAA,OAClB,GACF;AAAA,IAEA;AAAA,MAAC;AAAA;AAAA,QACC,WAAW;AAAA,UACT;AAAA,UACA;AAAA,QACF;AAAA,QACA;AAAA,QACA;AAAA,QACA,YAAY;AAAA,QAEZ,+BAAC,SAAI,WAAU,2BACb;AAAA,+BAAC,SAAI,WAAU,qCACb;AAAA,gCAAC,UAAK,WAAU,4BAA2B,yBAAQ;AAAA,YACnD,qBAAC,SAAI,WAAU,6BACb;AAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,SAAQ;AAAA,kBACR,WAAU;AAAA,kBACV,SAAS,MAAM,OAAO,KAAK,GAAG,SAAS,4BAA4B,QAAQ;AAAA,kBAE3E;AAAA,wCAAC,QAAK,MAAM,IAAI;AAAA,oBAAE;AAAA;AAAA;AAAA,cAEpB;AAAA,cACA,qBAAC,WACC;AAAA,oCAAC,kBAAe,SAAO,MACrB;AAAA,kBAAC;AAAA;AAAA,oBACC,SAAQ;AAAA,oBACR,WAAU;AAAA,oBACV,SAAS,MAAM,OAAO,KAAK,GAAG,SAAS,aAAa,QAAQ;AAAA,oBAE5D,8BAAC,YAAS,MAAM,IAAI;AAAA;AAAA,gBACtB,GACF;AAAA,gBACA,oBAAC,kBAAe,WAAU,YAAW,0CAAyB;AAAA,iBAChE;AAAA,eACF;AAAA,aACF;AAAA,UAEA,qBAAC,WAAQ,cAAc,OAAO,WAAU,SAAQ,OAAM,IACpD;AAAA;AAAA,cAAC;AAAA;AAAA,gBACC,aAAY;AAAA,gBACZ,OAAO;AAAA,gBACP,eAAe;AAAA;AAAA,YACjB;AAAA,YACA;AAAA,cAAC;AAAA;AAAA,gBACC,WAAU;AAAA,gBACV,UAAU;AAAA,gBAET,sBACC,iCACE;AAAA,sCAAC,oBAAiB;AAAA,kBAClB,oBAAC,oBAAiB;AAAA,kBAClB,oBAAC,oBAAiB;AAAA,mBACpB,IACE,SAAS,WAAW,IACtB,qBAAC,SAAI,WAAU,6EACb;AAAA,sCAAC,SAAM,MAAM,IAAI,WAAU,iBAAgB;AAAA,kBAC3C,qBAAC,UAAK,WAAU,oDAAmD;AAAA;AAAA,oBAEjE,oBAAC,QAAG;AAAA,oBAAE;AAAA,qBAER;AAAA,mBACF,IAEA,iCACE;AAAA,sCAAC,gBAAa,0CAA4B;AAAA,kBACzC,SAAS,IAAI,CAAC,SACb;AAAA,oBAAC;AAAA;AAAA,sBAEC,OAAO,KAAK,QAAQ,OAAO,KAAK,EAAE;AAAA,sBAClC,WAAW;AAAA,sBACX,gBAAgB,MAAM,aAAa,KAAK,EAAE;AAAA,sBAC1C,gBAAgB,MAAM,aAAa,IAAI;AAAA,sBACvC,SAAS,MAAM,aAAa,KAAK,EAAE;AAAA,sBACnC,QAAQ,MAAM,aAAa,IAAI;AAAA,sBAC/B,UAAU,MAAM,WAAW,KAAK,IAAI,KAAK,SAAS,KAAK,SAAS;AAAA,sBAChE,WAAW,KAAK,YAAY,mBAAmB;AAAA,sBAE/C,+BAAC,SAAI,WAAU,4CACb;AAAA,6CAAC,SAAI,WAAU,2BACb;AAAA;AAAA,4BAAC;AAAA;AAAA,8BACC,OAAO,KAAK;AAAA,8BACZ,MAAM,KAAK,QAAQ;AAAA,8BACnB,MAAM;AAAA;AAAA,0BACR;AAAA,0BACC,KAAK;AAAA,2BACR;AAAA,wBACA,qBAAC,WAAQ,MAAM,KAAK,aAAa,cAAc,KAAK,IAClD;AAAA;AAAA,4BAAC;AAAA;AAAA,8BACC,SAAS,CAAC,MAAM,EAAE,gBAAgB;AAAA,8BAClC,eAAe,CAAC,MAAM,EAAE,gBAAgB;AAAA,8BAExC;AAAA,gCAAC;AAAA;AAAA,kCACC,SAAS,KAAK;AAAA,kCACd,UAAU,CAAC,KAAK;AAAA,kCAChB,iBAAiB,MAAM,WAAW,KAAK,IAAI,KAAK,SAAS,KAAK,SAAS;AAAA,kCACvE,WAAW,KAAK,aAAa,cAAc,KAAK,KAAK,oBAAoB;AAAA;AAAA,8BAC3E;AAAA;AAAA,0BACF;AAAA,0BACA,oBAAC,kBAAe,WAAU,YACvB,eAAK,UAAU,uBAAuB,wBACzC;AAAA,2BACF;AAAA,yBACF;AAAA;AAAA,oBAnCK,KAAK;AAAA,kBAoCZ,CACD;AAAA,kBACA,kBACC,iCACE;AAAA,wCAAC,oBAAiB;AAAA,oBAClB,oBAAC,oBAAiB;AAAA,qBACpB;AAAA,mBAEJ;AAAA;AAAA,YAEJ;AAAA,aACF;AAAA,WACF;AAAA;AAAA,IACF;AAAA,KACF;AAEJ;","names":["id"]}
|
|
@@ -10,7 +10,7 @@ import { ProjectSelector } from "./subcomponents/ProjectSelector";
|
|
|
10
10
|
import { PlanCard } from "./subcomponents/PlanCard";
|
|
11
11
|
import { CreditsCard } from "./subcomponents/CreditsCard";
|
|
12
12
|
import { NavItemsContext } from "./NavItemsContext";
|
|
13
|
-
function AppNavigationRoot({ children, mobileVariant = "sheet", mobileTabsOffset }) {
|
|
13
|
+
function AppNavigationRoot({ children, mobileVariant = "sheet", mobileTabsOffset, onCancelledReactivate }) {
|
|
14
14
|
const [navItems, setNavItems] = useState([]);
|
|
15
15
|
return /* @__PURE__ */ jsxs(NavItemsContext.Provider, { value: { navItems, setNavItems, mobileVariant }, children: [
|
|
16
16
|
/* @__PURE__ */ jsx(DesktopShell, { children }),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/navigation/AppNavigation.tsx"],"sourcesContent":["'use client';\r\n\r\nimport { ReactNode, useState } from 'react';\r\nimport { DesktopShell } from './shells/DesktopShell';\r\nimport { MdShell } from './shells/MdShell';\r\nimport { MobileShell } from './shells/MobileShell';\r\nimport { TabsMobileShell } from './shells/TabsMobileShell';\r\nimport { NavItems } from './subcomponents/NavItems';\r\nimport { ProjectSelector } from './subcomponents/ProjectSelector';\r\nimport { PlanCard } from './subcomponents/PlanCard';\r\nimport { CreditsCard } from './subcomponents/CreditsCard';\r\nimport { NavItemsContext } from './NavItemsContext';\r\nimport type { NavItemConfig } from './subcomponents/NavItems';\r\n\r\nexport type { NavItemConfig } from './subcomponents/NavItems';\r\nexport type { ProjectSelectorProps } from './subcomponents/ProjectSelector';\r\nexport type { PlanCardProps } from './subcomponents/PlanCard';\r\nexport type { CreditsCardProps } from './subcomponents/CreditsCard';\r\n\r\ninterface AppNavigationProps {\r\n children: ReactNode;\r\n mobileVariant?: 'sheet' | 'tabs';\r\n mobileTabsOffset?: string;\r\n}\r\n\r\nfunction AppNavigationRoot({ children, mobileVariant = 'sheet', mobileTabsOffset }: AppNavigationProps) {\r\n const [navItems, setNavItems] = useState<NavItemConfig[]>([]);\r\n\r\n return (\r\n <NavItemsContext.Provider value={{ navItems, setNavItems, mobileVariant }}>\r\n <DesktopShell>{children}</DesktopShell>\r\n <MdShell>{children}</MdShell>\r\n {mobileVariant === 'sheet' ? (\r\n <MobileShell>{children}</MobileShell>\r\n ) : (\r\n <TabsMobileShell topOffset={mobileTabsOffset}>{children}</TabsMobileShell>\r\n )}\r\n </NavItemsContext.Provider>\r\n );\r\n}\r\n\r\nexport const AppNavigation = Object.assign(AppNavigationRoot, {\r\n NavItems,\r\n ProjectSelector,\r\n PlanCard,\r\n CreditsCard,\r\n});\r\n"],"mappings":";
|
|
1
|
+
{"version":3,"sources":["../../../src/components/navigation/AppNavigation.tsx"],"sourcesContent":["'use client';\r\n\r\nimport { ReactNode, useState } from 'react';\r\nimport { DesktopShell } from './shells/DesktopShell';\r\nimport { MdShell } from './shells/MdShell';\r\nimport { MobileShell } from './shells/MobileShell';\r\nimport { TabsMobileShell } from './shells/TabsMobileShell';\r\nimport { NavItems } from './subcomponents/NavItems';\r\nimport { ProjectSelector } from './subcomponents/ProjectSelector';\r\nimport { PlanCard } from './subcomponents/PlanCard';\r\nimport { CreditsCard } from './subcomponents/CreditsCard';\r\nimport { NavItemsContext } from './NavItemsContext';\r\nimport type { NavItemConfig } from './subcomponents/NavItems';\r\n\r\nexport type { NavItemConfig } from './subcomponents/NavItems';\r\nexport type { ProjectSelectorProps } from './subcomponents/ProjectSelector';\r\nexport type { PlanCardProps } from './subcomponents/PlanCard';\r\nexport type { CreditsCardProps } from './subcomponents/CreditsCard';\r\n\r\ninterface AppNavigationProps {\r\n children: ReactNode;\r\n mobileVariant?: 'sheet' | 'tabs';\r\n mobileTabsOffset?: string;\r\n onCancelledReactivate?: () => void;\r\n}\r\n\r\nfunction AppNavigationRoot({ children, mobileVariant = 'sheet', mobileTabsOffset, onCancelledReactivate }: AppNavigationProps) {\r\n const [navItems, setNavItems] = useState<NavItemConfig[]>([]);\r\n\r\n return (\r\n <NavItemsContext.Provider value={{ navItems, setNavItems, mobileVariant }}>\r\n <DesktopShell>{children}</DesktopShell>\r\n <MdShell>{children}</MdShell>\r\n {mobileVariant === 'sheet' ? (\r\n <MobileShell>{children}</MobileShell>\r\n ) : (\r\n <TabsMobileShell topOffset={mobileTabsOffset}>{children}</TabsMobileShell>\r\n )}\r\n </NavItemsContext.Provider>\r\n );\r\n}\r\n\r\nexport const AppNavigation = Object.assign(AppNavigationRoot, {\r\n NavItems,\r\n ProjectSelector,\r\n PlanCard,\r\n CreditsCard,\r\n});\r\n"],"mappings":";AA8BI,SACE,KADF;AA5BJ,SAAoB,gBAAgB;AACpC,SAAS,oBAAoB;AAC7B,SAAS,eAAe;AACxB,SAAS,mBAAmB;AAC5B,SAAS,uBAAuB;AAChC,SAAS,gBAAgB;AACzB,SAAS,uBAAuB;AAChC,SAAS,gBAAgB;AACzB,SAAS,mBAAmB;AAC5B,SAAS,uBAAuB;AAehC,SAAS,kBAAkB,EAAE,UAAU,gBAAgB,SAAS,kBAAkB,sBAAsB,GAAuB;AAC7H,QAAM,CAAC,UAAU,WAAW,IAAI,SAA0B,CAAC,CAAC;AAE5D,SACE,qBAAC,gBAAgB,UAAhB,EAAyB,OAAO,EAAE,UAAU,aAAa,cAAc,GACtE;AAAA,wBAAC,gBAAc,UAAS;AAAA,IACxB,oBAAC,WAAS,UAAS;AAAA,IAClB,kBAAkB,UACjB,oBAAC,eAAa,UAAS,IAEvB,oBAAC,mBAAgB,WAAW,kBAAmB,UAAS;AAAA,KAE5D;AAEJ;AAEO,MAAM,gBAAgB,OAAO,OAAO,mBAAmB;AAAA,EAC5D;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;","names":[]}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useState, useEffect, useCallback } from "react";
|
|
4
|
+
import { IconAlertOctagon, IconX } from "@tabler/icons-react";
|
|
5
|
+
import { useActiveSubscription } from "../../modules/subscriptions/hooks/find-active-subscription.hook";
|
|
6
|
+
function daysBetween(a, b) {
|
|
7
|
+
const msPerDay = 24 * 60 * 60 * 1e3;
|
|
8
|
+
const da = new Date(a.getFullYear(), a.getMonth(), a.getDate());
|
|
9
|
+
const db = new Date(b.getFullYear(), b.getMonth(), b.getDate());
|
|
10
|
+
return Math.round((db.getTime() - da.getTime()) / msPerDay);
|
|
11
|
+
}
|
|
12
|
+
function CancelledSubscriptionBanner({ onReactivate }) {
|
|
13
|
+
const { data: { data: [subscription] = [] } = {} } = useActiveSubscription();
|
|
14
|
+
const [visible, setVisible] = useState(true);
|
|
15
|
+
const [animated, setAnimated] = useState(false);
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
const timer = setTimeout(() => setAnimated(true), 50);
|
|
18
|
+
return () => clearTimeout(timer);
|
|
19
|
+
}, []);
|
|
20
|
+
const dismiss = useCallback(() => setVisible(false), []);
|
|
21
|
+
const cancellationDate = subscription?.date_cancellation;
|
|
22
|
+
if (!cancellationDate || !visible) return null;
|
|
23
|
+
const today = /* @__PURE__ */ new Date();
|
|
24
|
+
const daysSinceCancellation = daysBetween(new Date(cancellationDate), today);
|
|
25
|
+
if (daysSinceCancellation < 0 || daysSinceCancellation > 5) return null;
|
|
26
|
+
const daysRemaining = Math.max(0, 5 - daysSinceCancellation);
|
|
27
|
+
return /* @__PURE__ */ jsx("div", { className: "fixed top-[80px] md:top-0 lg:left-[273px] left-0 right-0 z-[60] flex justify-center pointer-events-none px-4 lg:px-0", children: /* @__PURE__ */ jsxs(
|
|
28
|
+
"div",
|
|
29
|
+
{
|
|
30
|
+
className: `flex flex-col sm:flex-row items-start sm:items-center justify-between bg-red-500 rounded-lg px-3 py-2 sm:py-1 w-full lg:w-[805px] max-w-full pointer-events-auto transition-transform duration-500 ease-out gap-2 sm:gap-0 ${animated ? "translate-y-0 md:translate-y-9" : "-translate-y-full"}`,
|
|
31
|
+
children: [
|
|
32
|
+
daysRemaining > 0 && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 flex-1 w-full sm:w-auto", children: [
|
|
33
|
+
/* @__PURE__ */ jsx(IconAlertOctagon, { size: 16, className: "text-white shrink-0" }),
|
|
34
|
+
/* @__PURE__ */ jsxs("span", { className: "paragraph-xsmall-semibold text-white", children: [
|
|
35
|
+
"Assinatura cancelada! Em ",
|
|
36
|
+
daysRemaining,
|
|
37
|
+
" dias suas p\xE1ginas ser\xE3o tiradas do ar!"
|
|
38
|
+
] })
|
|
39
|
+
] }),
|
|
40
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 w-full sm:w-auto justify-between sm:justify-start", children: [
|
|
41
|
+
/* @__PURE__ */ jsx(
|
|
42
|
+
"button",
|
|
43
|
+
{
|
|
44
|
+
type: "button",
|
|
45
|
+
className: "flex items-center justify-center p-1.5 cursor-pointer",
|
|
46
|
+
onClick: onReactivate,
|
|
47
|
+
children: /* @__PURE__ */ jsx("span", { className: "paragraph-xsmall-semibold text-white underline", children: "Reativar assinatura" })
|
|
48
|
+
}
|
|
49
|
+
),
|
|
50
|
+
/* @__PURE__ */ jsx("button", { type: "button", className: "cursor-pointer shrink-0", onClick: dismiss, children: /* @__PURE__ */ jsx(IconX, { size: 18, className: "text-red-200" }) })
|
|
51
|
+
] })
|
|
52
|
+
]
|
|
53
|
+
}
|
|
54
|
+
) });
|
|
55
|
+
}
|
|
56
|
+
export {
|
|
57
|
+
CancelledSubscriptionBanner
|
|
58
|
+
};
|
|
59
|
+
//# sourceMappingURL=CancelledSubscriptionBanner.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/navigation/CancelledSubscriptionBanner.tsx"],"sourcesContent":["'use client';\n\nimport { useState, useEffect, useCallback } from 'react';\nimport { IconAlertOctagon, IconX } from '@tabler/icons-react';\nimport { useActiveSubscription } from '../../modules/subscriptions/hooks/find-active-subscription.hook';\n\nfunction daysBetween(a: Date, b: Date): number {\n const msPerDay = 24 * 60 * 60 * 1000;\n const da = new Date(a.getFullYear(), a.getMonth(), a.getDate());\n const db = new Date(b.getFullYear(), b.getMonth(), b.getDate());\n return Math.round((db.getTime() - da.getTime()) / msPerDay);\n}\n\ninterface CancelledSubscriptionBannerProps {\n onReactivate?: () => void;\n}\n\nexport function CancelledSubscriptionBanner({ onReactivate }: CancelledSubscriptionBannerProps) {\n const { data: { data: [subscription] = [] } = {} } = useActiveSubscription();\n const [visible, setVisible] = useState(true);\n const [animated, setAnimated] = useState(false);\n\n useEffect(() => {\n const timer = setTimeout(() => setAnimated(true), 50);\n return () => clearTimeout(timer);\n }, []);\n\n const dismiss = useCallback(() => setVisible(false), []);\n\n const cancellationDate = subscription?.date_cancellation;\n if (!cancellationDate || !visible) return null;\n\n const today = new Date();\n const daysSinceCancellation = daysBetween(new Date(cancellationDate), today);\n if (daysSinceCancellation < 0 || daysSinceCancellation > 5) return null;\n\n const daysRemaining = Math.max(0, 5 - daysSinceCancellation);\n\n return (\n <div className=\"fixed top-[80px] md:top-0 lg:left-[273px] left-0 right-0 z-[60] flex justify-center pointer-events-none px-4 lg:px-0\">\n <div\n className={`flex flex-col sm:flex-row items-start sm:items-center justify-between bg-red-500 rounded-lg px-3 py-2 sm:py-1 w-full lg:w-[805px] max-w-full pointer-events-auto transition-transform duration-500 ease-out gap-2 sm:gap-0 ${animated ? 'translate-y-0 md:translate-y-9' : '-translate-y-full'}`}\n >\n {daysRemaining > 0 && (\n <div className=\"flex items-center gap-2 flex-1 w-full sm:w-auto\">\n <IconAlertOctagon size={16} className=\"text-white shrink-0\" />\n <span className=\"paragraph-xsmall-semibold text-white\">\n Assinatura cancelada! Em {daysRemaining} dias suas páginas serão tiradas do ar!\n </span>\n </div>\n )}\n <div className=\"flex items-center gap-1.5 w-full sm:w-auto justify-between sm:justify-start\">\n <button\n type=\"button\"\n className=\"flex items-center justify-center p-1.5 cursor-pointer\"\n onClick={onReactivate}\n >\n <span className=\"paragraph-xsmall-semibold text-white underline\">\n Reativar assinatura\n </span>\n </button>\n <button type=\"button\" className=\"cursor-pointer shrink-0\" onClick={dismiss}>\n <IconX size={18} className=\"text-red-200\" />\n </button>\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":";AA6CY,cACA,YADA;AA3CZ,SAAS,UAAU,WAAW,mBAAmB;AACjD,SAAS,kBAAkB,aAAa;AACxC,SAAS,6BAA6B;AAEtC,SAAS,YAAY,GAAS,GAAiB;AAC7C,QAAM,WAAW,KAAK,KAAK,KAAK;AAChC,QAAM,KAAK,IAAI,KAAK,EAAE,YAAY,GAAG,EAAE,SAAS,GAAG,EAAE,QAAQ,CAAC;AAC9D,QAAM,KAAK,IAAI,KAAK,EAAE,YAAY,GAAG,EAAE,SAAS,GAAG,EAAE,QAAQ,CAAC;AAC9D,SAAO,KAAK,OAAO,GAAG,QAAQ,IAAI,GAAG,QAAQ,KAAK,QAAQ;AAC5D;AAMO,SAAS,4BAA4B,EAAE,aAAa,GAAqC;AAC9F,QAAM,EAAE,MAAM,EAAE,MAAM,CAAC,YAAY,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,IAAI,sBAAsB;AAC3E,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,IAAI;AAC3C,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,KAAK;AAE9C,YAAU,MAAM;AACd,UAAM,QAAQ,WAAW,MAAM,YAAY,IAAI,GAAG,EAAE;AACpD,WAAO,MAAM,aAAa,KAAK;AAAA,EACjC,GAAG,CAAC,CAAC;AAEL,QAAM,UAAU,YAAY,MAAM,WAAW,KAAK,GAAG,CAAC,CAAC;AAEvD,QAAM,mBAAmB,cAAc;AACvC,MAAI,CAAC,oBAAoB,CAAC,QAAS,QAAO;AAE1C,QAAM,QAAQ,oBAAI,KAAK;AACvB,QAAM,wBAAwB,YAAY,IAAI,KAAK,gBAAgB,GAAG,KAAK;AAC3E,MAAI,wBAAwB,KAAK,wBAAwB,EAAG,QAAO;AAEnE,QAAM,gBAAgB,KAAK,IAAI,GAAG,IAAI,qBAAqB;AAE3D,SACE,oBAAC,SAAI,WAAU,wHACb;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,8NAA8N,WAAW,mCAAmC,mBAAmB;AAAA,MAEzS;AAAA,wBAAgB,KACf,qBAAC,SAAI,WAAU,mDACb;AAAA,8BAAC,oBAAiB,MAAM,IAAI,WAAU,uBAAsB;AAAA,UAC5D,qBAAC,UAAK,WAAU,wCAAuC;AAAA;AAAA,YAC3B;AAAA,YAAc;AAAA,aAC1C;AAAA,WACF;AAAA,QAEF,qBAAC,SAAI,WAAU,+EACb;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,WAAU;AAAA,cACV,SAAS;AAAA,cAET,8BAAC,UAAK,WAAU,kDAAiD,iCAEjE;AAAA;AAAA,UACF;AAAA,UACA,oBAAC,YAAO,MAAK,UAAS,WAAU,2BAA0B,SAAS,SACjE,8BAAC,SAAM,MAAM,IAAI,WAAU,gBAAe,GAC5C;AAAA,WACF;AAAA;AAAA;AAAA,EACF,GACF;AAEJ;","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/navigation/NavItemsContext.ts"],"sourcesContent":["'use client';\
|
|
1
|
+
{"version":3,"sources":["../../../src/components/navigation/NavItemsContext.ts"],"sourcesContent":["'use client';\n\nimport { createContext, useContext } from 'react';\nimport type { NavItemConfig } from './subcomponents/NavItems';\n\ninterface NavItemsContextValue {\n navItems: NavItemConfig[];\n setNavItems: (items: NavItemConfig[]) => void;\n mobileVariant: 'sheet' | 'tabs';\n}\n\nexport const NavItemsContext = createContext<NavItemsContextValue>({\n navItems: [],\n setNavItems: () => {},\n mobileVariant: 'sheet',\n});\n\nexport function useNavItemsContext(): NavItemsContextValue {\n return useContext(NavItemsContext);\n}\n"],"mappings":";AAEA,SAAS,eAAe,kBAAkB;AASnC,MAAM,kBAAkB,cAAoC;AAAA,EACjE,UAAU,CAAC;AAAA,EACX,aAAa,MAAM;AAAA,EAAC;AAAA,EACpB,eAAe;AACjB,CAAC;AAEM,SAAS,qBAA2C;AACzD,SAAO,WAAW,eAAe;AACnC;","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/components/navigation/shells/TabsMobileShell.tsx"],"sourcesContent":["'use client';\
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/navigation/shells/TabsMobileShell.tsx"],"sourcesContent":["'use client';\n\nimport { ReactNode, useRef, useEffect } from 'react';\nimport { AppNavigationContext } from '../AppNavigationContext';\nimport { useNavItemsContext } from '../NavItemsContext';\n\nfunction InternalTabsBar({ topOffset = '72px' }: { topOffset?: string }) {\n const { navItems } = useNavItemsContext();\n const tabsListRef = useRef<HTMLDivElement>(null);\n const activeTabRef = useRef<HTMLButtonElement>(null);\n\n const activeLabel = navItems.find((i) => i.isActive)?.label;\n\n // Scroll active tab into center when active item changes\n useEffect(() => {\n if (activeTabRef.current && tabsListRef.current) {\n const tabsList = tabsListRef.current;\n const activeTabElement = activeTabRef.current;\n const tabsListRect = tabsList.getBoundingClientRect();\n const activeTabRect = activeTabElement.getBoundingClientRect();\n const scrollLeft =\n activeTabElement.offsetLeft - tabsListRect.width / 2 + activeTabRect.width / 2;\n tabsList.scrollTo({ left: Math.max(0, scrollLeft), behavior: 'smooth' });\n }\n }, [activeLabel]);\n\n if (!navItems.length) return null;\n\n return (\n <div\n ref={tabsListRef}\n className=\"md:hidden fixed left-0 right-0 z-40 bg-white border-b border-gray-200 flex overflow-x-auto scrollbar-hide\"\n style={{ top: topOffset }}\n >\n {navItems.map((item) => (\n <button\n key={item.label}\n ref={item.isActive ? activeTabRef : undefined}\n onClick={item.onClick}\n className={`flex items-center gap-2 px-4 py-3 shrink-0 border-b-2 transition-colors ${\n item.isActive\n ? 'border-gray-950 text-gray-950'\n : 'border-transparent text-gray-500 hover:text-gray-900'\n }`}\n >\n {item.icon && <item.icon size={16} className=\"shrink-0\" />}\n <span\n className={\n item.isActive ? 'paragraph-small-semibold' : 'paragraph-small-medium'\n }\n >\n {item.label}\n </span>\n </button>\n ))}\n </div>\n );\n}\n\nexport function TabsMobileShell({ children, topOffset }: { children: ReactNode; topOffset?: string }) {\n return (\n <AppNavigationContext.Provider value={{ breakpoint: 'mobile' }}>\n {/*\n Children are hidden visually, but NavItems' useEffect still fires inside\n display:none — React effects are tied to commit phase, not layout visibility.\n This registers navItems in NavItemsContext so InternalTabsBar can read them.\n */}\n <div className=\"hidden\">{children}</div>\n <InternalTabsBar topOffset={topOffset} />\n </AppNavigationContext.Provider>\n );\n}\n"],"mappings":";AAmCQ,SAUgB,KAVhB;AAjCR,SAAoB,QAAQ,iBAAiB;AAC7C,SAAS,4BAA4B;AACrC,SAAS,0BAA0B;AAEnC,SAAS,gBAAgB,EAAE,YAAY,OAAO,GAA2B;AACvE,QAAM,EAAE,SAAS,IAAI,mBAAmB;AACxC,QAAM,cAAc,OAAuB,IAAI;AAC/C,QAAM,eAAe,OAA0B,IAAI;AAEnD,QAAM,cAAc,SAAS,KAAK,CAAC,MAAM,EAAE,QAAQ,GAAG;AAGtD,YAAU,MAAM;AACd,QAAI,aAAa,WAAW,YAAY,SAAS;AAC/C,YAAM,WAAW,YAAY;AAC7B,YAAM,mBAAmB,aAAa;AACtC,YAAM,eAAe,SAAS,sBAAsB;AACpD,YAAM,gBAAgB,iBAAiB,sBAAsB;AAC7D,YAAM,aACJ,iBAAiB,aAAa,aAAa,QAAQ,IAAI,cAAc,QAAQ;AAC/E,eAAS,SAAS,EAAE,MAAM,KAAK,IAAI,GAAG,UAAU,GAAG,UAAU,SAAS,CAAC;AAAA,IACzE;AAAA,EACF,GAAG,CAAC,WAAW,CAAC;AAEhB,MAAI,CAAC,SAAS,OAAQ,QAAO;AAE7B,SACE;AAAA,IAAC;AAAA;AAAA,MACC,KAAK;AAAA,MACL,WAAU;AAAA,MACV,OAAO,EAAE,KAAK,UAAU;AAAA,MAEvB,mBAAS,IAAI,CAAC,SACb;AAAA,QAAC;AAAA;AAAA,UAEC,KAAK,KAAK,WAAW,eAAe;AAAA,UACpC,SAAS,KAAK;AAAA,UACd,WAAW,2EACT,KAAK,WACD,kCACA,sDACN;AAAA,UAEC;AAAA,iBAAK,QAAQ,oBAAC,KAAK,MAAL,EAAU,MAAM,IAAI,WAAU,YAAW;AAAA,YACxD;AAAA,cAAC;AAAA;AAAA,gBACC,WACE,KAAK,WAAW,6BAA6B;AAAA,gBAG9C,eAAK;AAAA;AAAA,YACR;AAAA;AAAA;AAAA,QAhBK,KAAK;AAAA,MAiBZ,CACD;AAAA;AAAA,EACH;AAEJ;AAEO,SAAS,gBAAgB,EAAE,UAAU,UAAU,GAAgD;AACpG,SACE,qBAAC,qBAAqB,UAArB,EAA8B,OAAO,EAAE,YAAY,SAAS,GAM3D;AAAA,wBAAC,SAAI,WAAU,UAAU,UAAS;AAAA,IAClC,oBAAC,mBAAgB,WAAsB;AAAA,KACzC;AAEJ;","names":[]}
|