@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.
Files changed (167) hide show
  1. package/dist/components/account/ConfirmDeleteAccountModal.mjs.map +1 -1
  2. package/dist/components/account/DeleteAccountModal.mjs.map +1 -1
  3. package/dist/components/account/IsntPossibleDeleteAccountModal.mjs.map +1 -1
  4. package/dist/components/account/hooks/useTwoFactorAuthForm.mjs.map +1 -1
  5. package/dist/components/layouts/AppMobileNavBar.mjs.map +1 -1
  6. package/dist/components/layouts/AppNavBar.mjs.map +1 -1
  7. package/dist/components/layouts/NavBar.mjs +29 -1
  8. package/dist/components/layouts/NavBar.mjs.map +1 -1
  9. package/dist/components/layouts/UsersSelectorPopover.mjs +9 -12
  10. package/dist/components/layouts/UsersSelectorPopover.mjs.map +1 -1
  11. package/dist/components/navigation/AppNavigation.mjs +1 -1
  12. package/dist/components/navigation/AppNavigation.mjs.map +1 -1
  13. package/dist/components/navigation/CancelledSubscriptionBanner.mjs +59 -0
  14. package/dist/components/navigation/CancelledSubscriptionBanner.mjs.map +1 -0
  15. package/dist/components/navigation/NavItemsContext.mjs.map +1 -1
  16. package/dist/components/navigation/shells/TabsMobileShell.mjs.map +1 -1
  17. package/dist/components/pages/notifications/Notifications.mjs.map +1 -1
  18. package/dist/components/ui/buttons/Button.mjs.map +1 -1
  19. package/dist/components/ui/buttons/CancelButton.mjs.map +1 -1
  20. package/dist/components/ui/buttons/CopyButton.mjs.map +1 -1
  21. package/dist/components/ui/data-display/Accordion.mjs.map +1 -1
  22. package/dist/components/ui/data-display/Badge.mjs.map +1 -1
  23. package/dist/components/ui/data-display/Card.mjs.map +1 -1
  24. package/dist/components/ui/data-display/Pagination.mjs.map +1 -1
  25. package/dist/components/ui/data-display/ScrollArea.mjs.map +1 -1
  26. package/dist/components/ui/data-display/Separator.mjs.map +1 -1
  27. package/dist/components/ui/data-display/Table.mjs.map +1 -1
  28. package/dist/components/ui/data-display/Tabs.mjs.map +1 -1
  29. package/dist/components/ui/feedback/CircularProgress.mjs.map +1 -1
  30. package/dist/components/ui/feedback/DefaultCircularProgress.mjs.map +1 -1
  31. package/dist/components/ui/feedback/LoadingOverlay.mjs.map +1 -1
  32. package/dist/components/ui/feedback/Progress.mjs.map +1 -1
  33. package/dist/components/ui/feedback/Toast.mjs.map +1 -1
  34. package/dist/components/ui/form/Calendar.mjs.map +1 -1
  35. package/dist/components/ui/form/Checkbox.mjs.map +1 -1
  36. package/dist/components/ui/form/DatePicker.mjs.map +1 -1
  37. package/dist/components/ui/form/DateRangePicker.mjs.map +1 -1
  38. package/dist/components/ui/form/Input.mjs.map +1 -1
  39. package/dist/components/ui/form/InputOtp.mjs.map +1 -1
  40. package/dist/components/ui/form/RadioGroup.mjs.map +1 -1
  41. package/dist/components/ui/form/Select.mjs +1 -1
  42. package/dist/components/ui/form/Select.mjs.map +1 -1
  43. package/dist/components/ui/form/Switch.mjs.map +1 -1
  44. package/dist/components/ui/form/Textarea.mjs.map +1 -1
  45. package/dist/components/ui/overlay/Command.mjs.map +1 -1
  46. package/dist/components/ui/overlay/Dialog.mjs.map +1 -1
  47. package/dist/components/ui/overlay/Popover.mjs.map +1 -1
  48. package/dist/components/ui/overlay/Sheet.mjs.map +1 -1
  49. package/dist/components/ui/overlay/Tooltip.mjs.map +1 -1
  50. package/dist/hooks/copy-to-clipboard.hook.mjs.map +1 -1
  51. package/dist/index.mjs +28 -24
  52. package/dist/index.mjs.map +1 -1
  53. package/dist/middleware.mjs.map +1 -1
  54. package/dist/modules/accounts/actions/account-management.action.mjs.map +1 -1
  55. package/dist/modules/accounts/actions/find-current-account.action.mjs.map +1 -1
  56. package/dist/modules/accounts/actions/list-currencies.action.mjs.map +1 -1
  57. package/dist/modules/accounts/actions/list-timezones.action.mjs.map +1 -1
  58. package/dist/modules/accounts/hooks/current-account.hook.mjs.map +1 -1
  59. package/dist/modules/accounts/hooks/useAccountManagement.mjs.map +1 -1
  60. package/dist/modules/accounts/hooks/useCurrencies.mjs.map +1 -1
  61. package/dist/modules/accounts/hooks/useTimezones.mjs.map +1 -1
  62. package/dist/modules/auth/hooks/login.hook.mjs.map +1 -1
  63. package/dist/modules/auth/hooks/logout.hook.mjs.map +1 -1
  64. package/dist/modules/auth/hooks/register.hook.mjs.map +1 -1
  65. package/dist/modules/auth/services/auth.service.mjs +1 -1
  66. package/dist/modules/auth/services/auth.service.mjs.map +1 -1
  67. package/dist/modules/ia-credits/actions/list-ia-credits.action.mjs.map +1 -1
  68. package/dist/modules/projects/actions/add-project-user.action.mjs.map +1 -1
  69. package/dist/modules/projects/actions/list-available-users.action.mjs.map +1 -1
  70. package/dist/modules/projects/actions/list-project-users.action.mjs.map +1 -1
  71. package/dist/modules/projects/actions/remove-project-user.action.mjs.map +1 -1
  72. package/dist/modules/projects/hooks/list-available-users.hook.mjs.map +1 -1
  73. package/dist/modules/projects/hooks/list-project-users.hook.mjs.map +1 -1
  74. package/dist/modules/subscriptions/actions/list-subscriptions.action.mjs.map +1 -1
  75. package/dist/modules/subscriptions/hooks/find-active-subscription.hook.mjs.map +1 -1
  76. package/dist/modules/subscriptions/hooks/list-subscriptions.hook.mjs.map +1 -1
  77. package/dist/modules/users/action/find-user-by-id.action.mjs.map +1 -1
  78. package/dist/modules/users/action/list-messages.action.mjs.map +1 -1
  79. package/dist/modules/users/action/mark-all-messages-as-read.action.mjs.map +1 -1
  80. package/dist/modules/users/action/mark-message-as-read.action.mjs.map +1 -1
  81. package/dist/modules/users/hooks/messages.hook.mjs.map +1 -1
  82. package/dist/modules/whitelabel/actions/find-whitelabel-styles.action.mjs.map +1 -1
  83. package/dist/modules/whitelabel/actions/find-whitelabel.action.mjs.map +1 -1
  84. package/dist/modules/whitelabel/services/whitelabel-styles.service.mjs.map +1 -1
  85. package/dist/providers/whitelabel.provider.mjs.map +1 -1
  86. package/dist/utils/safeServerAction.mjs.map +1 -1
  87. package/dist/utils/withAction.mjs.map +1 -1
  88. package/package.json +90 -90
  89. package/src/components/account/ConfirmDeleteAccountModal.tsx +55 -55
  90. package/src/components/account/DeleteAccountModal.tsx +130 -130
  91. package/src/components/account/IsntPossibleDeleteAccountModal.tsx +49 -49
  92. package/src/components/account/hooks/useTwoFactorAuthForm.tsx +101 -101
  93. package/src/components/layouts/AppMobileNavBar.tsx +125 -125
  94. package/src/components/layouts/AppNavBar.tsx +57 -57
  95. package/src/components/layouts/NavBar.tsx +139 -139
  96. package/src/components/navigation/CancelledSubscriptionBanner.tsx +69 -69
  97. package/src/components/navigation/NavItemsContext.ts +20 -20
  98. package/src/components/navigation/shells/TabsMobileShell.tsx +72 -72
  99. package/src/components/pages/notifications/Notifications.tsx +160 -160
  100. package/src/components/ui/buttons/Button.tsx +57 -57
  101. package/src/components/ui/buttons/CancelButton.tsx +14 -14
  102. package/src/components/ui/buttons/CopyButton.tsx +54 -54
  103. package/src/components/ui/data-display/Accordion.tsx +81 -81
  104. package/src/components/ui/data-display/Badge.tsx +47 -47
  105. package/src/components/ui/data-display/Card.tsx +93 -93
  106. package/src/components/ui/data-display/Pagination.tsx +126 -126
  107. package/src/components/ui/data-display/ScrollArea.tsx +59 -59
  108. package/src/components/ui/data-display/Separator.tsx +29 -29
  109. package/src/components/ui/data-display/Table.tsx +117 -117
  110. package/src/components/ui/data-display/Tabs.tsx +67 -67
  111. package/src/components/ui/feedback/CircularProgress.tsx +75 -75
  112. package/src/components/ui/feedback/DefaultCircularProgress.tsx +53 -53
  113. package/src/components/ui/feedback/LoadingOverlay.tsx +31 -31
  114. package/src/components/ui/feedback/Progress.tsx +40 -40
  115. package/src/components/ui/feedback/Toast.tsx +101 -101
  116. package/src/components/ui/form/Calendar.tsx +228 -228
  117. package/src/components/ui/form/Checkbox.tsx +31 -31
  118. package/src/components/ui/form/DatePicker.tsx +97 -97
  119. package/src/components/ui/form/DateRangePicker.tsx +108 -108
  120. package/src/components/ui/form/Input.tsx +20 -20
  121. package/src/components/ui/form/InputOtp.tsx +80 -80
  122. package/src/components/ui/form/RadioGroup.tsx +45 -45
  123. package/src/components/ui/form/Select.tsx +200 -200
  124. package/src/components/ui/form/Switch.tsx +32 -32
  125. package/src/components/ui/form/Textarea.tsx +19 -19
  126. package/src/components/ui/overlay/Command.tsx +185 -185
  127. package/src/components/ui/overlay/Dialog.tsx +151 -151
  128. package/src/components/ui/overlay/Popover.tsx +49 -49
  129. package/src/components/ui/overlay/Sheet.tsx +159 -159
  130. package/src/components/ui/overlay/Tooltip.tsx +62 -62
  131. package/src/hooks/copy-to-clipboard.hook.tsx +67 -67
  132. package/src/index.ts +351 -348
  133. package/src/middleware.ts +4 -4
  134. package/src/modules/accounts/actions/account-management.action.ts +90 -90
  135. package/src/modules/accounts/actions/find-current-account.action.ts +9 -9
  136. package/src/modules/accounts/actions/list-currencies.action.ts +8 -8
  137. package/src/modules/accounts/actions/list-timezones.action.ts +8 -8
  138. package/src/modules/accounts/hooks/current-account.hook.tsx +22 -22
  139. package/src/modules/accounts/hooks/useAccountManagement.ts +85 -85
  140. package/src/modules/accounts/hooks/useCurrencies.ts +15 -15
  141. package/src/modules/accounts/hooks/useTimezones.ts +15 -15
  142. package/src/modules/accounts/types.ts +214 -214
  143. package/src/modules/auth/hooks/login.hook.tsx +13 -13
  144. package/src/modules/auth/hooks/logout.hook.tsx +11 -11
  145. package/src/modules/auth/hooks/register.hook.tsx +11 -11
  146. package/src/modules/ia-credits/actions/list-ia-credits.action.ts +8 -8
  147. package/src/modules/projects/actions/add-project-user.action.ts +9 -9
  148. package/src/modules/projects/actions/list-available-users.action.ts +9 -9
  149. package/src/modules/projects/actions/list-project-users.action.ts +9 -9
  150. package/src/modules/projects/actions/remove-project-user.action.ts +9 -9
  151. package/src/modules/projects/hooks/list-available-users.hook.ts +33 -33
  152. package/src/modules/projects/hooks/list-project-users.hook.ts +33 -33
  153. package/src/modules/subscriptions/actions/list-subscriptions.action.ts +9 -9
  154. package/src/modules/subscriptions/hooks/find-active-subscription.hook.ts +19 -19
  155. package/src/modules/subscriptions/hooks/list-subscriptions.hook.ts +17 -17
  156. package/src/modules/users/action/find-user-by-id.action.ts +8 -8
  157. package/src/modules/users/action/list-messages.action.ts +12 -12
  158. package/src/modules/users/action/mark-all-messages-as-read.action.ts +8 -8
  159. package/src/modules/users/action/mark-message-as-read.action.ts +8 -8
  160. package/src/modules/users/hooks/messages.hook.ts +60 -60
  161. package/src/modules/whitelabel/actions/find-whitelabel-styles.action.ts +14 -14
  162. package/src/modules/whitelabel/actions/find-whitelabel.action.ts +23 -23
  163. package/src/modules/whitelabel/services/whitelabel-styles.service.ts +98 -98
  164. package/src/modules/whitelabel/styles-schema.ts +37 -37
  165. package/src/providers/whitelabel.provider.tsx +46 -46
  166. package/src/utils/safeServerAction.ts +21 -21
  167. package/src/utils/withAction.ts +13 -13
