@greatapps/common 1.1.362 → 1.1.364
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/layouts/NavBar.mjs +2 -1
- package/dist/components/layouts/NavBar.mjs.map +1 -1
- package/dist/modules/subscriptions/actions/update-subscription-plan.action.mjs +9 -0
- package/dist/modules/subscriptions/actions/update-subscription-plan.action.mjs.map +1 -1
- package/dist/store/useDesktopSidebarStore.mjs +18 -7
- package/dist/store/useDesktopSidebarStore.mjs.map +1 -1
- package/package.json +1 -1
- package/src/components/account/sections/ChangeEmailModal.tsx +1 -1
- package/src/components/account/sections/ChangePhoneModal.tsx +1 -1
- package/src/components/layouts/NavBar.tsx +2 -1
- package/src/components/navigation/ProjectSelectorPopover.tsx +13 -14
- package/src/components/pages/notifications/Notifications.tsx +1 -1
- package/src/components/ui/buttons/Button.tsx +1 -1
- package/src/components/ui/feedback/Toast.tsx +1 -1
- package/src/components/widgets/notifications/NotificationCard.tsx +1 -1
- package/src/store/useDesktopSidebarStore.ts +21 -8
|
@@ -4,7 +4,7 @@ import Image from "next/image";
|
|
|
4
4
|
import { IconChevronRight } from "@tabler/icons-react";
|
|
5
5
|
import { Separator } from "../ui/data-display/Separator";
|
|
6
6
|
import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/overlay/Tooltip";
|
|
7
|
-
import { useDesktopSidebarStore } from "../../store/useDesktopSidebarStore";
|
|
7
|
+
import { useDesktopSidebarStore, useDesktopSidebarHydration } from "../../store/useDesktopSidebarStore";
|
|
8
8
|
import { useWhitelabel } from "../../providers/whitelabel.provider";
|
|
9
9
|
import { cn } from "../../infra/utils/clsx";
|
|
10
10
|
function NavBar({
|
|
@@ -17,6 +17,7 @@ function NavBar({
|
|
|
17
17
|
className
|
|
18
18
|
}) {
|
|
19
19
|
const { isExpanded: isDesktopExpanded, toggle: toggleDesktop } = useDesktopSidebarStore();
|
|
20
|
+
useDesktopSidebarHydration();
|
|
20
21
|
const { whitelabel } = useWhitelabel();
|
|
21
22
|
const isDefaultWl = !whitelabel || whitelabel.id === 1;
|
|
22
23
|
const primaryColor = whitelabel?.general?.primary_color;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/layouts/NavBar.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport Image from \"next/image\";\nimport { IconChevronRight } from \"@tabler/icons-react\";\nimport { Separator } from \"../ui/data-display/Separator\";\nimport { Tooltip, TooltipContent, TooltipTrigger } from \"../ui/overlay/Tooltip\";\nimport { useDesktopSidebarStore } from \"../../store/useDesktopSidebarStore\";\nimport { useWhitelabel } from \"../../providers/whitelabel.provider\";\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 const { isExpanded: isDesktopExpanded, toggle: toggleDesktop } =\n useDesktopSidebarStore();\n const { whitelabel } = useWhitelabel();\n const isDefaultWl = !whitelabel || whitelabel.id === 1;\n const primaryColor = whitelabel?.general?.primary_color;\n const wlName = whitelabel?.name || 'Great';\n\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 {isDefaultWl ? (\n <Image\n src=\"/icons/great-icon.svg\"\n alt=\"Great Icon\"\n width={28}\n height={28}\n />\n ) : (\n <div\n className={cn(\"size-10 rounded-lg flex items-center justify-center transition-opacity duration-300\", activeApp !== \"gapps\" && \"opacity-20\")}\n style={{ backgroundColor: primaryColor }}\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"white\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M4 5a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v4a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1l0 -4\" />\n <path d=\"M14 5a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v4a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1l0 -4\" />\n <path d=\"M4 15a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v4a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1l0 -4\" />\n <path d=\"M14 15a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v4a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1l0 -4\" />\n </svg>\n </div>\n )}\n </TooltipTrigger>\n <TooltipContent side=\"right\">{wlName}</TooltipContent>\n </Tooltip>\n <div\n className={cn(\n \"absolute -left-[22px] top-1/2 -translate-y-1/2 z-10 w-[3px] h-5 rounded-r-xl transition-opacity duration-300\",\n isDefaultWl ? \"bg-gray-950\" : \"\",\n activeApp === \"gapps\" ? \"opacity-100\" : \"opacity-0\",\n )}\n style={!isDefaultWl ? { backgroundColor: primaryColor } : undefined}\n />\n </div>\n\n <div className=\"relative w-full mt-[7.5px]\">\n <Separator />\n {/* Md expand button */}\n {showExpandButton && (\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n onClick={onExpandClick}\n className=\"hidden md:flex lg:hidden absolute top-1/2 -translate-y-1/2 right-0 translate-x-[calc(50%+1rem)] size-8 items-center justify-center rounded-full border border-gray-200 bg-white hover:bg-gray-100 cursor-pointer transition-colors z-10\"\n >\n <IconChevronRight size={16} className=\"text-gray-500\" />\n </button>\n </TooltipTrigger>\n <TooltipContent side=\"right\">Expandir menu</TooltipContent>\n </Tooltip>\n )}\n {/* Desktop expand button */}\n {!isDesktopExpanded && (\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n onClick={toggleDesktop}\n className=\"hidden lg:flex absolute top-1/2 -translate-y-1/2 right-0 translate-x-[calc(50%+1rem)] size-8 items-center justify-center rounded-full border border-gray-200 bg-white hover:bg-gray-100 cursor-pointer transition-colors z-10\"\n >\n <IconChevronRight 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=\"relative\">\n <Tooltip>\n <TooltipTrigger asChild onClick={onAppIconClick}>\n <div\n className={cn(\n \"size-10 rounded-lg cursor-pointer flex items-center justify-center border-2 ring-2 transition-colors duration-300\",\n activeApp === \"gpages\"\n ? isDefaultWl\n ? \"bg-cyan-100 border-white ring-cyan-300\"\n : \"border-white ring-transparent\"\n : isDefaultWl\n ? \"hover:bg-gray-100 border-transparent ring-transparent\"\n : \"border-transparent ring-transparent\",\n )}\n style={!isDefaultWl ? { backgroundColor: primaryColor, boxShadow: activeApp === \"gpages\" ? `0 0 0 2px ${primaryColor}40` : undefined, opacity: activeApp !== \"gpages\" ? 0.2 : undefined } : undefined}\n >\n {isDefaultWl ? (\n <Image\n src=\"/icons/icon-navbar.svg\"\n alt=\"GreatPages\"\n width={24}\n height={24}\n />\n ) : (\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"white\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M4 8h16\" />\n <path d=\"M4 6a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v12a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2l0 -12\" />\n <path d=\"M8 4v4\" />\n </svg>\n )}\n </div>\n </TooltipTrigger>\n <TooltipContent side=\"right\">{isDefaultWl ? 'GreatPages' : 'Páginas'}</TooltipContent>\n </Tooltip>\n <div\n className={cn(\n \"absolute -left-4 top-1/2 -translate-y-1/2 z-10 w-[3px] h-5 rounded-r-xl transition-opacity duration-300\",\n isDefaultWl ? \"bg-cyan-300\" : \"\",\n activeApp === \"gpages\" ? \"opacity-100\" : \"opacity-0\",\n )}\n style={!isDefaultWl ? { backgroundColor: primaryColor } : undefined}\n />\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":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/components/layouts/NavBar.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport Image from \"next/image\";\nimport { IconChevronRight } from \"@tabler/icons-react\";\nimport { Separator } from \"../ui/data-display/Separator\";\nimport { Tooltip, TooltipContent, TooltipTrigger } from \"../ui/overlay/Tooltip\";\nimport { useDesktopSidebarStore, useDesktopSidebarHydration } from \"../../store/useDesktopSidebarStore\";\nimport { useWhitelabel } from \"../../providers/whitelabel.provider\";\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 const { isExpanded: isDesktopExpanded, toggle: toggleDesktop } =\n useDesktopSidebarStore();\n useDesktopSidebarHydration();\n const { whitelabel } = useWhitelabel();\n const isDefaultWl = !whitelabel || whitelabel.id === 1;\n const primaryColor = whitelabel?.general?.primary_color;\n const wlName = whitelabel?.name || 'Great';\n\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 {isDefaultWl ? (\n <Image\n src=\"/icons/great-icon.svg\"\n alt=\"Great Icon\"\n width={28}\n height={28}\n />\n ) : (\n <div\n className={cn(\"size-10 rounded-lg flex items-center justify-center transition-opacity duration-300\", activeApp !== \"gapps\" && \"opacity-20\")}\n style={{ backgroundColor: primaryColor }}\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"white\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M4 5a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v4a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1l0 -4\" />\n <path d=\"M14 5a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v4a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1l0 -4\" />\n <path d=\"M4 15a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v4a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1l0 -4\" />\n <path d=\"M14 15a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v4a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1l0 -4\" />\n </svg>\n </div>\n )}\n </TooltipTrigger>\n <TooltipContent side=\"right\">{wlName}</TooltipContent>\n </Tooltip>\n <div\n className={cn(\n \"absolute -left-[22px] top-1/2 -translate-y-1/2 z-10 w-[3px] h-5 rounded-r-xl transition-opacity duration-300\",\n isDefaultWl ? \"bg-gray-950\" : \"\",\n activeApp === \"gapps\" ? \"opacity-100\" : \"opacity-0\",\n )}\n style={!isDefaultWl ? { backgroundColor: primaryColor } : undefined}\n />\n </div>\n\n <div className=\"relative w-full mt-[7.5px]\">\n <Separator />\n {/* Md expand button */}\n {showExpandButton && (\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n onClick={onExpandClick}\n className=\"hidden md:flex lg:hidden absolute top-1/2 -translate-y-1/2 right-0 translate-x-[calc(50%+1rem)] size-8 items-center justify-center rounded-full border border-gray-200 bg-white hover:bg-gray-100 cursor-pointer transition-colors z-10\"\n >\n <IconChevronRight size={16} className=\"text-gray-500\" />\n </button>\n </TooltipTrigger>\n <TooltipContent side=\"right\">Expandir menu</TooltipContent>\n </Tooltip>\n )}\n {/* Desktop expand button */}\n {!isDesktopExpanded && (\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n onClick={toggleDesktop}\n className=\"hidden lg:flex absolute top-1/2 -translate-y-1/2 right-0 translate-x-[calc(50%+1rem)] size-8 items-center justify-center rounded-full border border-gray-200 bg-white hover:bg-gray-100 cursor-pointer transition-colors z-10\"\n >\n <IconChevronRight 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=\"relative\">\n <Tooltip>\n <TooltipTrigger asChild onClick={onAppIconClick}>\n <div\n className={cn(\n \"size-10 rounded-lg cursor-pointer flex items-center justify-center border-2 ring-2 transition-colors duration-300\",\n activeApp === \"gpages\"\n ? isDefaultWl\n ? \"bg-cyan-100 border-white ring-cyan-300\"\n : \"border-white ring-transparent\"\n : isDefaultWl\n ? \"hover:bg-gray-100 border-transparent ring-transparent\"\n : \"border-transparent ring-transparent\",\n )}\n style={!isDefaultWl ? { backgroundColor: primaryColor, boxShadow: activeApp === \"gpages\" ? `0 0 0 2px ${primaryColor}40` : undefined, opacity: activeApp !== \"gpages\" ? 0.2 : undefined } : undefined}\n >\n {isDefaultWl ? (\n <Image\n src=\"/icons/icon-navbar.svg\"\n alt=\"GreatPages\"\n width={24}\n height={24}\n />\n ) : (\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"white\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M4 8h16\" />\n <path d=\"M4 6a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v12a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2l0 -12\" />\n <path d=\"M8 4v4\" />\n </svg>\n )}\n </div>\n </TooltipTrigger>\n <TooltipContent side=\"right\">{isDefaultWl ? 'GreatPages' : 'Páginas'}</TooltipContent>\n </Tooltip>\n <div\n className={cn(\n \"absolute -left-4 top-1/2 -translate-y-1/2 z-10 w-[3px] h-5 rounded-r-xl transition-opacity duration-300\",\n isDefaultWl ? \"bg-cyan-300\" : \"\",\n activeApp === \"gpages\" ? \"opacity-100\" : \"opacity-0\",\n )}\n style={!isDefaultWl ? { backgroundColor: primaryColor } : undefined}\n />\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":"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","names":[]}
|
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
"use server";
|
|
2
2
|
import { safeServerAction } from "../../../utils/safeServerAction";
|
|
3
3
|
import { subscriptionsService } from "../services/subscriptions.service";
|
|
4
|
+
import { resolvePlanExtrasPrices } from "../utils/resolve-plan-extras-prices";
|
|
4
5
|
async function updateSubscriptionPlanAction(subscriptionId, data) {
|
|
5
6
|
return safeServerAction(async () => {
|
|
7
|
+
if (data.plan_extras?.length) {
|
|
8
|
+
const { data: subscriptions } = await subscriptionsService.listSubscriptions({ active: true });
|
|
9
|
+
const subscription = subscriptions.find((s) => String(s.id) === String(subscriptionId)) ?? subscriptions[0];
|
|
10
|
+
data = {
|
|
11
|
+
...data,
|
|
12
|
+
plan_extras: resolvePlanExtrasPrices(data.plan_extras, subscription?.items ?? [])
|
|
13
|
+
};
|
|
14
|
+
}
|
|
6
15
|
return subscriptionsService.updateSubscriptionPlan(subscriptionId, data);
|
|
7
16
|
});
|
|
8
17
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/modules/subscriptions/actions/update-subscription-plan.action.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"sources":["../../../../src/modules/subscriptions/actions/update-subscription-plan.action.ts"],"sourcesContent":["'use server';\n\nimport { safeServerAction } from '../../../utils/safeServerAction';\nimport type { UpdateSubscriptionPlanRequest } from '../types/calculate-subscription.type';\nimport { subscriptionsService } from '../services/subscriptions.service';\nimport { resolvePlanExtrasPrices } from '../utils/resolve-plan-extras-prices';\n\nexport async function updateSubscriptionPlanAction(\n subscriptionId: number | string,\n data: UpdateSubscriptionPlanRequest\n) {\n return safeServerAction(async () => {\n if (data.plan_extras?.length) {\n const { data: subscriptions } = await subscriptionsService.listSubscriptions({ active: true });\n const subscription =\n subscriptions.find((s) => String(s.id) === String(subscriptionId)) ?? subscriptions[0];\n\n data = {\n ...data,\n plan_extras: resolvePlanExtrasPrices(data.plan_extras, subscription?.items ?? []),\n };\n }\n\n return subscriptionsService.updateSubscriptionPlan(subscriptionId, data);\n });\n}\n"],"mappings":";AAEA,SAAS,wBAAwB;AAEjC,SAAS,4BAA4B;AACrC,SAAS,+BAA+B;AAExC,eAAsB,6BACpB,gBACA,MACA;AACA,SAAO,iBAAiB,YAAY;AAClC,QAAI,KAAK,aAAa,QAAQ;AAC5B,YAAM,EAAE,MAAM,cAAc,IAAI,MAAM,qBAAqB,kBAAkB,EAAE,QAAQ,KAAK,CAAC;AAC7F,YAAM,eACJ,cAAc,KAAK,CAAC,MAAM,OAAO,EAAE,EAAE,MAAM,OAAO,cAAc,CAAC,KAAK,cAAc,CAAC;AAEvF,aAAO;AAAA,QACL,GAAG;AAAA,QACH,aAAa,wBAAwB,KAAK,aAAa,cAAc,SAAS,CAAC,CAAC;AAAA,MAClF;AAAA,IACF;AAEA,WAAO,qBAAqB,uBAAuB,gBAAgB,IAAI;AAAA,EACzE,CAAC;AACH;","names":[]}
|
|
@@ -1,13 +1,9 @@
|
|
|
1
1
|
import { create } from "zustand";
|
|
2
|
+
import { useEffect } from "react";
|
|
2
3
|
const STORAGE_KEY = "desktop-sidebar-expanded";
|
|
3
|
-
function getInitialState() {
|
|
4
|
-
if (typeof window === "undefined") return true;
|
|
5
|
-
const stored = localStorage.getItem(STORAGE_KEY);
|
|
6
|
-
if (stored === null) return true;
|
|
7
|
-
return stored === "true";
|
|
8
|
-
}
|
|
9
4
|
const useDesktopSidebarStore = create((set) => ({
|
|
10
|
-
isExpanded:
|
|
5
|
+
isExpanded: true,
|
|
6
|
+
_hydrated: false,
|
|
11
7
|
toggle: () => set((state) => {
|
|
12
8
|
const next = !state.isExpanded;
|
|
13
9
|
localStorage.setItem(STORAGE_KEY, String(next));
|
|
@@ -20,9 +16,24 @@ const useDesktopSidebarStore = create((set) => ({
|
|
|
20
16
|
collapse: () => {
|
|
21
17
|
localStorage.setItem(STORAGE_KEY, "false");
|
|
22
18
|
return set({ isExpanded: false });
|
|
19
|
+
},
|
|
20
|
+
_hydrate: () => {
|
|
21
|
+
const stored = localStorage.getItem(STORAGE_KEY);
|
|
22
|
+
const value = stored === null ? true : stored === "true";
|
|
23
|
+
set({ isExpanded: value, _hydrated: true });
|
|
23
24
|
}
|
|
24
25
|
}));
|
|
26
|
+
function useDesktopSidebarHydration() {
|
|
27
|
+
const hydrate = useDesktopSidebarStore((s) => s._hydrate);
|
|
28
|
+
const hydrated = useDesktopSidebarStore((s) => s._hydrated);
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
if (!hydrated) {
|
|
31
|
+
hydrate();
|
|
32
|
+
}
|
|
33
|
+
}, [hydrate, hydrated]);
|
|
34
|
+
}
|
|
25
35
|
export {
|
|
36
|
+
useDesktopSidebarHydration,
|
|
26
37
|
useDesktopSidebarStore
|
|
27
38
|
};
|
|
28
39
|
//# sourceMappingURL=useDesktopSidebarStore.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/store/useDesktopSidebarStore.ts"],"sourcesContent":["import { create } from \"zustand\";\
|
|
1
|
+
{"version":3,"sources":["../../src/store/useDesktopSidebarStore.ts"],"sourcesContent":["import { create } from \"zustand\";\nimport { useEffect } from \"react\";\n\nconst STORAGE_KEY = \"desktop-sidebar-expanded\";\n\ntype DesktopSidebarStore = {\n isExpanded: boolean;\n _hydrated: boolean;\n toggle: () => void;\n expand: () => void;\n collapse: () => void;\n _hydrate: () => void;\n};\n\nexport const useDesktopSidebarStore = create<DesktopSidebarStore>((set) => ({\n isExpanded: true,\n _hydrated: false,\n toggle: () => set((state) => {\n const next = !state.isExpanded;\n localStorage.setItem(STORAGE_KEY, String(next));\n return { isExpanded: next };\n }),\n expand: () => {\n localStorage.setItem(STORAGE_KEY, \"true\");\n return set({ isExpanded: true });\n },\n collapse: () => {\n localStorage.setItem(STORAGE_KEY, \"false\");\n return set({ isExpanded: false });\n },\n _hydrate: () => {\n const stored = localStorage.getItem(STORAGE_KEY);\n const value = stored === null ? true : stored === \"true\";\n set({ isExpanded: value, _hydrated: true });\n },\n}));\n\nexport function useDesktopSidebarHydration() {\n const hydrate = useDesktopSidebarStore((s) => s._hydrate);\n const hydrated = useDesktopSidebarStore((s) => s._hydrated);\n\n useEffect(() => {\n if (!hydrated) {\n hydrate();\n }\n }, [hydrate, hydrated]);\n}\n"],"mappings":"AAAA,SAAS,cAAc;AACvB,SAAS,iBAAiB;AAE1B,MAAM,cAAc;AAWb,MAAM,yBAAyB,OAA4B,CAAC,SAAS;AAAA,EACxE,YAAY;AAAA,EACZ,WAAW;AAAA,EACX,QAAQ,MAAM,IAAI,CAAC,UAAU;AACzB,UAAM,OAAO,CAAC,MAAM;AACpB,iBAAa,QAAQ,aAAa,OAAO,IAAI,CAAC;AAC9C,WAAO,EAAE,YAAY,KAAK;AAAA,EAC9B,CAAC;AAAA,EACD,QAAQ,MAAM;AACV,iBAAa,QAAQ,aAAa,MAAM;AACxC,WAAO,IAAI,EAAE,YAAY,KAAK,CAAC;AAAA,EACnC;AAAA,EACA,UAAU,MAAM;AACZ,iBAAa,QAAQ,aAAa,OAAO;AACzC,WAAO,IAAI,EAAE,YAAY,MAAM,CAAC;AAAA,EACpC;AAAA,EACA,UAAU,MAAM;AACZ,UAAM,SAAS,aAAa,QAAQ,WAAW;AAC/C,UAAM,QAAQ,WAAW,OAAO,OAAO,WAAW;AAClD,QAAI,EAAE,YAAY,OAAO,WAAW,KAAK,CAAC;AAAA,EAC9C;AACJ,EAAE;AAEK,SAAS,6BAA6B;AACzC,QAAM,UAAU,uBAAuB,CAAC,MAAM,EAAE,QAAQ;AACxD,QAAM,WAAW,uBAAuB,CAAC,MAAM,EAAE,SAAS;AAE1D,YAAU,MAAM;AACZ,QAAI,CAAC,UAAU;AACX,cAAQ;AAAA,IACZ;AAAA,EACJ,GAAG,CAAC,SAAS,QAAQ,CAAC;AAC1B;","names":[]}
|
package/package.json
CHANGED
|
@@ -117,7 +117,7 @@ export function ChangeEmailModal({ open, onClose }: ChangeEmailModalProps) {
|
|
|
117
117
|
</>
|
|
118
118
|
)}
|
|
119
119
|
|
|
120
|
-
<div className={`${showVerification ? 'w-full' : 'w-1/2'} h-0.75 bg-
|
|
120
|
+
<div className={`${showVerification ? 'w-full' : 'w-1/2'} h-0.75 bg-cyan-300`} />
|
|
121
121
|
|
|
122
122
|
{showVerification ? (
|
|
123
123
|
<form
|
|
@@ -134,7 +134,7 @@ export function ChangePhoneModal({ open, onClose }: ChangePhoneModalProps) {
|
|
|
134
134
|
</>
|
|
135
135
|
)}
|
|
136
136
|
|
|
137
|
-
<div className={`${showVerification || !hasExistingPhone ? 'w-full' : 'w-1/2'} h-0.75 bg-
|
|
137
|
+
<div className={`${showVerification || !hasExistingPhone ? 'w-full' : 'w-1/2'} h-0.75 bg-cyan-300`} />
|
|
138
138
|
|
|
139
139
|
{showVerification ? (
|
|
140
140
|
<form
|
|
@@ -5,7 +5,7 @@ import Image from "next/image";
|
|
|
5
5
|
import { IconChevronRight } from "@tabler/icons-react";
|
|
6
6
|
import { Separator } from "../ui/data-display/Separator";
|
|
7
7
|
import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/overlay/Tooltip";
|
|
8
|
-
import { useDesktopSidebarStore } from "../../store/useDesktopSidebarStore";
|
|
8
|
+
import { useDesktopSidebarStore, useDesktopSidebarHydration } from "../../store/useDesktopSidebarStore";
|
|
9
9
|
import { useWhitelabel } from "../../providers/whitelabel.provider";
|
|
10
10
|
import { cn } from "../../infra/utils/clsx";
|
|
11
11
|
|
|
@@ -30,6 +30,7 @@ function NavBar({
|
|
|
30
30
|
}: NavBarProps) {
|
|
31
31
|
const { isExpanded: isDesktopExpanded, toggle: toggleDesktop } =
|
|
32
32
|
useDesktopSidebarStore();
|
|
33
|
+
useDesktopSidebarHydration();
|
|
33
34
|
const { whitelabel } = useWhitelabel();
|
|
34
35
|
const isDefaultWl = !whitelabel || whitelabel.id === 1;
|
|
35
36
|
const primaryColor = whitelabel?.general?.primary_color;
|
|
@@ -13,12 +13,9 @@ import {
|
|
|
13
13
|
Popover,
|
|
14
14
|
PopoverContent,
|
|
15
15
|
PopoverTrigger,
|
|
16
|
-
Tooltip,
|
|
17
|
-
TooltipContent,
|
|
18
|
-
TooltipTrigger,
|
|
19
16
|
UserAvatar,
|
|
20
17
|
} from '../../index';
|
|
21
|
-
import { IconCheck, IconChevronDown, IconFolderOpen, IconPlus
|
|
18
|
+
import { IconCheck, IconChevronDown, IconFolderOpen, IconPlus } from '@tabler/icons-react';
|
|
22
19
|
import type { NavigationProject } from './types';
|
|
23
20
|
|
|
24
21
|
interface ProjectSelectorPopoverProps {
|
|
@@ -96,16 +93,6 @@ export function ProjectSelectorPopover({
|
|
|
96
93
|
Adicionar
|
|
97
94
|
</Button>
|
|
98
95
|
)}
|
|
99
|
-
{onManageProjects && (
|
|
100
|
-
<Tooltip>
|
|
101
|
-
<TooltipTrigger asChild>
|
|
102
|
-
<Button variant="secondary" className="p-0 size-8" onClick={onManageProjects}>
|
|
103
|
-
<IconSettings size={18} />
|
|
104
|
-
</Button>
|
|
105
|
-
</TooltipTrigger>
|
|
106
|
-
<TooltipContent className="z-[1002]">Visualizar todos projetos</TooltipContent>
|
|
107
|
-
</Tooltip>
|
|
108
|
-
)}
|
|
109
96
|
</div>
|
|
110
97
|
)}
|
|
111
98
|
</div>
|
|
@@ -154,6 +141,18 @@ export function ProjectSelectorPopover({
|
|
|
154
141
|
)}
|
|
155
142
|
</CommandList>
|
|
156
143
|
</Command>
|
|
144
|
+
{onManageProjects && (
|
|
145
|
+
<>
|
|
146
|
+
<div className="border-t border-gray-200" />
|
|
147
|
+
<button
|
|
148
|
+
type="button"
|
|
149
|
+
className="paragraph-small-medium text-violet-700 underline cursor-pointer py-1 text-center"
|
|
150
|
+
onClick={onManageProjects}
|
|
151
|
+
>
|
|
152
|
+
Gerenciar projetos
|
|
153
|
+
</button>
|
|
154
|
+
</>
|
|
155
|
+
)}
|
|
157
156
|
</div>
|
|
158
157
|
</PopoverContent>
|
|
159
158
|
</Popover>
|
|
@@ -48,7 +48,7 @@ function NotificationsList({
|
|
|
48
48
|
<NotificationCard
|
|
49
49
|
key={notification.id}
|
|
50
50
|
icon={<IconBell size={20} className="text-pages-600" />}
|
|
51
|
-
iconBgColor="bg-
|
|
51
|
+
iconBgColor="bg-cyan-100"
|
|
52
52
|
title={notification.subject}
|
|
53
53
|
description={notification.message}
|
|
54
54
|
gapPx={8}
|
|
@@ -15,7 +15,7 @@ const buttonVariants = cva(
|
|
|
15
15
|
"bg-white text-gray-950 border-gray-200 hover:border-gray-400 border",
|
|
16
16
|
ghost:
|
|
17
17
|
"text-gray-600 hover:bg-accent hover:text-gray-950 dark:hover:bg-accent/50",
|
|
18
|
-
brand: "bg-
|
|
18
|
+
brand: "bg-cyan-300 hover:bg-cyan-200 text-gray-950",
|
|
19
19
|
},
|
|
20
20
|
size: {
|
|
21
21
|
default: "h-12 px-4 py-2 has-[>svg]:px-3",
|
|
@@ -35,7 +35,7 @@ const toastIconContainerVariants = cva(
|
|
|
35
35
|
success: "bg-green-50 text-green-500",
|
|
36
36
|
error: "bg-red-50 text-red-500",
|
|
37
37
|
warning: "bg-yellow-50 text-yellow-400",
|
|
38
|
-
info: "bg-
|
|
38
|
+
info: "bg-cyan-50 text-pages-500",
|
|
39
39
|
default: "bg-gray-50 text-gray-950",
|
|
40
40
|
},
|
|
41
41
|
},
|
|
@@ -60,7 +60,7 @@ export default function NotificationCard({
|
|
|
60
60
|
{actions && <div className="flex items-center gap-2">{actions}</div>}
|
|
61
61
|
</div>
|
|
62
62
|
|
|
63
|
-
{isUnread && <div className="size-2 bg-
|
|
63
|
+
{isUnread && <div className="size-2 bg-cyan-400 rounded-full shrink-0 mt-1" />}
|
|
64
64
|
</div>
|
|
65
65
|
);
|
|
66
66
|
}
|
|
@@ -1,23 +1,20 @@
|
|
|
1
1
|
import { create } from "zustand";
|
|
2
|
+
import { useEffect } from "react";
|
|
2
3
|
|
|
3
4
|
const STORAGE_KEY = "desktop-sidebar-expanded";
|
|
4
5
|
|
|
5
|
-
function getInitialState(): boolean {
|
|
6
|
-
if (typeof window === "undefined") return true;
|
|
7
|
-
const stored = localStorage.getItem(STORAGE_KEY);
|
|
8
|
-
if (stored === null) return true;
|
|
9
|
-
return stored === "true";
|
|
10
|
-
}
|
|
11
|
-
|
|
12
6
|
type DesktopSidebarStore = {
|
|
13
7
|
isExpanded: boolean;
|
|
8
|
+
_hydrated: boolean;
|
|
14
9
|
toggle: () => void;
|
|
15
10
|
expand: () => void;
|
|
16
11
|
collapse: () => void;
|
|
12
|
+
_hydrate: () => void;
|
|
17
13
|
};
|
|
18
14
|
|
|
19
15
|
export const useDesktopSidebarStore = create<DesktopSidebarStore>((set) => ({
|
|
20
|
-
isExpanded:
|
|
16
|
+
isExpanded: true,
|
|
17
|
+
_hydrated: false,
|
|
21
18
|
toggle: () => set((state) => {
|
|
22
19
|
const next = !state.isExpanded;
|
|
23
20
|
localStorage.setItem(STORAGE_KEY, String(next));
|
|
@@ -31,4 +28,20 @@ export const useDesktopSidebarStore = create<DesktopSidebarStore>((set) => ({
|
|
|
31
28
|
localStorage.setItem(STORAGE_KEY, "false");
|
|
32
29
|
return set({ isExpanded: false });
|
|
33
30
|
},
|
|
31
|
+
_hydrate: () => {
|
|
32
|
+
const stored = localStorage.getItem(STORAGE_KEY);
|
|
33
|
+
const value = stored === null ? true : stored === "true";
|
|
34
|
+
set({ isExpanded: value, _hydrated: true });
|
|
35
|
+
},
|
|
34
36
|
}));
|
|
37
|
+
|
|
38
|
+
export function useDesktopSidebarHydration() {
|
|
39
|
+
const hydrate = useDesktopSidebarStore((s) => s._hydrate);
|
|
40
|
+
const hydrated = useDesktopSidebarStore((s) => s._hydrated);
|
|
41
|
+
|
|
42
|
+
useEffect(() => {
|
|
43
|
+
if (!hydrated) {
|
|
44
|
+
hydrate();
|
|
45
|
+
}
|
|
46
|
+
}, [hydrate, hydrated]);
|
|
47
|
+
}
|