@greatapps/common 1.1.128 → 1.1.129

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 (149) 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.map +1 -1
  8. package/dist/components/navigation/NavItemsContext.mjs.map +1 -1
  9. package/dist/components/navigation/ProjectSelectorPopover.mjs +2 -10
  10. package/dist/components/navigation/ProjectSelectorPopover.mjs.map +1 -1
  11. package/dist/components/navigation/shells/TabsMobileShell.mjs.map +1 -1
  12. package/dist/components/pages/notifications/Notifications.mjs.map +1 -1
  13. package/dist/components/ui/buttons/Button.mjs.map +1 -1
  14. package/dist/components/ui/buttons/CancelButton.mjs.map +1 -1
  15. package/dist/components/ui/buttons/CopyButton.mjs.map +1 -1
  16. package/dist/components/ui/data-display/Accordion.mjs.map +1 -1
  17. package/dist/components/ui/data-display/Badge.mjs.map +1 -1
  18. package/dist/components/ui/data-display/Card.mjs.map +1 -1
  19. package/dist/components/ui/data-display/Pagination.mjs.map +1 -1
  20. package/dist/components/ui/data-display/ScrollArea.mjs.map +1 -1
  21. package/dist/components/ui/data-display/Separator.mjs.map +1 -1
  22. package/dist/components/ui/data-display/Table.mjs.map +1 -1
  23. package/dist/components/ui/data-display/Tabs.mjs.map +1 -1
  24. package/dist/components/ui/feedback/CircularProgress.mjs.map +1 -1
  25. package/dist/components/ui/feedback/DefaultCircularProgress.mjs.map +1 -1
  26. package/dist/components/ui/feedback/LoadingOverlay.mjs.map +1 -1
  27. package/dist/components/ui/feedback/Progress.mjs.map +1 -1
  28. package/dist/components/ui/feedback/Toast.mjs.map +1 -1
  29. package/dist/components/ui/form/Calendar.mjs.map +1 -1
  30. package/dist/components/ui/form/Checkbox.mjs.map +1 -1
  31. package/dist/components/ui/form/DatePicker.mjs.map +1 -1
  32. package/dist/components/ui/form/DateRangePicker.mjs.map +1 -1
  33. package/dist/components/ui/form/Input.mjs.map +1 -1
  34. package/dist/components/ui/form/InputOtp.mjs.map +1 -1
  35. package/dist/components/ui/form/RadioGroup.mjs.map +1 -1
  36. package/dist/components/ui/form/Select.mjs +1 -1
  37. package/dist/components/ui/form/Select.mjs.map +1 -1
  38. package/dist/components/ui/form/Switch.mjs.map +1 -1
  39. package/dist/components/ui/form/Textarea.mjs.map +1 -1
  40. package/dist/components/ui/overlay/Command.mjs.map +1 -1
  41. package/dist/components/ui/overlay/Dialog.mjs.map +1 -1
  42. package/dist/components/ui/overlay/Popover.mjs.map +1 -1
  43. package/dist/components/ui/overlay/Sheet.mjs.map +1 -1
  44. package/dist/components/ui/overlay/Tooltip.mjs.map +1 -1
  45. package/dist/hooks/copy-to-clipboard.hook.mjs.map +1 -1
  46. package/dist/index.mjs.map +1 -1
  47. package/dist/modules/accounts/actions/account-management.action.mjs.map +1 -1
  48. package/dist/modules/accounts/actions/find-current-account.action.mjs.map +1 -1
  49. package/dist/modules/accounts/actions/list-currencies.action.mjs.map +1 -1
  50. package/dist/modules/accounts/actions/list-timezones.action.mjs.map +1 -1
  51. package/dist/modules/accounts/hooks/current-account.hook.mjs.map +1 -1
  52. package/dist/modules/accounts/hooks/useAccountManagement.mjs.map +1 -1
  53. package/dist/modules/accounts/hooks/useCurrencies.mjs.map +1 -1
  54. package/dist/modules/accounts/hooks/useTimezones.mjs.map +1 -1
  55. package/dist/modules/auth/hooks/login.hook.mjs.map +1 -1
  56. package/dist/modules/auth/hooks/logout.hook.mjs.map +1 -1
  57. package/dist/modules/auth/hooks/register.hook.mjs.map +1 -1
  58. package/dist/modules/ia-credits/actions/list-ia-credits.action.mjs.map +1 -1
  59. package/dist/modules/projects/actions/add-project-user.action.mjs.map +1 -1
  60. package/dist/modules/projects/actions/list-available-users.action.mjs.map +1 -1
  61. package/dist/modules/projects/actions/list-project-users.action.mjs.map +1 -1
  62. package/dist/modules/projects/actions/remove-project-user.action.mjs.map +1 -1
  63. package/dist/modules/projects/hooks/list-available-users.hook.mjs.map +1 -1
  64. package/dist/modules/projects/hooks/list-project-users.hook.mjs.map +1 -1
  65. package/dist/modules/subscriptions/actions/list-subscriptions.action.mjs.map +1 -1
  66. package/dist/modules/subscriptions/hooks/find-active-subscription.hook.mjs.map +1 -1
  67. package/dist/modules/subscriptions/hooks/list-subscriptions.hook.mjs.map +1 -1
  68. package/dist/modules/users/action/find-user-by-id.action.mjs.map +1 -1
  69. package/dist/modules/users/action/list-messages.action.mjs.map +1 -1
  70. package/dist/modules/users/action/mark-all-messages-as-read.action.mjs.map +1 -1
  71. package/dist/modules/users/action/mark-message-as-read.action.mjs.map +1 -1
  72. package/dist/modules/users/hooks/messages.hook.mjs.map +1 -1
  73. package/dist/modules/whitelabel/actions/find-whitelabel.action.mjs.map +1 -1
  74. package/dist/utils/safeServerAction.mjs.map +1 -1
  75. package/dist/utils/withAction.mjs.map +1 -1
  76. package/package.json +84 -84
  77. package/src/components/account/ConfirmDeleteAccountModal.tsx +55 -55
  78. package/src/components/account/DeleteAccountModal.tsx +130 -130
  79. package/src/components/account/IsntPossibleDeleteAccountModal.tsx +49 -49
  80. package/src/components/account/hooks/useTwoFactorAuthForm.tsx +101 -101
  81. package/src/components/layouts/AppMobileNavBar.tsx +125 -125
  82. package/src/components/layouts/AppNavBar.tsx +57 -57
  83. package/src/components/layouts/NavBar.tsx +139 -139
  84. package/src/components/navigation/NavItemsContext.ts +20 -20
  85. package/src/components/navigation/ProjectSelectorPopover.tsx +4 -7
  86. package/src/components/navigation/shells/TabsMobileShell.tsx +72 -72
  87. package/src/components/pages/notifications/Notifications.tsx +160 -160
  88. package/src/components/ui/buttons/Button.tsx +57 -57
  89. package/src/components/ui/buttons/CancelButton.tsx +14 -14
  90. package/src/components/ui/buttons/CopyButton.tsx +54 -54
  91. package/src/components/ui/data-display/Accordion.tsx +81 -81
  92. package/src/components/ui/data-display/Badge.tsx +47 -47
  93. package/src/components/ui/data-display/Card.tsx +93 -93
  94. package/src/components/ui/data-display/Pagination.tsx +126 -126
  95. package/src/components/ui/data-display/ScrollArea.tsx +59 -59
  96. package/src/components/ui/data-display/Separator.tsx +29 -29
  97. package/src/components/ui/data-display/Table.tsx +117 -117
  98. package/src/components/ui/data-display/Tabs.tsx +67 -67
  99. package/src/components/ui/feedback/CircularProgress.tsx +75 -75
  100. package/src/components/ui/feedback/DefaultCircularProgress.tsx +53 -53
  101. package/src/components/ui/feedback/LoadingOverlay.tsx +31 -31
  102. package/src/components/ui/feedback/Progress.tsx +40 -40
  103. package/src/components/ui/feedback/Toast.tsx +101 -101
  104. package/src/components/ui/form/Calendar.tsx +228 -228
  105. package/src/components/ui/form/Checkbox.tsx +31 -31
  106. package/src/components/ui/form/DatePicker.tsx +97 -97
  107. package/src/components/ui/form/DateRangePicker.tsx +108 -108
  108. package/src/components/ui/form/Input.tsx +20 -20
  109. package/src/components/ui/form/InputOtp.tsx +80 -80
  110. package/src/components/ui/form/RadioGroup.tsx +45 -45
  111. package/src/components/ui/form/Select.tsx +200 -200
  112. package/src/components/ui/form/Switch.tsx +32 -32
  113. package/src/components/ui/form/Textarea.tsx +19 -19
  114. package/src/components/ui/overlay/Command.tsx +185 -185
  115. package/src/components/ui/overlay/Dialog.tsx +151 -151
  116. package/src/components/ui/overlay/Popover.tsx +49 -49
  117. package/src/components/ui/overlay/Sheet.tsx +159 -159
  118. package/src/components/ui/overlay/Tooltip.tsx +62 -62
  119. package/src/hooks/copy-to-clipboard.hook.tsx +67 -67
  120. package/src/index.ts +346 -346
  121. package/src/modules/accounts/actions/account-management.action.ts +90 -90
  122. package/src/modules/accounts/actions/find-current-account.action.ts +9 -9
  123. package/src/modules/accounts/actions/list-currencies.action.ts +8 -8
  124. package/src/modules/accounts/actions/list-timezones.action.ts +8 -8
  125. package/src/modules/accounts/hooks/current-account.hook.tsx +22 -22
  126. package/src/modules/accounts/hooks/useAccountManagement.ts +85 -85
  127. package/src/modules/accounts/hooks/useCurrencies.ts +15 -15
  128. package/src/modules/accounts/hooks/useTimezones.ts +15 -15
  129. package/src/modules/auth/hooks/login.hook.tsx +17 -17
  130. package/src/modules/auth/hooks/logout.hook.tsx +11 -11
  131. package/src/modules/auth/hooks/register.hook.tsx +11 -11
  132. package/src/modules/ia-credits/actions/list-ia-credits.action.ts +8 -8
  133. package/src/modules/projects/actions/add-project-user.action.ts +9 -9
  134. package/src/modules/projects/actions/list-available-users.action.ts +9 -9
  135. package/src/modules/projects/actions/list-project-users.action.ts +9 -9
  136. package/src/modules/projects/actions/remove-project-user.action.ts +9 -9
  137. package/src/modules/projects/hooks/list-available-users.hook.ts +33 -33
  138. package/src/modules/projects/hooks/list-project-users.hook.ts +33 -33
  139. package/src/modules/subscriptions/actions/list-subscriptions.action.ts +9 -9
  140. package/src/modules/subscriptions/hooks/find-active-subscription.hook.ts +19 -19
  141. package/src/modules/subscriptions/hooks/list-subscriptions.hook.ts +17 -17
  142. package/src/modules/users/action/find-user-by-id.action.ts +8 -8
  143. package/src/modules/users/action/list-messages.action.ts +12 -12
  144. package/src/modules/users/action/mark-all-messages-as-read.action.ts +8 -8
  145. package/src/modules/users/action/mark-message-as-read.action.ts +8 -8
  146. package/src/modules/users/hooks/messages.hook.ts +60 -60
  147. package/src/modules/whitelabel/actions/find-whitelabel.action.ts +23 -23
  148. package/src/utils/safeServerAction.ts +21 -21
  149. 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
+ }