@@ -1,101 +1,101 @@
1
- 'use client';
2
-
3
- import { useState, useCallback, useEffect } from 'react';
4
- import { useMutation } from '@tanstack/react-query';
5
- import { toast } from 'sonner';
6
- import { Toast } from '../../ui/feedback/Toast';
7
- import { copyToClipboard } from '../../../utils/browser/clipboard';
8
- import {
9
- generateTwoFactorAction,
10
- confirmTwoFactorAction,
11
- } from '../../../modules/accounts/actions/account-management.action';
12
- import { withAction } from '../../../utils/withAction';
13
-
14
- type Step = 'code' | 'recovery';
15
-
16
- interface UseTwoFactorAuthFormProps {
17
- onSuccess?: () => void;
18
- open?: boolean;
19
- }
20
-
21
- export default function useTwoFactorAuthForm({ onSuccess, open }: UseTwoFactorAuthFormProps = {}) {
22
- const [code, setCode] = useState('');
23
- const [step, setStep] = useState<Step>('code');
24
-
25
- const generateMutation = useMutation({
26
- mutationFn: withAction(generateTwoFactorAction),
27
- onError: () => {
28
- toast.custom((t) => (
29
- <Toast variant="error" message="Erro ao gerar QR Code. Tente novamente." toastId={t} />
30
- ));
31
- },
32
- });
33
-
34
- const confirmMutation = useMutation({
35
- mutationFn: withAction(confirmTwoFactorAction),
36
- onSuccess: () => {
37
- setStep('recovery');
38
- },
39
- onError: () => {
40
- toast.custom((t) => (
41
- <Toast variant="error" message="Erro ao confirmar código. Tente novamente." toastId={t} />
42
- ));
43
- },
44
- });
45
-
46
- const { mutate: triggerGenerate } = generateMutation;
47
-
48
- useEffect(() => {
49
- if (open) {
50
- triggerGenerate();
51
- }
52
- }, [open, triggerGenerate]);
53
-
54
- const generateFailed = generateMutation.isError;
55
-
56
- const isCodeComplete = code.length === 6;
57
-
58
- const handleSubmit = () => {
59
- if (!isCodeComplete) return;
60
- confirmMutation.mutate(code);
61
- };
62
-
63
- const handleFinalize = () => {
64
- onSuccess?.();
65
- setTimeout(resetForm, 300);
66
- };
67
-
68
- const handleCopyCodes = useCallback(async () => {
69
- const codes = generateMutation.data?.backupCodes ?? [];
70
- const success = await copyToClipboard(codes.join('\n'));
71
- if (success) {
72
- toast.custom((t) => (
73
- <Toast variant="success" message="Códigos copiados com sucesso" toastId={t} />
74
- ));
75
- }
76
- }, [generateMutation.data]);
77
-
78
- const resetForm = () => {
79
- setCode('');
80
- setStep('code');
81
- generateMutation.reset();
82
- confirmMutation.reset();
83
- };
84
-
85
- return {
86
- code,
87
- setCode,
88
- isCodeComplete,
89
- isGenerating: generateMutation.isPending,
90
- isConfirming: confirmMutation.isPending,
91
- generateFailed,
92
- retryGenerate: triggerGenerate,
93
- qrcode: generateMutation.data?.qrcode,
94
- backupCodes: generateMutation.data?.backupCodes ?? [],
95
- step,
96
- handleSubmit,
97
- handleFinalize,
98
- handleCopyCodes,
99
- resetForm,
100
- };
101
- }
1
+ 'use client';
2
+
3
+ import { useState, useCallback, useEffect } from 'react';
4
+ import { useMutation } from '@tanstack/react-query';
5
+ import { toast } from 'sonner';
6
+ import { Toast } from '../../ui/feedback/Toast';
7
+ import { copyToClipboard } from '../../../utils/browser/clipboard';
8
+ import {
9
+ generateTwoFactorAction,
10
+ confirmTwoFactorAction,
11
+ } from '../../../modules/accounts/actions/account-management.action';
12
+ import { withAction } from '../../../utils/withAction';
13
+
14
+ type Step = 'code' | 'recovery';
15
+
16
+ interface UseTwoFactorAuthFormProps {
17
+ onSuccess?: () => void;
18
+ open?: boolean;
19
+ }
20
+
21
+ export default function useTwoFactorAuthForm({ onSuccess, open }: UseTwoFactorAuthFormProps = {}) {
22
+ const [code, setCode] = useState('');
23
+ const [step, setStep] = useState<Step>('code');
24
+
25
+ const generateMutation = useMutation({
26
+ mutationFn: withAction(generateTwoFactorAction),
27
+ onError: () => {
28
+ toast.custom((t) => (
29
+ <Toast variant="error" message="Erro ao gerar QR Code. Tente novamente." toastId={t} />
30
+ ));
31
+ },
32
+ });
33
+
34
+ const confirmMutation = useMutation({
35
+ mutationFn: withAction(confirmTwoFactorAction),
36
+ onSuccess: () => {
37
+ setStep('recovery');
38
+ },
39
+ onError: () => {
40
+ toast.custom((t) => (
41
+ <Toast variant="error" message="Erro ao confirmar código. Tente novamente." toastId={t} />
42
+ ));
43
+ },
44
+ });
45
+
46
+ const { mutate: triggerGenerate } = generateMutation;
47
+
48
+ useEffect(() => {
49
+ if (open) {
50
+ triggerGenerate();
51
+ }
52
+ }, [open, triggerGenerate]);
53
+
54
+ const generateFailed = generateMutation.isError;
55
+
56
+ const isCodeComplete = code.length === 6;
57
+
58
+ const handleSubmit = () => {
59
+ if (!isCodeComplete) return;
60
+ confirmMutation.mutate(code);
61
+ };
62
+
63
+ const handleFinalize = () => {
64
+ onSuccess?.();
65
+ setTimeout(resetForm, 300);
66
+ };
67
+
68
+ const handleCopyCodes = useCallback(async () => {
69
+ const codes = generateMutation.data?.backupCodes ?? [];
70
+ const success = await copyToClipboard(codes.join('\n'));
71
+ if (success) {
72
+ toast.custom((t) => (
73
+ <Toast variant="success" message="Códigos copiados com sucesso" toastId={t} />
74
+ ));
75
+ }
76
+ }, [generateMutation.data]);
77
+
78
+ const resetForm = () => {
79
+ setCode('');
80
+ setStep('code');
81
+ generateMutation.reset();
82
+ confirmMutation.reset();
83
+ };
84
+
85
+ return {
86
+ code,
87
+ setCode,
88
+ isCodeComplete,
89
+ isGenerating: generateMutation.isPending,
90
+ isConfirming: confirmMutation.isPending,
91
+ generateFailed,
92
+ retryGenerate: triggerGenerate,
93
+ qrcode: generateMutation.data?.qrcode,
94
+ backupCodes: generateMutation.data?.backupCodes ?? [],
95
+ step,
96
+ handleSubmit,
97
+ handleFinalize,
98
+ handleCopyCodes,
99
+ resetForm,
100
+ };
101
+ }
@@ -1,125 +1,125 @@
1
- "use client";
2
-
3
- import { ReactNode } from "react";
4
- import Image from "next/image";
5
- import { ProfilePopover } from "./ProfilePopover";
6
- import { useAccountModals } from "../../store/useAccountModals";
7
- import type { ProfileMenuItem } from "./ProfilePopover";
8
- import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/overlay/Tooltip";
9
-
10
- export interface AppMobileNavBarProps {
11
- /** Which app is currently active — controls which icon gets the indicator */
12
- activeApp?: "gapps" | "gpages";
13
- /** Called when the GreatApps logo is clicked */
14
- onLogoClick?: () => void;
15
- /** Called when the app icon (e.g. GreatPages) is clicked */
16
- onAppIconClick?: () => void;
17
- /** Extra slot rendered after the app icon (e.g. project selector) */
18
- extraLeftSlot?: ReactNode;
19
- /** Required: the right-side action element (toggle button, sheet button, etc.) */
20
- rightActionSlot: ReactNode;
21
- menuItems?: ProfileMenuItem[];
22
- onCreditsClick?: () => void;
23
- }
24
-
25
- export function AppMobileNavBar({
26
- activeApp,
27
- onLogoClick,
28
- onAppIconClick,
29
- extraLeftSlot,
30
- rightActionSlot,
31
- menuItems = [],
32
- onCreditsClick,
33
- }: AppMobileNavBarProps) {
34
- const { openConfigurations } = useAccountModals();
35
-
36
- const isGpagesActive = activeApp === "gpages";
37
- const isGappsActive = activeApp === "gapps";
38
-
39
- return (
40
- <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">
41
- <div className="flex items-center gap-1.5">
42
- <Tooltip>
43
- <TooltipTrigger asChild>
44
- <div
45
- className={`relative size-10 flex items-center justify-center rounded-lg transition-colors ${onLogoClick ? "cursor-pointer hover:bg-gray-100" : ""}`}
46
- onClick={onLogoClick}
47
- >
48
- <Image
49
- src="/icons/great-icon.svg"
50
- alt="GreatApps"
51
- width={28}
52
- height={28}
53
- />
54
- {isGappsActive && (
55
- <div className="absolute bottom-[-17px] left-1/2 -translate-x-1/2 w-5 h-[3px] bg-gray-950 rounded-t-xl" />
56
- )}
57
- </div>
58
- </TooltipTrigger>
59
- <TooltipContent side="bottom">GreatApps</TooltipContent>
60
- </Tooltip>
61
- <div className="relative">
62
- <Tooltip>
63
- <TooltipTrigger asChild>
64
- {isGpagesActive ? (
65
- <div
66
- className="size-10 rounded-xl cursor-pointer p-[2px]"
67
- style={{
68
- border: "1.5px solid rgba(153,234,255,0.75)",
69
- background: "white",
70
- boxShadow:
71
- "0 0 8px rgba(153,234,255,0.5), 0 0 18px rgba(153,234,255,0.2)",
72
- }}
73
- onClick={onAppIconClick}
74
- >
75
- <div
76
- className="w-full h-full rounded-lg flex items-center justify-center"
77
- style={{
78
- background:
79
- "radial-gradient(circle at center, rgba(255,255,255,0.95) 0%, rgba(153,234,255,0.45) 100%)",
80
- }}
81
- >
82
- <Image
83
- src="/icons/icon-navbar.svg"
84
- alt="GreatPages"
85
- width={24}
86
- height={24}
87
- />
88
- </div>
89
- </div>
90
- ) : (
91
- <div
92
- className={`size-10 flex items-center justify-center rounded-lg transition-colors duration-300 bg-gray-100 ${onAppIconClick ? "cursor-pointer hover:opacity-80" : ""}`}
93
- onClick={onAppIconClick}
94
- >
95
- <Image
96
- src="/icons/icon-navbar.svg"
97
- alt="GreatPages"
98
- width={24}
99
- height={24}
100
- />
101
- </div>
102
- )}
103
- </TooltipTrigger>
104
- <TooltipContent side="bottom">GreatPages</TooltipContent>
105
- </Tooltip>
106
- {isGpagesActive && (
107
- <div className="absolute -bottom-[17px] left-1/2 -translate-x-1/2 w-5 h-[3px] rounded-t-xl" style={{ backgroundColor: "#6ADCFF" }} />
108
- )}
109
- </div>
110
- {extraLeftSlot}
111
- </div>
112
- <div className="flex items-center gap-1.5">
113
- <ProfilePopover
114
- side="bottom"
115
- align="end"
116
- contentClassName=""
117
- onEditProfile={() => openConfigurations()}
118
- onCreditsClick={onCreditsClick}
119
- menuItems={menuItems}
120
- />
121
- {rightActionSlot}
122
- </div>
123
- </div>
124
- );
125
- }
1
+ "use client";
2
+
3
+ import { ReactNode } from "react";
4
+ import Image from "next/image";
5
+ import { ProfilePopover } from "./ProfilePopover";
6
+ import { useAccountModals } from "../../store/useAccountModals";
7
+ import type { ProfileMenuItem } from "./ProfilePopover";
8
+ import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/overlay/Tooltip";
9
+
10
+ export interface AppMobileNavBarProps {
11
+ /** Which app is currently active — controls which icon gets the indicator */
12
+ activeApp?: "gapps" | "gpages";
13
+ /** Called when the GreatApps logo is clicked */
14
+ onLogoClick?: () => void;
15
+ /** Called when the app icon (e.g. GreatPages) is clicked */
16
+ onAppIconClick?: () => void;
17
+ /** Extra slot rendered after the app icon (e.g. project selector) */
18
+ extraLeftSlot?: ReactNode;
19
+ /** Required: the right-side action element (toggle button, sheet button, etc.) */
20
+ rightActionSlot: ReactNode;
21
+ menuItems?: ProfileMenuItem[];
22
+ onCreditsClick?: () => void;
23
+ }
24
+
25
+ export function AppMobileNavBar({
26
+ activeApp,
27
+ onLogoClick,
28
+ onAppIconClick,
29
+ extraLeftSlot,
30
+ rightActionSlot,
31
+ menuItems = [],
32
+ onCreditsClick,
33
+ }: AppMobileNavBarProps) {
34
+ const { openConfigurations } = useAccountModals();
35
+
36
+ const isGpagesActive = activeApp === "gpages";
37
+ const isGappsActive = activeApp === "gapps";
38
+
39
+ return (
40
+ <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">
41
+ <div className="flex items-center gap-1.5">
42
+ <Tooltip>
43
+ <TooltipTrigger asChild>
44
+ <div
45
+ className={`relative size-10 flex items-center justify-center rounded-lg transition-colors ${onLogoClick ? "cursor-pointer hover:bg-gray-100" : ""}`}
46
+ onClick={onLogoClick}
47
+ >
48
+ <Image
49
+ src="/icons/great-icon.svg"
50
+ alt="GreatApps"
51
+ width={28}
52
+ height={28}
53
+ />
54
+ {isGappsActive && (
55
+ <div className="absolute bottom-[-17px] left-1/2 -translate-x-1/2 w-5 h-[3px] bg-gray-950 rounded-t-xl" />
56
+ )}
57
+ </div>
58
+ </TooltipTrigger>
59
+ <TooltipContent side="bottom">GreatApps</TooltipContent>
60
+ </Tooltip>
61
+ <div className="relative">
62
+ <Tooltip>
63
+ <TooltipTrigger asChild>
64
+ {isGpagesActive ? (
65
+ <div
66
+ className="size-10 rounded-xl cursor-pointer p-[2px]"
67
+ style={{
68
+ border: "1.5px solid rgba(153,234,255,0.75)",
69
+ background: "white",
70
+ boxShadow:
71
+ "0 0 8px rgba(153,234,255,0.5), 0 0 18px rgba(153,234,255,0.2)",
72
+ }}
73
+ onClick={onAppIconClick}
74
+ >
75
+ <div
76
+ className="w-full h-full rounded-lg flex items-center justify-center"
77
+ style={{
78
+ background:
79
+ "radial-gradient(circle at center, rgba(255,255,255,0.95) 0%, rgba(153,234,255,0.45) 100%)",
80
+ }}
81
+ >
82
+ <Image
83
+ src="/icons/icon-navbar.svg"
84
+ alt="GreatPages"
85
+ width={24}
86
+ height={24}
87
+ />
88
+ </div>
89
+ </div>
90
+ ) : (
91
+ <div
92
+ className={`size-10 flex items-center justify-center rounded-lg transition-colors duration-300 bg-gray-100 ${onAppIconClick ? "cursor-pointer hover:opacity-80" : ""}`}
93
+ onClick={onAppIconClick}
94
+ >
95
+ <Image
96
+ src="/icons/icon-navbar.svg"
97
+ alt="GreatPages"
98
+ width={24}
99
+ height={24}
100
+ />
101
+ </div>
102
+ )}
103
+ </TooltipTrigger>
104
+ <TooltipContent side="bottom">GreatPages</TooltipContent>
105
+ </Tooltip>
106
+ {isGpagesActive && (
107
+ <div className="absolute -bottom-[17px] left-1/2 -translate-x-1/2 w-5 h-[3px] rounded-t-xl" style={{ backgroundColor: "#6ADCFF" }} />
108
+ )}
109
+ </div>
110
+ {extraLeftSlot}
111
+ </div>
112
+ <div className="flex items-center gap-1.5">
113
+ <ProfilePopover
114
+ side="bottom"
115
+ align="end"
116
+ contentClassName=""
117
+ onEditProfile={() => openConfigurations()}
118
+ onCreditsClick={onCreditsClick}
119
+ menuItems={menuItems}
120
+ />
121
+ {rightActionSlot}
122
+ </div>
123
+ </div>
124
+ );
125
+ }
@@ -1,57 +1,57 @@
1
- "use client";
2
-
3
- import { useRouter } from "next/navigation";
4
- import { NavBar } from "./NavBar";
5
- import { ProfilePopover } from "./ProfilePopover";
6
- import { NotificationsPopover } from "./NotificationsPopover";
7
- import { useAccountModals } from "../../store/useAccountModals";
8
- import type { ProfileMenuItem } from "./ProfilePopover";
9
-
10
- export interface AppNavBarProps {
11
- onLogoClick?: () => void;
12
- /** Which app is currently active — controls which icon gets the indicator */
13
- activeApp?: "gapps" | "gpages";
14
- appIconHref?: string;
15
- showExpandButton?: boolean;
16
- onExpandClick?: () => void;
17
- menuItems?: ProfileMenuItem[];
18
- onCreditsClick?: () => void;
19
- onNotificationsViewAll?: () => void;
20
- logoutRedirect?: string;
21
- }
22
-
23
- export function AppNavBar({
24
- onLogoClick,
25
- activeApp,
26
- appIconHref = "/",
27
- showExpandButton = false,
28
- onExpandClick,
29
- menuItems = [],
30
- onCreditsClick,
31
- onNotificationsViewAll,
32
- logoutRedirect,
33
- }: AppNavBarProps) {
34
- const router = useRouter();
35
- const { openConfigurations } = useAccountModals();
36
-
37
- const handleLogoClick = onLogoClick ?? (() => router.push("/"));
38
- const handleAppIconClick = () => router.push(appIconHref);
39
-
40
- return (
41
- <NavBar
42
- onLogoClick={handleLogoClick}
43
- onAppIconClick={handleAppIconClick}
44
- activeApp={activeApp}
45
- showExpandButton={showExpandButton}
46
- onExpandClick={onExpandClick}
47
- >
48
- <NotificationsPopover onViewAll={onNotificationsViewAll} />
49
- <ProfilePopover
50
- onEditProfile={() => openConfigurations()}
51
- onCreditsClick={onCreditsClick}
52
- menuItems={menuItems}
53
- logoutRedirect={logoutRedirect}
54
- />
55
- </NavBar>
56
- );
57
- }
1
+ "use client";
2
+
3
+ import { useRouter } from "next/navigation";
4
+ import { NavBar } from "./NavBar";
5
+ import { ProfilePopover } from "./ProfilePopover";
6
+ import { NotificationsPopover } from "./NotificationsPopover";
7
+ import { useAccountModals } from "../../store/useAccountModals";
8
+ import type { ProfileMenuItem } from "./ProfilePopover";
9
+
10
+ export interface AppNavBarProps {
11
+ onLogoClick?: () => void;
12
+ /** Which app is currently active — controls which icon gets the indicator */
13
+ activeApp?: "gapps" | "gpages";
14
+ appIconHref?: string;
15
+ showExpandButton?: boolean;
16
+ onExpandClick?: () => void;
17
+ menuItems?: ProfileMenuItem[];
18
+ onCreditsClick?: () => void;
19
+ onNotificationsViewAll?: () => void;
20
+ logoutRedirect?: string;
21
+ }
22
+
23
+ export function AppNavBar({
24
+ onLogoClick,
25
+ activeApp,
26
+ appIconHref = "/",
27
+ showExpandButton = false,
28
+ onExpandClick,
29
+ menuItems = [],
30
+ onCreditsClick,
31
+ onNotificationsViewAll,
32
+ logoutRedirect,
33
+ }: AppNavBarProps) {
34
+ const router = useRouter();
35
+ const { openConfigurations } = useAccountModals();
36
+
37
+ const handleLogoClick = onLogoClick ?? (() => router.push("/"));
38
+ const handleAppIconClick = () => router.push(appIconHref);
39
+
40
+ return (
41
+ <NavBar
42
+ onLogoClick={handleLogoClick}
43
+ onAppIconClick={handleAppIconClick}
44
+ activeApp={activeApp}
45
+ showExpandButton={showExpandButton}
46
+ onExpandClick={onExpandClick}
47
+ >
48
+ <NotificationsPopover onViewAll={onNotificationsViewAll} />
49
+ <ProfilePopover
50
+ onEditProfile={() => openConfigurations()}
51
+ onCreditsClick={onCreditsClick}
52
+ menuItems={menuItems}
53
+ logoutRedirect={logoutRedirect}
54
+ />
55
+ </NavBar>
56
+ );
57
+ }