@greatapps/common 1.1.188 → 1.1.191

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.
@@ -0,0 +1,64 @@
1
+ "use client";
2
+ import { useEffect, useRef } from "react";
3
+ import { useAuth } from "../../providers/auth.provider";
4
+ import { useWhitelabel } from "../../providers/whitelabel.provider";
5
+ import { useActiveSubscription } from "../../modules/subscriptions/hooks/find-active-subscription.hook";
6
+ const V4_WHITELABEL_ID = 367568;
7
+ const CRISP_WEBSITE_ID = "3339a3ec-b4c6-4aac-8b86-45668fb7655c";
8
+ const CRISP_SCRIPT_URL = "https://client.crisp.chat/l.js";
9
+ const CRISP_LOAD_DELAY = 800;
10
+ function openCrispHelpdesk() {
11
+ if (typeof window !== "undefined" && window.$crisp) {
12
+ window.$crisp.push(["do", "helpdesk:search"]);
13
+ }
14
+ }
15
+ function CrispEmbed() {
16
+ const { user, account } = useAuth();
17
+ const { whitelabel } = useWhitelabel();
18
+ const { data: subscriptionData } = useActiveSubscription();
19
+ const scriptLoadedRef = useRef(false);
20
+ const subscription = subscriptionData?.data?.[0] ?? null;
21
+ const isV4 = whitelabel?.id === V4_WHITELABEL_ID;
22
+ useEffect(() => {
23
+ if (!user || scriptLoadedRef.current) return;
24
+ const win = window;
25
+ win.$crisp = [];
26
+ win.CRISP_WEBSITE_ID = CRISP_WEBSITE_ID;
27
+ const timeout = setTimeout(() => {
28
+ if (document.querySelector(`script[src="${CRISP_SCRIPT_URL}"]`)) return;
29
+ const s = document.createElement("script");
30
+ s.src = CRISP_SCRIPT_URL;
31
+ s.async = true;
32
+ document.head.appendChild(s);
33
+ scriptLoadedRef.current = true;
34
+ }, CRISP_LOAD_DELAY);
35
+ return () => clearTimeout(timeout);
36
+ }, [user]);
37
+ useEffect(() => {
38
+ const $crisp = window.$crisp;
39
+ if (!user || !$crisp) return;
40
+ $crisp.push(["set", "user:email", user.email]);
41
+ $crisp.push(["set", "user:nickname", `${user.name} ${user.last_name}`.trim()]);
42
+ $crisp.push(["set", "user:company", account?.name ?? ""]);
43
+ $crisp.push(["set", "user:phone", `${user.ddi}${user.phone}`]);
44
+ if (user.photo) {
45
+ $crisp.push(["set", "user:avatar", user.photo]);
46
+ }
47
+ if (isV4) {
48
+ $crisp.push(["set", "session:segments", [["company_v4"]]]);
49
+ $crisp.push(["set", "session:data", [[["Company", "V4"]]]]);
50
+ } else {
51
+ const planName = subscription?.plan_name ?? "";
52
+ $crisp.push(["set", "session:segments", [[`plano_${planName}`]]]);
53
+ $crisp.push(["set", "session:segments", [[`usuario_${user.profile}`]]]);
54
+ $crisp.push(["set", "session:data", [[["Plano", planName]]]]);
55
+ $crisp.push(["set", "session:data", [[["Usuario", user.profile]]]]);
56
+ }
57
+ }, [user, account, isV4, subscription?.plan_name]);
58
+ return null;
59
+ }
60
+ export {
61
+ CrispEmbed,
62
+ openCrispHelpdesk
63
+ };
64
+ //# sourceMappingURL=CrispEmbed.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/embeds/CrispEmbed.tsx"],"sourcesContent":["'use client';\n\nimport { useEffect, useRef } from 'react';\nimport { useAuth } from '../../providers/auth.provider';\nimport { useWhitelabel } from '../../providers/whitelabel.provider';\nimport { useActiveSubscription } from '../../modules/subscriptions/hooks/find-active-subscription.hook';\n\nconst V4_WHITELABEL_ID = 367568;\n\nconst CRISP_WEBSITE_ID = '3339a3ec-b4c6-4aac-8b86-45668fb7655c';\nconst CRISP_SCRIPT_URL = 'https://client.crisp.chat/l.js';\nconst CRISP_LOAD_DELAY = 800;\n\nexport function openCrispHelpdesk() {\n if (typeof window !== 'undefined' && (window as any).$crisp) {\n (window as any).$crisp.push(['do', 'helpdesk:search']);\n }\n}\n\nexport function CrispEmbed() {\n const { user, account } = useAuth();\n const { whitelabel } = useWhitelabel();\n const { data: subscriptionData } = useActiveSubscription();\n const scriptLoadedRef = useRef(false);\n\n const subscription = subscriptionData?.data?.[0] ?? null;\n const isV4 = whitelabel?.id === V4_WHITELABEL_ID;\n\n // Load Crisp script (once, with 800ms delay)\n useEffect(() => {\n if (!user || scriptLoadedRef.current) return;\n\n const win = window as any;\n win.$crisp = [];\n win.CRISP_WEBSITE_ID = CRISP_WEBSITE_ID;\n\n const timeout = setTimeout(() => {\n if (document.querySelector(`script[src=\"${CRISP_SCRIPT_URL}\"]`)) return;\n const s = document.createElement('script');\n s.src = CRISP_SCRIPT_URL;\n s.async = true;\n document.head.appendChild(s);\n scriptLoadedRef.current = true;\n }, CRISP_LOAD_DELAY);\n\n return () => clearTimeout(timeout);\n }, [user]);\n\n // Identify user\n useEffect(() => {\n const $crisp = (window as any).$crisp;\n if (!user || !$crisp) return;\n\n $crisp.push(['set', 'user:email', user.email]);\n $crisp.push(['set', 'user:nickname', `${user.name} ${user.last_name}`.trim()]);\n $crisp.push(['set', 'user:company', account?.name ?? '']);\n $crisp.push(['set', 'user:phone', `${user.ddi}${user.phone}`]);\n\n if (user.photo) {\n $crisp.push(['set', 'user:avatar', user.photo]);\n }\n\n if (isV4) {\n $crisp.push(['set', 'session:segments', [['company_v4']]]);\n $crisp.push(['set', 'session:data', [[['Company', 'V4']]]]);\n } else {\n const planName = subscription?.plan_name ?? '';\n $crisp.push(['set', 'session:segments', [[`plano_${planName}`]]]);\n $crisp.push(['set', 'session:segments', [[`usuario_${user.profile}`]]]);\n $crisp.push(['set', 'session:data', [[['Plano', planName]]]]);\n $crisp.push(['set', 'session:data', [[['Usuario', user.profile]]]]);\n }\n }, [user, account, isV4, subscription?.plan_name]);\n\n return null;\n}\n"],"mappings":";AAEA,SAAS,WAAW,cAAc;AAClC,SAAS,eAAe;AACxB,SAAS,qBAAqB;AAC9B,SAAS,6BAA6B;AAEtC,MAAM,mBAAmB;AAEzB,MAAM,mBAAmB;AACzB,MAAM,mBAAmB;AACzB,MAAM,mBAAmB;AAElB,SAAS,oBAAoB;AAClC,MAAI,OAAO,WAAW,eAAgB,OAAe,QAAQ;AAC3D,IAAC,OAAe,OAAO,KAAK,CAAC,MAAM,iBAAiB,CAAC;AAAA,EACvD;AACF;AAEO,SAAS,aAAa;AAC3B,QAAM,EAAE,MAAM,QAAQ,IAAI,QAAQ;AAClC,QAAM,EAAE,WAAW,IAAI,cAAc;AACrC,QAAM,EAAE,MAAM,iBAAiB,IAAI,sBAAsB;AACzD,QAAM,kBAAkB,OAAO,KAAK;AAEpC,QAAM,eAAe,kBAAkB,OAAO,CAAC,KAAK;AACpD,QAAM,OAAO,YAAY,OAAO;AAGhC,YAAU,MAAM;AACd,QAAI,CAAC,QAAQ,gBAAgB,QAAS;AAEtC,UAAM,MAAM;AACZ,QAAI,SAAS,CAAC;AACd,QAAI,mBAAmB;AAEvB,UAAM,UAAU,WAAW,MAAM;AAC/B,UAAI,SAAS,cAAc,eAAe,gBAAgB,IAAI,EAAG;AACjE,YAAM,IAAI,SAAS,cAAc,QAAQ;AACzC,QAAE,MAAM;AACR,QAAE,QAAQ;AACV,eAAS,KAAK,YAAY,CAAC;AAC3B,sBAAgB,UAAU;AAAA,IAC5B,GAAG,gBAAgB;AAEnB,WAAO,MAAM,aAAa,OAAO;AAAA,EACnC,GAAG,CAAC,IAAI,CAAC;AAGT,YAAU,MAAM;AACd,UAAM,SAAU,OAAe;AAC/B,QAAI,CAAC,QAAQ,CAAC,OAAQ;AAEtB,WAAO,KAAK,CAAC,OAAO,cAAc,KAAK,KAAK,CAAC;AAC7C,WAAO,KAAK,CAAC,OAAO,iBAAiB,GAAG,KAAK,IAAI,IAAI,KAAK,SAAS,GAAG,KAAK,CAAC,CAAC;AAC7E,WAAO,KAAK,CAAC,OAAO,gBAAgB,SAAS,QAAQ,EAAE,CAAC;AACxD,WAAO,KAAK,CAAC,OAAO,cAAc,GAAG,KAAK,GAAG,GAAG,KAAK,KAAK,EAAE,CAAC;AAE7D,QAAI,KAAK,OAAO;AACd,aAAO,KAAK,CAAC,OAAO,eAAe,KAAK,KAAK,CAAC;AAAA,IAChD;AAEA,QAAI,MAAM;AACR,aAAO,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC;AACzD,aAAO,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,CAAC,CAAC;AAAA,IAC5D,OAAO;AACL,YAAM,WAAW,cAAc,aAAa;AAC5C,aAAO,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,CAAC,CAAC;AAChE,aAAO,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC,WAAW,KAAK,OAAO,EAAE,CAAC,CAAC,CAAC;AACtE,aAAO,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC,CAAC,SAAS,QAAQ,CAAC,CAAC,CAAC,CAAC;AAC5D,aAAO,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC,CAAC,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;AAAA,IACpE;AAAA,EACF,GAAG,CAAC,MAAM,SAAS,MAAM,cAAc,SAAS,CAAC;AAEjD,SAAO;AACT;","names":[]}
@@ -0,0 +1,97 @@
1
+ "use client";
2
+ import { useEffect, useRef } from "react";
3
+ import { usePathname } from "next/navigation";
4
+ import { useAuth } from "../../providers/auth.provider";
5
+ import { useWhitelabel } from "../../providers/whitelabel.provider";
6
+ import { useActiveSubscription } from "../../modules/subscriptions/hooks/find-active-subscription.hook";
7
+ const V4_WHITELABEL_ID = 367568;
8
+ const FRILL_SCRIPT_URL = "https://widget.frill.co/v2/container.js";
9
+ const FRILL_KEY = "2f77f232-a120-438e-8ef6-01912ffd1b99";
10
+ const EXCLUDED_ROUTES = [
11
+ "/login",
12
+ "/forgot-password",
13
+ "/register"
14
+ ];
15
+ const SURVEYS = [{ key: "7f59dbf6-b665-458a-80e2-778de47efe1c" }];
16
+ const WIDGETS = [
17
+ { key: "4a5ba13b-1150-49fe-aa15-f9a2da0ba909" },
18
+ { key: "720c0912-e6a4-495c-835e-3ff1f59d6dfc" }
19
+ ];
20
+ function initFrillLoader() {
21
+ const win = window;
22
+ if (win.Frill) return;
23
+ let counter = 0;
24
+ const queue = {};
25
+ win.Frill = function(action, params) {
26
+ let instance;
27
+ const id = counter++;
28
+ const promise = new Promise((resolve, reject) => {
29
+ queue[id] = {
30
+ params: [action, params],
31
+ resolve: (f) => {
32
+ instance = f;
33
+ resolve(f);
34
+ },
35
+ reject
36
+ };
37
+ });
38
+ promise.destroy = () => {
39
+ delete queue[id];
40
+ instance?.destroy();
41
+ };
42
+ return promise;
43
+ };
44
+ win.Frill.q = queue;
45
+ }
46
+ function loadFrillScript() {
47
+ if (document.querySelector(`script[src="${FRILL_SCRIPT_URL}"]`)) return;
48
+ const anchor = document.getElementsByTagName("script")[0];
49
+ const script = document.createElement("script");
50
+ script.type = "text/javascript";
51
+ script.async = true;
52
+ script.src = FRILL_SCRIPT_URL;
53
+ anchor?.parentNode?.insertBefore(script, anchor);
54
+ }
55
+ function FrillEmbed() {
56
+ const pathname = usePathname();
57
+ const { user } = useAuth();
58
+ const { whitelabel } = useWhitelabel();
59
+ const { data: subscriptionData } = useActiveSubscription();
60
+ const containerRef = useRef(null);
61
+ const subscription = subscriptionData?.data?.[0] ?? null;
62
+ const isExcluded = EXCLUDED_ROUTES.some((route) => pathname.startsWith(route));
63
+ const isV4 = whitelabel?.id === V4_WHITELABEL_ID;
64
+ useEffect(() => {
65
+ if (isExcluded || !user) return;
66
+ initFrillLoader();
67
+ if (document.readyState === "complete" || document.readyState === "interactive") {
68
+ loadFrillScript();
69
+ } else {
70
+ document.addEventListener("DOMContentLoaded", loadFrillScript);
71
+ }
72
+ const userData = {
73
+ id: String(user.id),
74
+ email: user.email,
75
+ name: `${user.name} ${user.last_name}`.trim(),
76
+ attributes: isV4 ? { company: "V4" } : { profile: user.profile, plan: subscription?.plan_name ?? "" }
77
+ };
78
+ const config = { key: FRILL_KEY, user: userData };
79
+ if (!isV4) {
80
+ config.surveys = SURVEYS;
81
+ config.widgets = WIDGETS;
82
+ }
83
+ const win = window;
84
+ containerRef.current = win.Frill("container", config);
85
+ win.Frill("identify", userData);
86
+ return () => {
87
+ containerRef.current?.destroy();
88
+ containerRef.current = null;
89
+ document.removeEventListener("DOMContentLoaded", loadFrillScript);
90
+ };
91
+ }, [user, isExcluded, isV4, subscription?.plan_name]);
92
+ return null;
93
+ }
94
+ export {
95
+ FrillEmbed
96
+ };
97
+ //# sourceMappingURL=FrillEmbed.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/embeds/FrillEmbed.tsx"],"sourcesContent":["'use client';\n\nimport { useEffect, useRef } from 'react';\nimport { usePathname } from 'next/navigation';\nimport { useAuth } from '../../providers/auth.provider';\nimport { useWhitelabel } from '../../providers/whitelabel.provider';\nimport { useActiveSubscription } from '../../modules/subscriptions/hooks/find-active-subscription.hook';\n\nconst V4_WHITELABEL_ID = 367568;\n\nconst FRILL_SCRIPT_URL = 'https://widget.frill.co/v2/container.js';\nconst FRILL_KEY = '2f77f232-a120-438e-8ef6-01912ffd1b99';\n\nconst EXCLUDED_ROUTES = [\n '/login',\n '/forgot-password',\n '/register',\n];\n\nconst SURVEYS = [{ key: '7f59dbf6-b665-458a-80e2-778de47efe1c' }];\nconst WIDGETS = [\n { key: '4a5ba13b-1150-49fe-aa15-f9a2da0ba909' },\n { key: '720c0912-e6a4-495c-835e-3ff1f59d6dfc' },\n];\n\nfunction initFrillLoader() {\n const win = window as any;\n if (win.Frill) return;\n\n let counter = 0;\n const queue: Record<number, any> = {};\n\n win.Frill = function (action: string, params: any) {\n let instance: any;\n const id = counter++;\n const promise: any = new Promise((resolve, reject) => {\n queue[id] = {\n params: [action, params],\n resolve: (f: any) => {\n instance = f;\n resolve(f);\n },\n reject,\n };\n });\n promise.destroy = () => {\n delete queue[id];\n instance?.destroy();\n };\n return promise;\n };\n win.Frill.q = queue;\n}\n\nfunction loadFrillScript() {\n if (document.querySelector(`script[src=\"${FRILL_SCRIPT_URL}\"]`)) return;\n const anchor = document.getElementsByTagName('script')[0];\n const script = document.createElement('script');\n script.type = 'text/javascript';\n script.async = true;\n script.src = FRILL_SCRIPT_URL;\n anchor?.parentNode?.insertBefore(script, anchor);\n}\n\nexport function FrillEmbed() {\n const pathname = usePathname();\n const { user } = useAuth();\n const { whitelabel } = useWhitelabel();\n const { data: subscriptionData } = useActiveSubscription();\n const containerRef = useRef<any>(null);\n\n const subscription = subscriptionData?.data?.[0] ?? null;\n const isExcluded = EXCLUDED_ROUTES.some((route) => pathname.startsWith(route));\n const isV4 = whitelabel?.id === V4_WHITELABEL_ID;\n\n useEffect(() => {\n if (isExcluded || !user) return;\n\n initFrillLoader();\n\n if (document.readyState === 'complete' || document.readyState === 'interactive') {\n loadFrillScript();\n } else {\n document.addEventListener('DOMContentLoaded', loadFrillScript);\n }\n\n const userData = {\n id: String(user.id),\n email: user.email,\n name: `${user.name} ${user.last_name}`.trim(),\n attributes: isV4\n ? { company: 'V4' }\n : { profile: user.profile, plan: subscription?.plan_name ?? '' },\n };\n\n const config: Record<string, any> = { key: FRILL_KEY, user: userData };\n if (!isV4) {\n config.surveys = SURVEYS;\n config.widgets = WIDGETS;\n }\n\n const win = window as any;\n containerRef.current = win.Frill('container', config);\n win.Frill('identify', userData);\n\n return () => {\n containerRef.current?.destroy();\n containerRef.current = null;\n document.removeEventListener('DOMContentLoaded', loadFrillScript);\n };\n }, [user, isExcluded, isV4, subscription?.plan_name]);\n\n return null;\n}\n"],"mappings":";AAEA,SAAS,WAAW,cAAc;AAClC,SAAS,mBAAmB;AAC5B,SAAS,eAAe;AACxB,SAAS,qBAAqB;AAC9B,SAAS,6BAA6B;AAEtC,MAAM,mBAAmB;AAEzB,MAAM,mBAAmB;AACzB,MAAM,YAAY;AAElB,MAAM,kBAAkB;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AACF;AAEA,MAAM,UAAU,CAAC,EAAE,KAAK,uCAAuC,CAAC;AAChE,MAAM,UAAU;AAAA,EACd,EAAE,KAAK,uCAAuC;AAAA,EAC9C,EAAE,KAAK,uCAAuC;AAChD;AAEA,SAAS,kBAAkB;AACzB,QAAM,MAAM;AACZ,MAAI,IAAI,MAAO;AAEf,MAAI,UAAU;AACd,QAAM,QAA6B,CAAC;AAEpC,MAAI,QAAQ,SAAU,QAAgB,QAAa;AACjD,QAAI;AACJ,UAAM,KAAK;AACX,UAAM,UAAe,IAAI,QAAQ,CAAC,SAAS,WAAW;AACpD,YAAM,EAAE,IAAI;AAAA,QACV,QAAQ,CAAC,QAAQ,MAAM;AAAA,QACvB,SAAS,CAAC,MAAW;AACnB,qBAAW;AACX,kBAAQ,CAAC;AAAA,QACX;AAAA,QACA;AAAA,MACF;AAAA,IACF,CAAC;AACD,YAAQ,UAAU,MAAM;AACtB,aAAO,MAAM,EAAE;AACf,gBAAU,QAAQ;AAAA,IACpB;AACA,WAAO;AAAA,EACT;AACA,MAAI,MAAM,IAAI;AAChB;AAEA,SAAS,kBAAkB;AACzB,MAAI,SAAS,cAAc,eAAe,gBAAgB,IAAI,EAAG;AACjE,QAAM,SAAS,SAAS,qBAAqB,QAAQ,EAAE,CAAC;AACxD,QAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,SAAO,OAAO;AACd,SAAO,QAAQ;AACf,SAAO,MAAM;AACb,UAAQ,YAAY,aAAa,QAAQ,MAAM;AACjD;AAEO,SAAS,aAAa;AAC3B,QAAM,WAAW,YAAY;AAC7B,QAAM,EAAE,KAAK,IAAI,QAAQ;AACzB,QAAM,EAAE,WAAW,IAAI,cAAc;AACrC,QAAM,EAAE,MAAM,iBAAiB,IAAI,sBAAsB;AACzD,QAAM,eAAe,OAAY,IAAI;AAErC,QAAM,eAAe,kBAAkB,OAAO,CAAC,KAAK;AACpD,QAAM,aAAa,gBAAgB,KAAK,CAAC,UAAU,SAAS,WAAW,KAAK,CAAC;AAC7E,QAAM,OAAO,YAAY,OAAO;AAEhC,YAAU,MAAM;AACd,QAAI,cAAc,CAAC,KAAM;AAEzB,oBAAgB;AAEhB,QAAI,SAAS,eAAe,cAAc,SAAS,eAAe,eAAe;AAC/E,sBAAgB;AAAA,IAClB,OAAO;AACL,eAAS,iBAAiB,oBAAoB,eAAe;AAAA,IAC/D;AAEA,UAAM,WAAW;AAAA,MACf,IAAI,OAAO,KAAK,EAAE;AAAA,MAClB,OAAO,KAAK;AAAA,MACZ,MAAM,GAAG,KAAK,IAAI,IAAI,KAAK,SAAS,GAAG,KAAK;AAAA,MAC5C,YAAY,OACR,EAAE,SAAS,KAAK,IAChB,EAAE,SAAS,KAAK,SAAS,MAAM,cAAc,aAAa,GAAG;AAAA,IACnE;AAEA,UAAM,SAA8B,EAAE,KAAK,WAAW,MAAM,SAAS;AACrE,QAAI,CAAC,MAAM;AACT,aAAO,UAAU;AACjB,aAAO,UAAU;AAAA,IACnB;AAEA,UAAM,MAAM;AACZ,iBAAa,UAAU,IAAI,MAAM,aAAa,MAAM;AACpD,QAAI,MAAM,YAAY,QAAQ;AAE9B,WAAO,MAAM;AACX,mBAAa,SAAS,QAAQ;AAC9B,mBAAa,UAAU;AACvB,eAAS,oBAAoB,oBAAoB,eAAe;AAAA,IAClE;AAAA,EACF,GAAG,CAAC,MAAM,YAAY,MAAM,cAAc,SAAS,CAAC;AAEpD,SAAO;AACT;","names":[]}
@@ -3,7 +3,6 @@ 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
5
  import { UserAvatar } from "../ui/data-display/UserAvatar";
6
- import { useQueryClient, useMutation } from "@tanstack/react-query";
7
6
  import { Popover, PopoverContent, PopoverTrigger } from "../ui/overlay/Popover";
8
7
  import { Button } from "../ui/buttons/Button";
9
8
  import {
@@ -16,16 +15,10 @@ import {
16
15
  import { Checkbox } from "../ui/form/Checkbox";
17
16
  import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/overlay/Tooltip";
18
17
  import { cn } from "../../infra/utils/clsx";
19
- import {
20
- useListProjectUsers,
21
- LIST_PROJECT_USERS_BASE_KEY
22
- } from "../../modules/projects/hooks/list-project-users.hook";
23
- import {
24
- useListAllAccountUsers,
25
- LIST_ALL_ACCOUNT_USERS_BASE_KEY
26
- } from "../../modules/projects/hooks/list-all-account-users.hook";
27
- import { removeProjectUserAction } from "../../modules/projects/actions/remove-project-user.action";
28
- import { addProjectUserAction } from "../../modules/projects/actions/add-project-user.action";
18
+ import { useListProjectUsers } from "../../modules/projects/hooks/list-project-users.hook";
19
+ import { useListAllAccountUsers } from "../../modules/projects/hooks/list-all-account-users.hook";
20
+ import { useAddProjectUser } from "../../modules/projects/hooks/add-project-user.hook";
21
+ import { useRemoveProjectUser } from "../../modules/projects/hooks/remove-project-user.hook";
29
22
  function UserItemSkeleton() {
30
23
  return /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-2 py-1.5 gap-2", children: [
31
24
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 flex-1", children: [
@@ -42,7 +35,6 @@ function UsersSelectorPopover({
42
35
  align,
43
36
  contentClassName
44
37
  }) {
45
- const queryClient = useQueryClient();
46
38
  const [open, setOpen] = useState(false);
47
39
  const [hoveredId, setHoveredId] = useState(null);
48
40
  const [searchInput, setSearchInput] = useState("");
@@ -54,22 +46,12 @@ function UsersSelectorPopover({
54
46
  }, [searchInput]);
55
47
  const accountUsers = useListAllAccountUsers(search, id || void 0);
56
48
  const projectUsers = useListProjectUsers(id, "");
49
+ const addMutation = useAddProjectUser(id);
50
+ const removeMutation = useRemoveProjectUser(id);
57
51
  const allUsers = accountUsers.data?.pages.flatMap((p) => p.data) ?? [];
58
52
  const isLoading = accountUsers.isLoading;
59
53
  const isFetchingMore = accountUsers.isFetchingNextPage;
60
54
  const totalInProject = projectUsers.data?.pages[0]?.total ?? 0;
61
- const invalidate = () => {
62
- queryClient.invalidateQueries({ queryKey: LIST_PROJECT_USERS_BASE_KEY(id) });
63
- queryClient.invalidateQueries({ queryKey: LIST_ALL_ACCOUNT_USERS_BASE_KEY() });
64
- };
65
- const removeMutation = useMutation({
66
- mutationFn: (userId) => removeProjectUserAction({ projectId: id, users: [userId] }),
67
- onSuccess: invalidate
68
- });
69
- const addMutation = useMutation({
70
- mutationFn: (userId) => addProjectUserAction({ projectId: id, users: [userId] }),
71
- onSuccess: invalidate
72
- });
73
55
  const toggleUser = (userId, inProject, removable) => {
74
56
  if (inProject) {
75
57
  if (!removable) return;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/layouts/UsersSelectorPopover.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport { Plus, Settings, User, Users } from \"lucide-react\";\nimport { UserAvatar } from \"../ui/data-display/UserAvatar\";\nimport { useQueryClient, useMutation } from \"@tanstack/react-query\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"../ui/overlay/Popover\";\nimport { Button } from \"../ui/buttons/Button\";\nimport {\n Command,\n CommandEmpty,\n CommandInput,\n CommandItem,\n CommandList,\n} from \"../ui/overlay/Command\";\nimport { Checkbox } from \"../ui/form/Checkbox\";\nimport { Tooltip, TooltipContent, TooltipTrigger } from \"../ui/overlay/Tooltip\";\nimport { cn } from \"../../infra/utils/clsx\";\nimport {\n useListProjectUsers,\n LIST_PROJECT_USERS_BASE_KEY,\n} from \"../../modules/projects/hooks/list-project-users.hook\";\nimport {\n useListAllAccountUsers,\n LIST_ALL_ACCOUNT_USERS_BASE_KEY,\n} from \"../../modules/projects/hooks/list-all-account-users.hook\";\nimport { removeProjectUserAction } from \"../../modules/projects/actions/remove-project-user.action\";\nimport { addProjectUserAction } from \"../../modules/projects/actions/add-project-user.action\";\n\nexport interface UsersSelectorPopoverProps {\n projectId?: number;\n side?: \"top\" | \"bottom\" | \"left\" | \"right\";\n align?: \"start\" | \"center\" | \"end\";\n contentClassName?: string;\n}\n\nfunction UserItemSkeleton() {\n return (\n <div className=\"flex items-center justify-between px-2 py-1.5 gap-2\">\n <div className=\"flex items-center gap-2 flex-1\">\n <div className=\"skeleton size-8 rounded-full shrink-0\" />\n <div className=\"skeleton h-3.5 w-28 rounded\" />\n </div>\n <div className=\"skeleton size-4 rounded shrink-0\" />\n </div>\n );\n}\n\nconst GAPPS_URL = process.env.NEXT_PUBLIC_GREAT_APPS ?? \"\";\n\nexport function UsersSelectorPopover({\n projectId,\n side,\n align,\n contentClassName,\n}: UsersSelectorPopoverProps) {\n const queryClient = useQueryClient();\n const [open, setOpen] = useState(false);\n const [hoveredId, setHoveredId] = useState<number | null>(null);\n const [searchInput, setSearchInput] = useState(\"\");\n const [search, setSearch] = useState(\"\");\n\n const id = projectId ?? 0;\n\n useEffect(() => {\n const timer = setTimeout(() => setSearch(searchInput), 300);\n return () => clearTimeout(timer);\n }, [searchInput]);\n\n const accountUsers = useListAllAccountUsers(search, id || undefined);\n const projectUsers = useListProjectUsers(id, \"\");\n\n const allUsers = accountUsers.data?.pages.flatMap((p) => p.data) ?? [];\n const isLoading = accountUsers.isLoading;\n const isFetchingMore = accountUsers.isFetchingNextPage;\n const totalInProject = projectUsers.data?.pages[0]?.total ?? 0;\n\n const invalidate = () => {\n queryClient.invalidateQueries({ queryKey: LIST_PROJECT_USERS_BASE_KEY(id) });\n queryClient.invalidateQueries({ queryKey: LIST_ALL_ACCOUNT_USERS_BASE_KEY() });\n };\n\n const removeMutation = useMutation({\n mutationFn: (userId: number) =>\n removeProjectUserAction({ projectId: id, users: [userId] }),\n onSuccess: invalidate,\n });\n\n const addMutation = useMutation({\n mutationFn: (userId: number) =>\n addProjectUserAction({ projectId: id, users: [userId] }),\n onSuccess: invalidate,\n });\n\n const toggleUser = (userId: number, inProject: boolean, removable: boolean) => {\n if (inProject) {\n if (!removable) return;\n removeMutation.mutate(userId);\n } else {\n addMutation.mutate(userId);\n }\n };\n\n const handleScroll = (e: React.UIEvent<HTMLDivElement>) => {\n const target = e.currentTarget;\n const nearBottom =\n target.scrollTop + target.clientHeight >= target.scrollHeight - 50;\n if (!nearBottom) return;\n if (accountUsers.hasNextPage && !accountUsers.isFetchingNextPage) {\n accountUsers.fetchNextPage();\n }\n };\n\n return (\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger className=\"cursor-pointer\">\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\">\n <span className=\"paragraph-small-semibold\">{totalInProject}</span>\n <User size={16} />\n </div>\n </PopoverTrigger>\n\n <PopoverContent\n className={cn(\n \"absolute right-[-88px] w-[273px] p-0 bg-white rounded-2xl shadow-md border border-gray-200\",\n contentClassName,\n )}\n side={side}\n align={align}\n sideOffset={8}\n >\n <div className=\"flex flex-col p-3 gap-2\">\n <div className=\"flex items-center justify-between\">\n <span className=\"paragraph-small-semibold\">Usuários</span>\n <div className=\"flex items-center gap-1.5\">\n <Button\n variant=\"secondary\"\n className=\"h-8 paragraph-small-semibold text-gray-950\"\n onClick={() => {\n window.location.href = `${GAPPS_URL}/my-teams?createNew=true`;\n }}\n >\n <Plus size={16} />\n Adicionar\n </Button>\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n variant=\"secondary\"\n className=\"p-0 size-8\"\n onClick={() => {\n window.location.href = `${GAPPS_URL}/my-teams`;\n }}\n >\n <Settings size={18} />\n </Button>\n </TooltipTrigger>\n <TooltipContent className=\"z-[1002]\">\n Visualizar todos usuários\n </TooltipContent>\n </Tooltip>\n </div>\n </div>\n\n <Command shouldFilter={false} className=\"gap-2\" value=\"\">\n <CommandInput\n placeholder=\"Busque aqui\"\n value={searchInput}\n onValueChange={setSearchInput}\n />\n <CommandList\n className=\"custom-scrollbar paragraph-small-medium text-gray-600 h-[162px]\"\n onScroll={handleScroll}\n >\n {isLoading ? (\n <>\n <UserItemSkeleton />\n <UserItemSkeleton />\n <UserItemSkeleton />\n </>\n ) : allUsers.length === 0 ? (\n <div className=\"flex flex-col items-center justify-center gap-2 h-full text-gray-400 py-4\">\n <Users size={28} className=\"text-gray-300\" />\n <span className=\"paragraph-small-medium text-center text-gray-500\">\n Nenhum usuário encontrado.\n </span>\n </div>\n ) : (\n <>\n <CommandEmpty>Nenhum resultado encontrado.</CommandEmpty>\n {allUsers.map((user) => {\n const inProject = user.in_project ?? false;\n const removable =\n inProject &&\n user.profile !== \"owner\" &&\n user.profile !== \"admin\";\n const interactive = !inProject || removable;\n\n return (\n <CommandItem\n key={user.id}\n value={user.name || String(user.id)}\n autoFocus={false}\n onPointerEnter={() => setHoveredId(user.id)}\n onPointerLeave={() => setHoveredId(null)}\n onFocus={() => setHoveredId(user.id)}\n onBlur={() => setHoveredId(null)}\n onSelect={() => toggleUser(user.id, inProject, removable)}\n className={interactive ? \"cursor-pointer\" : \"cursor-default\"}\n >\n <div className=\"flex items-center justify-between w-full\">\n <div className=\"flex items-center gap-2 min-w-0\">\n <UserAvatar\n photo={user.photo}\n name={user.name ?? undefined}\n size={32}\n />\n <span className=\"truncate\">{user.name}</span>\n </div>\n <Tooltip open={interactive && hoveredId === user.id}>\n <TooltipTrigger\n onClick={(e) => e.stopPropagation()}\n onPointerDown={(e) => e.stopPropagation()}\n >\n <Checkbox\n checked={inProject}\n disabled={!interactive}\n onCheckedChange={() =>\n toggleUser(user.id, inProject, removable)\n }\n className={cn(\n interactive && hoveredId === user.id\n ? \"border-gray-950\"\n : \"\",\n \"disabled:opacity-10\",\n )}\n />\n </TooltipTrigger>\n <TooltipContent className=\"z-[1002]\">\n {inProject ? \"Remover do projeto\" : \"Adicionar ao projeto\"}\n </TooltipContent>\n </Tooltip>\n </div>\n </CommandItem>\n );\n })}\n {isFetchingMore && (\n <>\n <UserItemSkeleton />\n <UserItemSkeleton />\n </>\n )}\n </>\n )}\n </CommandList>\n </Command>\n </div>\n </PopoverContent>\n </Popover>\n );\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/components/layouts/UsersSelectorPopover.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport { Plus, Settings, User, Users } from \"lucide-react\";\nimport { UserAvatar } from \"../ui/data-display/UserAvatar\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"../ui/overlay/Popover\";\nimport { Button } from \"../ui/buttons/Button\";\nimport {\n Command,\n CommandEmpty,\n CommandInput,\n CommandItem,\n CommandList,\n} from \"../ui/overlay/Command\";\nimport { Checkbox } from \"../ui/form/Checkbox\";\nimport { Tooltip, TooltipContent, TooltipTrigger } from \"../ui/overlay/Tooltip\";\nimport { cn } from \"../../infra/utils/clsx\";\nimport { useListProjectUsers } from \"../../modules/projects/hooks/list-project-users.hook\";\nimport { useListAllAccountUsers } from \"../../modules/projects/hooks/list-all-account-users.hook\";\nimport { useAddProjectUser } from \"../../modules/projects/hooks/add-project-user.hook\";\nimport { useRemoveProjectUser } from \"../../modules/projects/hooks/remove-project-user.hook\";\n\nexport interface UsersSelectorPopoverProps {\n projectId?: number;\n side?: \"top\" | \"bottom\" | \"left\" | \"right\";\n align?: \"start\" | \"center\" | \"end\";\n contentClassName?: string;\n}\n\nfunction UserItemSkeleton() {\n return (\n <div className=\"flex items-center justify-between px-2 py-1.5 gap-2\">\n <div className=\"flex items-center gap-2 flex-1\">\n <div className=\"skeleton size-8 rounded-full shrink-0\" />\n <div className=\"skeleton h-3.5 w-28 rounded\" />\n </div>\n <div className=\"skeleton size-4 rounded shrink-0\" />\n </div>\n );\n}\n\nconst GAPPS_URL = process.env.NEXT_PUBLIC_GREAT_APPS ?? \"\";\n\nexport function UsersSelectorPopover({\n projectId,\n side,\n align,\n contentClassName,\n}: UsersSelectorPopoverProps) {\n const [open, setOpen] = useState(false);\n const [hoveredId, setHoveredId] = useState<number | null>(null);\n const [searchInput, setSearchInput] = useState(\"\");\n const [search, setSearch] = useState(\"\");\n\n const id = projectId ?? 0;\n\n useEffect(() => {\n const timer = setTimeout(() => setSearch(searchInput), 300);\n return () => clearTimeout(timer);\n }, [searchInput]);\n\n const accountUsers = useListAllAccountUsers(search, id || undefined);\n const projectUsers = useListProjectUsers(id, \"\");\n const addMutation = useAddProjectUser(id);\n const removeMutation = useRemoveProjectUser(id);\n\n const allUsers = accountUsers.data?.pages.flatMap((p) => p.data) ?? [];\n const isLoading = accountUsers.isLoading;\n const isFetchingMore = accountUsers.isFetchingNextPage;\n const totalInProject = projectUsers.data?.pages[0]?.total ?? 0;\n\n const toggleUser = (userId: number, inProject: boolean, removable: boolean) => {\n if (inProject) {\n if (!removable) return;\n removeMutation.mutate(userId);\n } else {\n addMutation.mutate(userId);\n }\n };\n\n const handleScroll = (e: React.UIEvent<HTMLDivElement>) => {\n const target = e.currentTarget;\n const nearBottom =\n target.scrollTop + target.clientHeight >= target.scrollHeight - 50;\n if (!nearBottom) return;\n if (accountUsers.hasNextPage && !accountUsers.isFetchingNextPage) {\n accountUsers.fetchNextPage();\n }\n };\n\n return (\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger className=\"cursor-pointer\">\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\">\n <span className=\"paragraph-small-semibold\">{totalInProject}</span>\n <User size={16} />\n </div>\n </PopoverTrigger>\n\n <PopoverContent\n className={cn(\n \"absolute right-[-88px] w-[273px] p-0 bg-white rounded-2xl shadow-md border border-gray-200\",\n contentClassName,\n )}\n side={side}\n align={align}\n sideOffset={8}\n >\n <div className=\"flex flex-col p-3 gap-2\">\n <div className=\"flex items-center justify-between\">\n <span className=\"paragraph-small-semibold\">Usuários</span>\n <div className=\"flex items-center gap-1.5\">\n <Button\n variant=\"secondary\"\n className=\"h-8 paragraph-small-semibold text-gray-950\"\n onClick={() => {\n window.location.href = `${GAPPS_URL}/my-teams?createNew=true`;\n }}\n >\n <Plus size={16} />\n Adicionar\n </Button>\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n variant=\"secondary\"\n className=\"p-0 size-8\"\n onClick={() => {\n window.location.href = `${GAPPS_URL}/my-teams`;\n }}\n >\n <Settings size={18} />\n </Button>\n </TooltipTrigger>\n <TooltipContent className=\"z-[1002]\">\n Visualizar todos usuários\n </TooltipContent>\n </Tooltip>\n </div>\n </div>\n\n <Command shouldFilter={false} className=\"gap-2\" value=\"\">\n <CommandInput\n placeholder=\"Busque aqui\"\n value={searchInput}\n onValueChange={setSearchInput}\n />\n <CommandList\n className=\"custom-scrollbar paragraph-small-medium text-gray-600 h-[162px]\"\n onScroll={handleScroll}\n >\n {isLoading ? (\n <>\n <UserItemSkeleton />\n <UserItemSkeleton />\n <UserItemSkeleton />\n </>\n ) : allUsers.length === 0 ? (\n <div className=\"flex flex-col items-center justify-center gap-2 h-full text-gray-400 py-4\">\n <Users size={28} className=\"text-gray-300\" />\n <span className=\"paragraph-small-medium text-center text-gray-500\">\n Nenhum usuário encontrado.\n </span>\n </div>\n ) : (\n <>\n <CommandEmpty>Nenhum resultado encontrado.</CommandEmpty>\n {allUsers.map((user) => {\n const inProject = user.in_project ?? false;\n const removable =\n inProject &&\n user.profile !== \"owner\" &&\n user.profile !== \"admin\";\n const interactive = !inProject || removable;\n\n return (\n <CommandItem\n key={user.id}\n value={user.name || String(user.id)}\n autoFocus={false}\n onPointerEnter={() => setHoveredId(user.id)}\n onPointerLeave={() => setHoveredId(null)}\n onFocus={() => setHoveredId(user.id)}\n onBlur={() => setHoveredId(null)}\n onSelect={() => toggleUser(user.id, inProject, removable)}\n className={interactive ? \"cursor-pointer\" : \"cursor-default\"}\n >\n <div className=\"flex items-center justify-between w-full\">\n <div className=\"flex items-center gap-2 min-w-0\">\n <UserAvatar\n photo={user.photo}\n name={user.name ?? undefined}\n size={32}\n />\n <span className=\"truncate\">{user.name}</span>\n </div>\n <Tooltip open={interactive && hoveredId === user.id}>\n <TooltipTrigger\n onClick={(e) => e.stopPropagation()}\n onPointerDown={(e) => e.stopPropagation()}\n >\n <Checkbox\n checked={inProject}\n disabled={!interactive}\n onCheckedChange={() =>\n toggleUser(user.id, inProject, removable)\n }\n className={cn(\n interactive && hoveredId === user.id\n ? \"border-gray-950\"\n : \"\",\n \"disabled:opacity-10\",\n )}\n />\n </TooltipTrigger>\n <TooltipContent className=\"z-[1002]\">\n {inProject ? \"Remover do projeto\" : \"Adicionar ao projeto\"}\n </TooltipContent>\n </Tooltip>\n </div>\n </CommandItem>\n );\n })}\n {isFetchingMore && (\n <>\n <UserItemSkeleton />\n <UserItemSkeleton />\n </>\n )}\n </>\n )}\n </CommandList>\n </Command>\n </div>\n </PopoverContent>\n </Popover>\n );\n}\n"],"mappings":"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","names":[]}
package/dist/index.mjs CHANGED
@@ -191,6 +191,8 @@ import {
191
191
  TooltipContent,
192
192
  TooltipProvider
193
193
  } from "./components/ui/overlay/Tooltip";
194
+ import { FrillEmbed } from "./components/embeds/FrillEmbed";
195
+ import { CrispEmbed, openCrispHelpdesk } from "./components/embeds/CrispEmbed";
194
196
  import { useMdSidebarStore } from "./store/useMdSidebarStore";
195
197
  import { useModalManager } from "./store/useModalManager";
196
198
  import { AccountSectionType } from "./enums/AccountSectionType";
@@ -292,6 +294,7 @@ export {
292
294
  CommandShortcut,
293
295
  default15 as ConfirmGlobalPreferencesModal,
294
296
  CopyButton,
297
+ CrispEmbed,
295
298
  DatePicker,
296
299
  DateRangePicker,
297
300
  default6 as DefaultCircularProgress,
@@ -307,6 +310,7 @@ export {
307
310
  DialogTrigger,
308
311
  default14 as DisableTwoFactorAuthModal,
309
312
  FormField,
313
+ FrillEmbed,
310
314
  GENDER_OPTIONS,
311
315
  Input,
312
316
  InputOTP,
@@ -419,6 +423,7 @@ export {
419
423
  formatFullName,
420
424
  formatPhone,
421
425
  formatTimer,
426
+ openCrispHelpdesk,
422
427
  parseResult,
423
428
  parseSchema,
424
429
  readFromClipboard,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["// Types\nexport * from \"./modules/auth/schema\";\nexport * from \"./modules/users/schema\";\nexport * from \"./modules/whitelabel/schema\";\nexport * from \"./modules/whitelabel/styles-schema\";\nexport * from \"./infra/api/types\";\n\n// Contexts\nexport * from \"./providers/query.provider\";\nexport * from \"./providers/auth.provider\";\nexport * from \"./providers/whitelabel.provider\";\n\n// Hooks\nexport {\n useListProjectUsers,\n LIST_PROJECT_USERS_QUERY_KEY,\n LIST_PROJECT_USERS_BASE_KEY,\n} from \"./modules/projects/hooks/list-project-users.hook\";\nexport {\n useListAvailableUsers,\n LIST_AVAILABLE_USERS_QUERY_KEY,\n LIST_AVAILABLE_USERS_BASE_KEY,\n} from \"./modules/projects/hooks/list-available-users.hook\";\nexport type {\n ProjectUser,\n AccountUser,\n AddRemoveProjectUsersParams,\n ListUsersParams,\n UsersPage,\n} from \"./modules/projects/types\";\nexport {\n useUserQuery,\n useUserValidateSession,\n useInvalidateUser,\n useSetUserData,\n useTwoFactorVerify,\n USER_QUERY_KEY,\n} from \"./modules/auth/hooks/useUserQuery\";\nexport {\n useSubscriptions,\n SUBSCRIPTIONS_QUERY_KEY,\n} from \"./modules/subscriptions/hooks/list-subscriptions.hook\";\nexport { useActiveSubscription } from \"./modules/subscriptions/hooks/find-active-subscription.hook\";\nexport { useIaCredits } from \"./modules/ia-credits/hooks/ia-credits.hook\";\nexport type {\n IaCreditsSummary,\n IaCreditOperation,\n} from \"./modules/ia-credits/types\";\nexport type {\n Subscription,\n SubscriptionItem,\n FindSubscriptionsParams,\n} from \"./modules/subscriptions/types\";\nexport {\n SubscriptionSchema,\n SubscriptionItemSchema,\n} from \"./modules/subscriptions/types\";\nexport { ADDON_IDS } from \"./modules/subscriptions/constants/addons.constants\";\nexport type { AddonKindEnum } from \"./modules/subscriptions/constants/addons.constants\";\n\n// Providers\nexport { QueryProvider } from \"./providers/query.provider\";\n\n// Middleware\nexport { createAuthMiddleware } from \"./middlewares/create-auth-middleware\";\nexport { createMiddlewareChain } from \"./middlewares/chain\";\nexport { continueChain, stopChain } from \"./middlewares/types\";\nexport type {\n MiddlewareFunction,\n MiddlewareConfig,\n MiddlewareResult,\n} from \"./middlewares/types\";\n\n// Utils\nexport { cn } from \"./infra/utils/clsx\";\nexport { buildQueryParams } from \"./infra/utils/params\";\nexport { parseSchema, parseResult } from \"./infra/utils/parser\";\nexport { withAction } from \"./utils/withAction\";\n\n// Layout\nexport {\n MainLayout,\n MainLayoutContent,\n MainLayoutSpacer,\n MainLayoutMain,\n} from \"./components/layouts/MainLayout\";\nexport { NavBar } from \"./components/layouts/NavBar\";\nexport type { NavBarProps } from \"./components/layouts/NavBar\";\nexport { AppNavBar } from \"./components/layouts/AppNavBar\";\nexport type { AppNavBarProps } from \"./components/layouts/AppNavBar\";\nexport { AppMobileNavBar } from \"./components/layouts/AppMobileNavBar\";\nexport type { AppMobileNavBarProps } from \"./components/layouts/AppMobileNavBar\";\nexport { SideBarNavigation } from \"./components/layouts/SideBarNavigation\";\nexport { MdSideBarNavigation } from \"./components/layouts/MdSideBarNavigation\";\nexport { default as NotificationCard } from \"./components/widgets/notifications/NotificationCard\";\nexport type { NotificationCardProps } from \"./components/widgets/notifications/NotificationCard\";\nexport { NotificationsPopover } from \"./components/layouts/NotificationsPopover\";\nexport type { NotificationsPopoverProps } from \"./components/layouts/NotificationsPopover\";\nexport { NotificationPageContent } from \"./components/pages/notifications/Notifications\";\nexport { UsersSelectorPopover } from \"./components/layouts/UsersSelectorPopover\";\nexport type { UsersSelectorPopoverProps } from \"./components/layouts/UsersSelectorPopover\";\nexport { ProfilePopover } from \"./components/layouts/ProfilePopover\";\nexport type {\n ProfilePopoverProps,\n ProfileMenuItem,\n} from \"./components/layouts/ProfilePopover\";\nexport { NavBarItem } from \"./components/layouts/NavBarItem\";\nexport type { NavBarItemProps } from \"./components/layouts/NavBarItem\";\n\n// Navigation\nexport { AppNavigation } from './components/navigation/AppNavigation';\nexport { CancelledSubscriptionBanner } from './components/navigation/CancelledSubscriptionBanner';\nexport type { NavItemConfig } from './components/navigation/subcomponents/NavItems';\nexport type { NavigationProject } from './components/navigation/types';\nexport { useMobileNavbarSheet } from './store/useMobileNavbarSheet';\n\n// Hooks\nexport { default as useCopyToClipboard } from \"./hooks/copy-to-clipboard.hook\";\n\n// UI - Buttons\nexport { Button, buttonVariants } from \"./components/ui/buttons/Button\";\nexport { CopyButton } from \"./components/ui/buttons/CopyButton\";\nexport { default as CancelButton } from \"./components/ui/buttons/CancelButton\";\n\n// UI - Data Display\nexport {\n Accordion,\n AccordionItem,\n AccordionTrigger,\n AccordionContent,\n} from \"./components/ui/data-display/Accordion\";\nexport { Badge, badgeVariants } from \"./components/ui/data-display/Badge\";\nexport {\n Card,\n CardHeader,\n CardFooter,\n CardTitle,\n CardAction,\n CardDescription,\n CardContent,\n} from \"./components/ui/data-display/Card\";\nexport {\n Pagination,\n PaginationContent,\n PaginationLink,\n PaginationItem,\n PaginationPrevious,\n PaginationNext,\n PaginationEllipsis,\n} from \"./components/ui/data-display/Pagination\";\nexport { ScrollArea, ScrollBar } from \"./components/ui/data-display/ScrollArea\";\nexport { Separator } from \"./components/ui/data-display/Separator\";\nexport {\n Table,\n TableHeader,\n TableBody,\n TableFooter,\n TableHead,\n TableRow,\n TableCell,\n TableCaption,\n} from \"./components/ui/data-display/Table\";\nexport {\n Tabs,\n TabsList,\n TabsTrigger,\n TabsContent,\n} from \"./components/ui/data-display/Tabs\";\nexport { UserAvatar } from \"./components/ui/data-display/UserAvatar\";\nexport type { UserAvatarProps } from \"./components/ui/data-display/UserAvatar\";\n\n// UI - Feedback\nexport { default as CircularProgress } from \"./components/ui/feedback/CircularProgress\";\nexport { default as DefaultCircularProgress } from \"./components/ui/feedback/DefaultCircularProgress\";\nexport { Progress } from \"./components/ui/feedback/Progress\";\nexport { LoadingOverlay } from \"./components/ui/feedback/LoadingOverlay\";\nexport {\n Toast,\n toastVariants,\n toastIconContainerVariants,\n} from \"./components/ui/feedback/Toast\";\nexport type { ToastProps } from \"./components/ui/feedback/Toast\";\n\n// UI - Form\nexport { Calendar, CalendarDayButton } from \"./components/ui/form/Calendar\";\nexport { Checkbox } from \"./components/ui/form/Checkbox\";\nexport { DatePicker } from \"./components/ui/form/DatePicker\";\nexport { DateRangePicker } from \"./components/ui/form/DateRangePicker\";\nexport { Input } from \"./components/ui/form/Input\";\nexport {\n InputOTP,\n InputOTPGroup,\n InputOTPSlot,\n InputOTPSeparator,\n} from \"./components/ui/form/InputOtp\";\nexport { RadioGroup, RadioGroupItem } from \"./components/ui/form/RadioGroup\";\nexport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectLabel,\n SelectScrollDownButton,\n SelectScrollUpButton,\n SelectSeparator,\n SelectTrigger,\n SelectValue,\n} from \"./components/ui/form/Select\";\nexport { Switch } from \"./components/ui/form/Switch\";\nexport { Textarea } from \"./components/ui/form/Textarea\";\n\n// UI - Overlay\nexport {\n Command,\n CommandDialog,\n CommandInput,\n CommandList,\n CommandEmpty,\n CommandGroup,\n CommandItem,\n CommandShortcut,\n CommandSeparator,\n} from \"./components/ui/overlay/Command\";\nexport {\n Dialog,\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogOverlay,\n DialogPortal,\n DialogTitle,\n DialogTrigger,\n} from \"./components/ui/overlay/Dialog\";\nexport {\n Popover,\n PopoverTrigger,\n PopoverContent,\n PopoverAnchor,\n} from \"./components/ui/overlay/Popover\";\nexport {\n Sheet,\n SheetTrigger,\n SheetClose,\n SheetContent,\n SheetHeader,\n SheetFooter,\n SheetTitle,\n SheetDescription,\n} from \"./components/ui/overlay/Sheet\";\nexport {\n Tooltip,\n TooltipTrigger,\n TooltipContent,\n TooltipProvider,\n} from \"./components/ui/overlay/Tooltip\";\n\n// Store\nexport { useMdSidebarStore } from \"./store/useMdSidebarStore\";\nexport { useModalManager } from \"./store/useModalManager\";\nexport type { ModalData } from \"./store/useModalManager\";\n\n// Enums\nexport { AccountSectionType } from \"./enums/AccountSectionType\";\n\n// Hooks\nexport { default as usePasswordVisibility } from \"./hooks/usePasswordVisibility\";\nexport { default as useCountdownTimer } from \"./hooks/useCountdownTimer\";\nexport { default as useIsMobile } from \"./hooks/useIsMobile\";\nexport { useDebounce } from \"./hooks/useDebounce\";\nexport { useDebouncedEffect } from \"./hooks/useDebouncedEffect\";\nexport { useDebounceState } from \"./hooks/useDebounceState\";\n\n// Utils\nexport {\n formatPhone,\n formatTimer,\n formatFullName,\n formatCPF,\n formatCardNumber,\n} from \"./utils/format/masks\";\nexport type { TimezoneOption } from \"./modules/accounts/services/timezone.service\";\nexport {\n buildLocaleOptions,\n LANGUAGE_OPTIONS as LOCALE_LANGUAGE_OPTIONS,\n} from \"./utils/intl/locales\";\nexport type { LocaleOption } from \"./utils/intl/locales\";\nexport { copyToClipboard, readFromClipboard } from \"./utils/browser/clipboard\";\n\n// UI - Form (new widgets)\nexport { FormField } from \"./components/ui/form/FormField\";\nexport { SelectField } from \"./components/ui/form/SelectField\";\nexport { ComboboxField } from \"./components/ui/form/ComboboxField\";\nexport type { ComboboxOption } from \"./components/ui/form/ComboboxField\";\nexport { default as PhoneInput } from \"./components/ui/form/PhoneInput\";\nexport { default as SwitchOptionFieldWithIcon } from \"./components/ui/form/SwitchOptionFieldWithIcon\";\nexport { TextAreaField } from \"./components/ui/form/TextAreaField\";\n\n// Account Module - Hooks\nexport {\n useCurrentAccount,\n ACCOUNT_QUERY_KEY,\n} from \"./modules/accounts/hooks/current-account.hook\";\nexport {\n useUpdateAccount,\n useUpdateAccountUser,\n useUpdateAccountUserById,\n useDeleteAccountUser,\n useDeleteAccount,\n} from \"./modules/accounts/hooks/useAccountManagement\";\n\n// Account Types\nexport type {\n UpdateAccountRequest,\n UpdateAccountUserRequest,\n ChangePasswordRequest,\n DeleteAccountActionResult,\n DeleteUserActionResult,\n UpdateAccountActionResult,\n UpdateUserActionResult,\n TwoFactorGenerateResult,\n TwoFactorActionResult,\n ContactResetResult,\n} from \"./modules/accounts/types\";\n\nexport { default as AccountModals } from \"./components/account/AccountModals\";\nexport { useAccountModals } from \"./store/useAccountModals\";\nexport type { AccountModalsConfig } from \"./store/useAccountModals\";\n\nexport { ModalManager } from \"./components/modals/ModalManager\";\nexport { Modals } from \"./components/modals/Modals\";\n\nexport { default as TwoFactorAuthModal } from \"./components/account/TwoFactorAuthModal\";\nexport { default as DisableTwoFactorAuthModal } from \"./components/account/DisableTwoFactorAuthModal\";\nexport { default as ConfirmGlobalPreferencesModal } from \"./components/account/ConfirmGlobalPreferencesModal\";\nexport { MyProfileSection } from \"./components/account/sections/MyProfileSection\";\nexport { PreferencesSection } from \"./components/account/sections/PreferencesSection\";\nexport { SecuritySection } from \"./components/account/sections/SecuritySection\";\nexport { ChangePasswordSection } from \"./components/account/sections/ChangePasswordSection\";\nexport { ChangeEmailModal } from \"./components/account/sections/ChangeEmailModal\";\nexport { ChangePhoneModal } from \"./components/account/sections/ChangePhoneModal\";\n\n// Account Constants\nexport {\n GENDER_OPTIONS,\n CURRENCY_OPTIONS,\n TIME_FORMAT_OPTIONS,\n NOTIFICATION_TYPES,\n LANGUAGE_OPTIONS,\n} from \"./components/account/constants\";\n"],"mappings":"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","names":["default","LANGUAGE_OPTIONS"]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["// Types\nexport * from \"./modules/auth/schema\";\nexport * from \"./modules/users/schema\";\nexport * from \"./modules/whitelabel/schema\";\nexport * from \"./modules/whitelabel/styles-schema\";\nexport * from \"./infra/api/types\";\n\n// Contexts\nexport * from \"./providers/query.provider\";\nexport * from \"./providers/auth.provider\";\nexport * from \"./providers/whitelabel.provider\";\n\n// Hooks\nexport {\n useListProjectUsers,\n LIST_PROJECT_USERS_QUERY_KEY,\n LIST_PROJECT_USERS_BASE_KEY,\n} from \"./modules/projects/hooks/list-project-users.hook\";\nexport {\n useListAvailableUsers,\n LIST_AVAILABLE_USERS_QUERY_KEY,\n LIST_AVAILABLE_USERS_BASE_KEY,\n} from \"./modules/projects/hooks/list-available-users.hook\";\nexport type {\n ProjectUser,\n AccountUser,\n AddRemoveProjectUsersParams,\n ListUsersParams,\n UsersPage,\n} from \"./modules/projects/types\";\nexport {\n useUserQuery,\n useUserValidateSession,\n useInvalidateUser,\n useSetUserData,\n useTwoFactorVerify,\n USER_QUERY_KEY,\n} from \"./modules/auth/hooks/useUserQuery\";\nexport {\n useSubscriptions,\n SUBSCRIPTIONS_QUERY_KEY,\n} from \"./modules/subscriptions/hooks/list-subscriptions.hook\";\nexport { useActiveSubscription } from \"./modules/subscriptions/hooks/find-active-subscription.hook\";\nexport { useIaCredits } from \"./modules/ia-credits/hooks/ia-credits.hook\";\nexport type {\n IaCreditsSummary,\n IaCreditOperation,\n} from \"./modules/ia-credits/types\";\nexport type {\n Subscription,\n SubscriptionItem,\n FindSubscriptionsParams,\n} from \"./modules/subscriptions/types\";\nexport {\n SubscriptionSchema,\n SubscriptionItemSchema,\n} from \"./modules/subscriptions/types\";\nexport { ADDON_IDS } from \"./modules/subscriptions/constants/addons.constants\";\nexport type { AddonKindEnum } from \"./modules/subscriptions/constants/addons.constants\";\n\n// Providers\nexport { QueryProvider } from \"./providers/query.provider\";\n\n// Middleware\nexport { createAuthMiddleware } from \"./middlewares/create-auth-middleware\";\nexport { createMiddlewareChain } from \"./middlewares/chain\";\nexport { continueChain, stopChain } from \"./middlewares/types\";\nexport type {\n MiddlewareFunction,\n MiddlewareConfig,\n MiddlewareResult,\n} from \"./middlewares/types\";\n\n// Utils\nexport { cn } from \"./infra/utils/clsx\";\nexport { buildQueryParams } from \"./infra/utils/params\";\nexport { parseSchema, parseResult } from \"./infra/utils/parser\";\nexport { withAction } from \"./utils/withAction\";\n\n// Layout\nexport {\n MainLayout,\n MainLayoutContent,\n MainLayoutSpacer,\n MainLayoutMain,\n} from \"./components/layouts/MainLayout\";\nexport { NavBar } from \"./components/layouts/NavBar\";\nexport type { NavBarProps } from \"./components/layouts/NavBar\";\nexport { AppNavBar } from \"./components/layouts/AppNavBar\";\nexport type { AppNavBarProps } from \"./components/layouts/AppNavBar\";\nexport { AppMobileNavBar } from \"./components/layouts/AppMobileNavBar\";\nexport type { AppMobileNavBarProps } from \"./components/layouts/AppMobileNavBar\";\nexport { SideBarNavigation } from \"./components/layouts/SideBarNavigation\";\nexport { MdSideBarNavigation } from \"./components/layouts/MdSideBarNavigation\";\nexport { default as NotificationCard } from \"./components/widgets/notifications/NotificationCard\";\nexport type { NotificationCardProps } from \"./components/widgets/notifications/NotificationCard\";\nexport { NotificationsPopover } from \"./components/layouts/NotificationsPopover\";\nexport type { NotificationsPopoverProps } from \"./components/layouts/NotificationsPopover\";\nexport { NotificationPageContent } from \"./components/pages/notifications/Notifications\";\nexport { UsersSelectorPopover } from \"./components/layouts/UsersSelectorPopover\";\nexport type { UsersSelectorPopoverProps } from \"./components/layouts/UsersSelectorPopover\";\nexport { ProfilePopover } from \"./components/layouts/ProfilePopover\";\nexport type {\n ProfilePopoverProps,\n ProfileMenuItem,\n} from \"./components/layouts/ProfilePopover\";\nexport { NavBarItem } from \"./components/layouts/NavBarItem\";\nexport type { NavBarItemProps } from \"./components/layouts/NavBarItem\";\n\n// Navigation\nexport { AppNavigation } from './components/navigation/AppNavigation';\nexport { CancelledSubscriptionBanner } from './components/navigation/CancelledSubscriptionBanner';\nexport type { NavItemConfig } from './components/navigation/subcomponents/NavItems';\nexport type { NavigationProject } from './components/navigation/types';\nexport { useMobileNavbarSheet } from './store/useMobileNavbarSheet';\n\n// Hooks\nexport { default as useCopyToClipboard } from \"./hooks/copy-to-clipboard.hook\";\n\n// UI - Buttons\nexport { Button, buttonVariants } from \"./components/ui/buttons/Button\";\nexport { CopyButton } from \"./components/ui/buttons/CopyButton\";\nexport { default as CancelButton } from \"./components/ui/buttons/CancelButton\";\n\n// UI - Data Display\nexport {\n Accordion,\n AccordionItem,\n AccordionTrigger,\n AccordionContent,\n} from \"./components/ui/data-display/Accordion\";\nexport { Badge, badgeVariants } from \"./components/ui/data-display/Badge\";\nexport {\n Card,\n CardHeader,\n CardFooter,\n CardTitle,\n CardAction,\n CardDescription,\n CardContent,\n} from \"./components/ui/data-display/Card\";\nexport {\n Pagination,\n PaginationContent,\n PaginationLink,\n PaginationItem,\n PaginationPrevious,\n PaginationNext,\n PaginationEllipsis,\n} from \"./components/ui/data-display/Pagination\";\nexport { ScrollArea, ScrollBar } from \"./components/ui/data-display/ScrollArea\";\nexport { Separator } from \"./components/ui/data-display/Separator\";\nexport {\n Table,\n TableHeader,\n TableBody,\n TableFooter,\n TableHead,\n TableRow,\n TableCell,\n TableCaption,\n} from \"./components/ui/data-display/Table\";\nexport {\n Tabs,\n TabsList,\n TabsTrigger,\n TabsContent,\n} from \"./components/ui/data-display/Tabs\";\nexport { UserAvatar } from \"./components/ui/data-display/UserAvatar\";\nexport type { UserAvatarProps } from \"./components/ui/data-display/UserAvatar\";\n\n// UI - Feedback\nexport { default as CircularProgress } from \"./components/ui/feedback/CircularProgress\";\nexport { default as DefaultCircularProgress } from \"./components/ui/feedback/DefaultCircularProgress\";\nexport { Progress } from \"./components/ui/feedback/Progress\";\nexport { LoadingOverlay } from \"./components/ui/feedback/LoadingOverlay\";\nexport {\n Toast,\n toastVariants,\n toastIconContainerVariants,\n} from \"./components/ui/feedback/Toast\";\nexport type { ToastProps } from \"./components/ui/feedback/Toast\";\n\n// UI - Form\nexport { Calendar, CalendarDayButton } from \"./components/ui/form/Calendar\";\nexport { Checkbox } from \"./components/ui/form/Checkbox\";\nexport { DatePicker } from \"./components/ui/form/DatePicker\";\nexport { DateRangePicker } from \"./components/ui/form/DateRangePicker\";\nexport { Input } from \"./components/ui/form/Input\";\nexport {\n InputOTP,\n InputOTPGroup,\n InputOTPSlot,\n InputOTPSeparator,\n} from \"./components/ui/form/InputOtp\";\nexport { RadioGroup, RadioGroupItem } from \"./components/ui/form/RadioGroup\";\nexport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectLabel,\n SelectScrollDownButton,\n SelectScrollUpButton,\n SelectSeparator,\n SelectTrigger,\n SelectValue,\n} from \"./components/ui/form/Select\";\nexport { Switch } from \"./components/ui/form/Switch\";\nexport { Textarea } from \"./components/ui/form/Textarea\";\n\n// UI - Overlay\nexport {\n Command,\n CommandDialog,\n CommandInput,\n CommandList,\n CommandEmpty,\n CommandGroup,\n CommandItem,\n CommandShortcut,\n CommandSeparator,\n} from \"./components/ui/overlay/Command\";\nexport {\n Dialog,\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogOverlay,\n DialogPortal,\n DialogTitle,\n DialogTrigger,\n} from \"./components/ui/overlay/Dialog\";\nexport {\n Popover,\n PopoverTrigger,\n PopoverContent,\n PopoverAnchor,\n} from \"./components/ui/overlay/Popover\";\nexport {\n Sheet,\n SheetTrigger,\n SheetClose,\n SheetContent,\n SheetHeader,\n SheetFooter,\n SheetTitle,\n SheetDescription,\n} from \"./components/ui/overlay/Sheet\";\nexport {\n Tooltip,\n TooltipTrigger,\n TooltipContent,\n TooltipProvider,\n} from \"./components/ui/overlay/Tooltip\";\n\n// Embeds\nexport { FrillEmbed } from \"./components/embeds/FrillEmbed\";\nexport { CrispEmbed, openCrispHelpdesk } from \"./components/embeds/CrispEmbed\";\n\n// Store\nexport { useMdSidebarStore } from \"./store/useMdSidebarStore\";\nexport { useModalManager } from \"./store/useModalManager\";\nexport type { ModalData } from \"./store/useModalManager\";\n\n// Enums\nexport { AccountSectionType } from \"./enums/AccountSectionType\";\n\n// Hooks\nexport { default as usePasswordVisibility } from \"./hooks/usePasswordVisibility\";\nexport { default as useCountdownTimer } from \"./hooks/useCountdownTimer\";\nexport { default as useIsMobile } from \"./hooks/useIsMobile\";\nexport { useDebounce } from \"./hooks/useDebounce\";\nexport { useDebouncedEffect } from \"./hooks/useDebouncedEffect\";\nexport { useDebounceState } from \"./hooks/useDebounceState\";\n\n// Utils\nexport {\n formatPhone,\n formatTimer,\n formatFullName,\n formatCPF,\n formatCardNumber,\n} from \"./utils/format/masks\";\nexport type { TimezoneOption } from \"./modules/accounts/services/timezone.service\";\nexport {\n buildLocaleOptions,\n LANGUAGE_OPTIONS as LOCALE_LANGUAGE_OPTIONS,\n} from \"./utils/intl/locales\";\nexport type { LocaleOption } from \"./utils/intl/locales\";\nexport { copyToClipboard, readFromClipboard } from \"./utils/browser/clipboard\";\n\n// UI - Form (new widgets)\nexport { FormField } from \"./components/ui/form/FormField\";\nexport { SelectField } from \"./components/ui/form/SelectField\";\nexport { ComboboxField } from \"./components/ui/form/ComboboxField\";\nexport type { ComboboxOption } from \"./components/ui/form/ComboboxField\";\nexport { default as PhoneInput } from \"./components/ui/form/PhoneInput\";\nexport { default as SwitchOptionFieldWithIcon } from \"./components/ui/form/SwitchOptionFieldWithIcon\";\nexport { TextAreaField } from \"./components/ui/form/TextAreaField\";\n\n// Account Module - Hooks\nexport {\n useCurrentAccount,\n ACCOUNT_QUERY_KEY,\n} from \"./modules/accounts/hooks/current-account.hook\";\nexport {\n useUpdateAccount,\n useUpdateAccountUser,\n useUpdateAccountUserById,\n useDeleteAccountUser,\n useDeleteAccount,\n} from \"./modules/accounts/hooks/useAccountManagement\";\n\n// Account Types\nexport type {\n UpdateAccountRequest,\n UpdateAccountUserRequest,\n ChangePasswordRequest,\n DeleteAccountActionResult,\n DeleteUserActionResult,\n UpdateAccountActionResult,\n UpdateUserActionResult,\n TwoFactorGenerateResult,\n TwoFactorActionResult,\n ContactResetResult,\n} from \"./modules/accounts/types\";\n\nexport { default as AccountModals } from \"./components/account/AccountModals\";\nexport { useAccountModals } from \"./store/useAccountModals\";\nexport type { AccountModalsConfig } from \"./store/useAccountModals\";\n\nexport { ModalManager } from \"./components/modals/ModalManager\";\nexport { Modals } from \"./components/modals/Modals\";\n\nexport { default as TwoFactorAuthModal } from \"./components/account/TwoFactorAuthModal\";\nexport { default as DisableTwoFactorAuthModal } from \"./components/account/DisableTwoFactorAuthModal\";\nexport { default as ConfirmGlobalPreferencesModal } from \"./components/account/ConfirmGlobalPreferencesModal\";\nexport { MyProfileSection } from \"./components/account/sections/MyProfileSection\";\nexport { PreferencesSection } from \"./components/account/sections/PreferencesSection\";\nexport { SecuritySection } from \"./components/account/sections/SecuritySection\";\nexport { ChangePasswordSection } from \"./components/account/sections/ChangePasswordSection\";\nexport { ChangeEmailModal } from \"./components/account/sections/ChangeEmailModal\";\nexport { ChangePhoneModal } from \"./components/account/sections/ChangePhoneModal\";\n\n// Account Constants\nexport {\n GENDER_OPTIONS,\n CURRENCY_OPTIONS,\n TIME_FORMAT_OPTIONS,\n NOTIFICATION_TYPES,\n LANGUAGE_OPTIONS,\n} from \"./components/account/constants\";\n"],"mappings":"AACA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AAGd,cAAc;AACd,cAAc;AACd,cAAc;AAGd;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAQP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP,SAAS,6BAA6B;AACtC,SAAS,oBAAoB;AAU7B;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP,SAAS,iBAAiB;AAI1B,SAAS,qBAAqB;AAG9B,SAAS,4BAA4B;AACrC,SAAS,6BAA6B;AACtC,SAAS,eAAe,iBAAiB;AAQzC,SAAS,UAAU;AACnB,SAAS,wBAAwB;AACjC,SAAS,aAAa,mBAAmB;AACzC,SAAS,kBAAkB;AAG3B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,cAAc;AAEvB,SAAS,iBAAiB;AAE1B,SAAS,uBAAuB;AAEhC,SAAS,yBAAyB;AAClC,SAAS,2BAA2B;AACpC,SAAoB,WAAXA,gBAAmC;AAE5C,SAAS,4BAA4B;AAErC,SAAS,+BAA+B;AACxC,SAAS,4BAA4B;AAErC,SAAS,sBAAsB;AAK/B,SAAS,kBAAkB;AAI3B,SAAS,qBAAqB;AAC9B,SAAS,mCAAmC;AAG5C,SAAS,4BAA4B;AAGrC,SAAoB,WAAXA,gBAAqC;AAG9C,SAAS,QAAQ,sBAAsB;AACvC,SAAS,kBAAkB;AAC3B,SAAoB,WAAXA,gBAA+B;AAGxC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,OAAO,qBAAqB;AACrC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,YAAY,iBAAiB;AACtC,SAAS,iBAAiB;AAC1B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,kBAAkB;AAI3B,SAAoB,WAAXA,gBAAmC;AAC5C,SAAoB,WAAXA,gBAA0C;AACnD,SAAS,gBAAgB;AACzB,SAAS,sBAAsB;AAC/B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAIP,SAAS,UAAU,yBAAyB;AAC5C,SAAS,gBAAgB;AACzB,SAAS,kBAAkB;AAC3B,SAAS,uBAAuB;AAChC,SAAS,aAAa;AACtB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,YAAY,sBAAsB;AAC3C;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,cAAc;AACvB,SAAS,gBAAgB;AAGzB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAGP,SAAS,kBAAkB;AAC3B,SAAS,YAAY,yBAAyB;AAG9C,SAAS,yBAAyB;AAClC,SAAS,uBAAuB;AAIhC,SAAS,0BAA0B;AAGnC,SAAoB,WAAXA,gBAAwC;AACjD,SAAoB,WAAXA,gBAAoC;AAC7C,SAAoB,WAAXA,gBAA8B;AACvC,SAAS,mBAAmB;AAC5B,SAAS,0BAA0B;AACnC,SAAS,wBAAwB;AAGjC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP;AAAA,EACE;AAAA,EACoB;AAAA,OACf;AAEP,SAAS,iBAAiB,yBAAyB;AAGnD,SAAS,iBAAiB;AAC1B,SAAS,mBAAmB;AAC5B,SAAS,qBAAqB;AAE9B,SAAoB,WAAXA,iBAA6B;AACtC,SAAoB,WAAXA,iBAA4C;AACrD,SAAS,qBAAqB;AAG9B;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAgBP,SAAoB,WAAXA,iBAAgC;AACzC,SAAS,wBAAwB;AAGjC,SAAS,oBAAoB;AAC7B,SAAS,cAAc;AAEvB,SAAoB,WAAXA,iBAAqC;AAC9C,SAAoB,WAAXA,iBAA4C;AACrD,SAAoB,WAAXA,iBAAgD;AACzD,SAAS,wBAAwB;AACjC,SAAS,0BAA0B;AACnC,SAAS,uBAAuB;AAChC,SAAS,6BAA6B;AACtC,SAAS,wBAAwB;AACjC,SAAS,wBAAwB;AAGjC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,oBAAAC;AAAA,OACK;","names":["default","LANGUAGE_OPTIONS"]}
@@ -0,0 +1,61 @@
1
+ "use client";
2
+ import { useQueryClient, useMutation } from "@tanstack/react-query";
3
+ import { addProjectUserAction } from "../actions/add-project-user.action";
4
+ import { LIST_PROJECT_USERS_BASE_KEY } from "./list-project-users.hook";
5
+ import { LIST_ALL_ACCOUNT_USERS_BASE_KEY } from "./list-all-account-users.hook";
6
+ function useAddProjectUser(projectId) {
7
+ const queryClient = useQueryClient();
8
+ return useMutation({
9
+ mutationFn: (userId) => addProjectUserAction({ projectId, users: [userId] }),
10
+ onMutate: async (userId) => {
11
+ await queryClient.cancelQueries({ queryKey: LIST_ALL_ACCOUNT_USERS_BASE_KEY() });
12
+ await queryClient.cancelQueries({ queryKey: LIST_PROJECT_USERS_BASE_KEY(projectId) });
13
+ const prevAccountUsers = queryClient.getQueriesData({
14
+ queryKey: LIST_ALL_ACCOUNT_USERS_BASE_KEY()
15
+ });
16
+ const prevProjectUsers = queryClient.getQueriesData({
17
+ queryKey: LIST_PROJECT_USERS_BASE_KEY(projectId)
18
+ });
19
+ queryClient.setQueriesData(
20
+ { queryKey: LIST_ALL_ACCOUNT_USERS_BASE_KEY(), exact: false },
21
+ (old) => {
22
+ if (!old) return old;
23
+ return {
24
+ ...old,
25
+ pages: old.pages.map((page) => ({
26
+ ...page,
27
+ data: page.data.map(
28
+ (u) => u.id === userId ? { ...u, in_project: true } : u
29
+ )
30
+ }))
31
+ };
32
+ }
33
+ );
34
+ queryClient.setQueriesData(
35
+ { queryKey: LIST_PROJECT_USERS_BASE_KEY(projectId), exact: false },
36
+ (old) => {
37
+ if (!old?.pages.length) return old;
38
+ return {
39
+ ...old,
40
+ pages: old.pages.map(
41
+ (page, i) => i === 0 ? { ...page, total: page.total + 1 } : page
42
+ )
43
+ };
44
+ }
45
+ );
46
+ return { prevAccountUsers, prevProjectUsers };
47
+ },
48
+ onError: (_err, _userId, ctx) => {
49
+ ctx?.prevAccountUsers.forEach(([key, data]) => queryClient.setQueryData(key, data));
50
+ ctx?.prevProjectUsers.forEach(([key, data]) => queryClient.setQueryData(key, data));
51
+ },
52
+ onSettled: () => {
53
+ queryClient.invalidateQueries({ queryKey: LIST_PROJECT_USERS_BASE_KEY(projectId) });
54
+ queryClient.invalidateQueries({ queryKey: LIST_ALL_ACCOUNT_USERS_BASE_KEY() });
55
+ }
56
+ });
57
+ }
58
+ export {
59
+ useAddProjectUser
60
+ };
61
+ //# sourceMappingURL=add-project-user.hook.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/modules/projects/hooks/add-project-user.hook.ts"],"sourcesContent":["'use client';\n\nimport { useQueryClient, useMutation, InfiniteData } from '@tanstack/react-query';\nimport { addProjectUserAction } from '../actions/add-project-user.action';\nimport { LIST_PROJECT_USERS_BASE_KEY } from './list-project-users.hook';\nimport { LIST_ALL_ACCOUNT_USERS_BASE_KEY } from './list-all-account-users.hook';\nimport type { UsersPage, AccountUser, ProjectUser } from '../types';\n\nexport function useAddProjectUser(projectId: number) {\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: (userId: number) =>\n addProjectUserAction({ projectId, users: [userId] }),\n\n onMutate: async (userId) => {\n await queryClient.cancelQueries({ queryKey: LIST_ALL_ACCOUNT_USERS_BASE_KEY() });\n await queryClient.cancelQueries({ queryKey: LIST_PROJECT_USERS_BASE_KEY(projectId) });\n\n const prevAccountUsers = queryClient.getQueriesData<InfiniteData<UsersPage<AccountUser>>>({\n queryKey: LIST_ALL_ACCOUNT_USERS_BASE_KEY(),\n });\n const prevProjectUsers = queryClient.getQueriesData<InfiniteData<UsersPage<ProjectUser>>>({\n queryKey: LIST_PROJECT_USERS_BASE_KEY(projectId),\n });\n\n queryClient.setQueriesData<InfiniteData<UsersPage<AccountUser>>>(\n { queryKey: LIST_ALL_ACCOUNT_USERS_BASE_KEY(), exact: false },\n (old) => {\n if (!old) return old;\n return {\n ...old,\n pages: old.pages.map((page) => ({\n ...page,\n data: page.data.map((u) =>\n u.id === userId ? { ...u, in_project: true } : u\n ),\n })),\n };\n }\n );\n\n queryClient.setQueriesData<InfiniteData<UsersPage<ProjectUser>>>(\n { queryKey: LIST_PROJECT_USERS_BASE_KEY(projectId), exact: false },\n (old) => {\n if (!old?.pages.length) return old;\n return {\n ...old,\n pages: old.pages.map((page, i) =>\n i === 0 ? { ...page, total: page.total + 1 } : page\n ),\n };\n }\n );\n\n return { prevAccountUsers, prevProjectUsers };\n },\n\n onError: (_err, _userId, ctx) => {\n ctx?.prevAccountUsers.forEach(([key, data]) => queryClient.setQueryData(key, data));\n ctx?.prevProjectUsers.forEach(([key, data]) => queryClient.setQueryData(key, data));\n },\n\n onSettled: () => {\n queryClient.invalidateQueries({ queryKey: LIST_PROJECT_USERS_BASE_KEY(projectId) });\n queryClient.invalidateQueries({ queryKey: LIST_ALL_ACCOUNT_USERS_BASE_KEY() });\n },\n });\n}\n"],"mappings":";AAEA,SAAS,gBAAgB,mBAAiC;AAC1D,SAAS,4BAA4B;AACrC,SAAS,mCAAmC;AAC5C,SAAS,uCAAuC;AAGzC,SAAS,kBAAkB,WAAmB;AACnD,QAAM,cAAc,eAAe;AAEnC,SAAO,YAAY;AAAA,IACjB,YAAY,CAAC,WACX,qBAAqB,EAAE,WAAW,OAAO,CAAC,MAAM,EAAE,CAAC;AAAA,IAErD,UAAU,OAAO,WAAW;AAC1B,YAAM,YAAY,cAAc,EAAE,UAAU,gCAAgC,EAAE,CAAC;AAC/E,YAAM,YAAY,cAAc,EAAE,UAAU,4BAA4B,SAAS,EAAE,CAAC;AAEpF,YAAM,mBAAmB,YAAY,eAAqD;AAAA,QACxF,UAAU,gCAAgC;AAAA,MAC5C,CAAC;AACD,YAAM,mBAAmB,YAAY,eAAqD;AAAA,QACxF,UAAU,4BAA4B,SAAS;AAAA,MACjD,CAAC;AAED,kBAAY;AAAA,QACV,EAAE,UAAU,gCAAgC,GAAG,OAAO,MAAM;AAAA,QAC5D,CAAC,QAAQ;AACP,cAAI,CAAC,IAAK,QAAO;AACjB,iBAAO;AAAA,YACL,GAAG;AAAA,YACH,OAAO,IAAI,MAAM,IAAI,CAAC,UAAU;AAAA,cAC9B,GAAG;AAAA,cACH,MAAM,KAAK,KAAK;AAAA,gBAAI,CAAC,MACnB,EAAE,OAAO,SAAS,EAAE,GAAG,GAAG,YAAY,KAAK,IAAI;AAAA,cACjD;AAAA,YACF,EAAE;AAAA,UACJ;AAAA,QACF;AAAA,MACF;AAEA,kBAAY;AAAA,QACV,EAAE,UAAU,4BAA4B,SAAS,GAAG,OAAO,MAAM;AAAA,QACjE,CAAC,QAAQ;AACP,cAAI,CAAC,KAAK,MAAM,OAAQ,QAAO;AAC/B,iBAAO;AAAA,YACL,GAAG;AAAA,YACH,OAAO,IAAI,MAAM;AAAA,cAAI,CAAC,MAAM,MAC1B,MAAM,IAAI,EAAE,GAAG,MAAM,OAAO,KAAK,QAAQ,EAAE,IAAI;AAAA,YACjD;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,aAAO,EAAE,kBAAkB,iBAAiB;AAAA,IAC9C;AAAA,IAEA,SAAS,CAAC,MAAM,SAAS,QAAQ;AAC/B,WAAK,iBAAiB,QAAQ,CAAC,CAAC,KAAK,IAAI,MAAM,YAAY,aAAa,KAAK,IAAI,CAAC;AAClF,WAAK,iBAAiB,QAAQ,CAAC,CAAC,KAAK,IAAI,MAAM,YAAY,aAAa,KAAK,IAAI,CAAC;AAAA,IACpF;AAAA,IAEA,WAAW,MAAM;AACf,kBAAY,kBAAkB,EAAE,UAAU,4BAA4B,SAAS,EAAE,CAAC;AAClF,kBAAY,kBAAkB,EAAE,UAAU,gCAAgC,EAAE,CAAC;AAAA,IAC/E;AAAA,EACF,CAAC;AACH;","names":[]}
@@ -0,0 +1,61 @@
1
+ "use client";
2
+ import { useQueryClient, useMutation } from "@tanstack/react-query";
3
+ import { removeProjectUserAction } from "../actions/remove-project-user.action";
4
+ import { LIST_PROJECT_USERS_BASE_KEY } from "./list-project-users.hook";
5
+ import { LIST_ALL_ACCOUNT_USERS_BASE_KEY } from "./list-all-account-users.hook";
6
+ function useRemoveProjectUser(projectId) {
7
+ const queryClient = useQueryClient();
8
+ return useMutation({
9
+ mutationFn: (userId) => removeProjectUserAction({ projectId, users: [userId] }),
10
+ onMutate: async (userId) => {
11
+ await queryClient.cancelQueries({ queryKey: LIST_ALL_ACCOUNT_USERS_BASE_KEY() });
12
+ await queryClient.cancelQueries({ queryKey: LIST_PROJECT_USERS_BASE_KEY(projectId) });
13
+ const prevAccountUsers = queryClient.getQueriesData({
14
+ queryKey: LIST_ALL_ACCOUNT_USERS_BASE_KEY()
15
+ });
16
+ const prevProjectUsers = queryClient.getQueriesData({
17
+ queryKey: LIST_PROJECT_USERS_BASE_KEY(projectId)
18
+ });
19
+ queryClient.setQueriesData(
20
+ { queryKey: LIST_ALL_ACCOUNT_USERS_BASE_KEY(), exact: false },
21
+ (old) => {
22
+ if (!old) return old;
23
+ return {
24
+ ...old,
25
+ pages: old.pages.map((page) => ({
26
+ ...page,
27
+ data: page.data.map(
28
+ (u) => u.id === userId ? { ...u, in_project: false } : u
29
+ )
30
+ }))
31
+ };
32
+ }
33
+ );
34
+ queryClient.setQueriesData(
35
+ { queryKey: LIST_PROJECT_USERS_BASE_KEY(projectId), exact: false },
36
+ (old) => {
37
+ if (!old?.pages.length) return old;
38
+ return {
39
+ ...old,
40
+ pages: old.pages.map(
41
+ (page, i) => i === 0 ? { ...page, total: page.total - 1 } : page
42
+ )
43
+ };
44
+ }
45
+ );
46
+ return { prevAccountUsers, prevProjectUsers };
47
+ },
48
+ onError: (_err, _userId, ctx) => {
49
+ ctx?.prevAccountUsers.forEach(([key, data]) => queryClient.setQueryData(key, data));
50
+ ctx?.prevProjectUsers.forEach(([key, data]) => queryClient.setQueryData(key, data));
51
+ },
52
+ onSettled: () => {
53
+ queryClient.invalidateQueries({ queryKey: LIST_PROJECT_USERS_BASE_KEY(projectId) });
54
+ queryClient.invalidateQueries({ queryKey: LIST_ALL_ACCOUNT_USERS_BASE_KEY() });
55
+ }
56
+ });
57
+ }
58
+ export {
59
+ useRemoveProjectUser
60
+ };
61
+ //# sourceMappingURL=remove-project-user.hook.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/modules/projects/hooks/remove-project-user.hook.ts"],"sourcesContent":["'use client';\n\nimport { useQueryClient, useMutation, InfiniteData } from '@tanstack/react-query';\nimport { removeProjectUserAction } from '../actions/remove-project-user.action';\nimport { LIST_PROJECT_USERS_BASE_KEY } from './list-project-users.hook';\nimport { LIST_ALL_ACCOUNT_USERS_BASE_KEY } from './list-all-account-users.hook';\nimport type { UsersPage, AccountUser, ProjectUser } from '../types';\n\nexport function useRemoveProjectUser(projectId: number) {\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: (userId: number) =>\n removeProjectUserAction({ projectId, users: [userId] }),\n\n onMutate: async (userId) => {\n await queryClient.cancelQueries({ queryKey: LIST_ALL_ACCOUNT_USERS_BASE_KEY() });\n await queryClient.cancelQueries({ queryKey: LIST_PROJECT_USERS_BASE_KEY(projectId) });\n\n const prevAccountUsers = queryClient.getQueriesData<InfiniteData<UsersPage<AccountUser>>>({\n queryKey: LIST_ALL_ACCOUNT_USERS_BASE_KEY(),\n });\n const prevProjectUsers = queryClient.getQueriesData<InfiniteData<UsersPage<ProjectUser>>>({\n queryKey: LIST_PROJECT_USERS_BASE_KEY(projectId),\n });\n\n queryClient.setQueriesData<InfiniteData<UsersPage<AccountUser>>>(\n { queryKey: LIST_ALL_ACCOUNT_USERS_BASE_KEY(), exact: false },\n (old) => {\n if (!old) return old;\n return {\n ...old,\n pages: old.pages.map((page) => ({\n ...page,\n data: page.data.map((u) =>\n u.id === userId ? { ...u, in_project: false } : u\n ),\n })),\n };\n }\n );\n\n queryClient.setQueriesData<InfiniteData<UsersPage<ProjectUser>>>(\n { queryKey: LIST_PROJECT_USERS_BASE_KEY(projectId), exact: false },\n (old) => {\n if (!old?.pages.length) return old;\n return {\n ...old,\n pages: old.pages.map((page, i) =>\n i === 0 ? { ...page, total: page.total - 1 } : page\n ),\n };\n }\n );\n\n return { prevAccountUsers, prevProjectUsers };\n },\n\n onError: (_err, _userId, ctx) => {\n ctx?.prevAccountUsers.forEach(([key, data]) => queryClient.setQueryData(key, data));\n ctx?.prevProjectUsers.forEach(([key, data]) => queryClient.setQueryData(key, data));\n },\n\n onSettled: () => {\n queryClient.invalidateQueries({ queryKey: LIST_PROJECT_USERS_BASE_KEY(projectId) });\n queryClient.invalidateQueries({ queryKey: LIST_ALL_ACCOUNT_USERS_BASE_KEY() });\n },\n });\n}\n"],"mappings":";AAEA,SAAS,gBAAgB,mBAAiC;AAC1D,SAAS,+BAA+B;AACxC,SAAS,mCAAmC;AAC5C,SAAS,uCAAuC;AAGzC,SAAS,qBAAqB,WAAmB;AACtD,QAAM,cAAc,eAAe;AAEnC,SAAO,YAAY;AAAA,IACjB,YAAY,CAAC,WACX,wBAAwB,EAAE,WAAW,OAAO,CAAC,MAAM,EAAE,CAAC;AAAA,IAExD,UAAU,OAAO,WAAW;AAC1B,YAAM,YAAY,cAAc,EAAE,UAAU,gCAAgC,EAAE,CAAC;AAC/E,YAAM,YAAY,cAAc,EAAE,UAAU,4BAA4B,SAAS,EAAE,CAAC;AAEpF,YAAM,mBAAmB,YAAY,eAAqD;AAAA,QACxF,UAAU,gCAAgC;AAAA,MAC5C,CAAC;AACD,YAAM,mBAAmB,YAAY,eAAqD;AAAA,QACxF,UAAU,4BAA4B,SAAS;AAAA,MACjD,CAAC;AAED,kBAAY;AAAA,QACV,EAAE,UAAU,gCAAgC,GAAG,OAAO,MAAM;AAAA,QAC5D,CAAC,QAAQ;AACP,cAAI,CAAC,IAAK,QAAO;AACjB,iBAAO;AAAA,YACL,GAAG;AAAA,YACH,OAAO,IAAI,MAAM,IAAI,CAAC,UAAU;AAAA,cAC9B,GAAG;AAAA,cACH,MAAM,KAAK,KAAK;AAAA,gBAAI,CAAC,MACnB,EAAE,OAAO,SAAS,EAAE,GAAG,GAAG,YAAY,MAAM,IAAI;AAAA,cAClD;AAAA,YACF,EAAE;AAAA,UACJ;AAAA,QACF;AAAA,MACF;AAEA,kBAAY;AAAA,QACV,EAAE,UAAU,4BAA4B,SAAS,GAAG,OAAO,MAAM;AAAA,QACjE,CAAC,QAAQ;AACP,cAAI,CAAC,KAAK,MAAM,OAAQ,QAAO;AAC/B,iBAAO;AAAA,YACL,GAAG;AAAA,YACH,OAAO,IAAI,MAAM;AAAA,cAAI,CAAC,MAAM,MAC1B,MAAM,IAAI,EAAE,GAAG,MAAM,OAAO,KAAK,QAAQ,EAAE,IAAI;AAAA,YACjD;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,aAAO,EAAE,kBAAkB,iBAAiB;AAAA,IAC9C;AAAA,IAEA,SAAS,CAAC,MAAM,SAAS,QAAQ;AAC/B,WAAK,iBAAiB,QAAQ,CAAC,CAAC,KAAK,IAAI,MAAM,YAAY,aAAa,KAAK,IAAI,CAAC;AAClF,WAAK,iBAAiB,QAAQ,CAAC,CAAC,KAAK,IAAI,MAAM,YAAY,aAAa,KAAK,IAAI,CAAC;AAAA,IACpF;AAAA,IAEA,WAAW,MAAM;AACf,kBAAY,kBAAkB,EAAE,UAAU,4BAA4B,SAAS,EAAE,CAAC;AAClF,kBAAY,kBAAkB,EAAE,UAAU,gCAAgC,EAAE,CAAC;AAAA,IAC/E;AAAA,EACF,CAAC;AACH;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@greatapps/common",
3
- "version": "1.1.188",
3
+ "version": "1.1.191",
4
4
  "description": "Shared library for GreatApps frontend applications",
5
5
  "main": "./dist/index.mjs",
6
6
  "types": "./src/index.ts",
@@ -0,0 +1,76 @@
1
+ 'use client';
2
+
3
+ import { useEffect, useRef } from 'react';
4
+ import { useAuth } from '../../providers/auth.provider';
5
+ import { useWhitelabel } from '../../providers/whitelabel.provider';
6
+ import { useActiveSubscription } from '../../modules/subscriptions/hooks/find-active-subscription.hook';
7
+
8
+ const V4_WHITELABEL_ID = 367568;
9
+
10
+ const CRISP_WEBSITE_ID = '3339a3ec-b4c6-4aac-8b86-45668fb7655c';
11
+ const CRISP_SCRIPT_URL = 'https://client.crisp.chat/l.js';
12
+ const CRISP_LOAD_DELAY = 800;
13
+
14
+ export function openCrispHelpdesk() {
15
+ if (typeof window !== 'undefined' && (window as any).$crisp) {
16
+ (window as any).$crisp.push(['do', 'helpdesk:search']);
17
+ }
18
+ }
19
+
20
+ export function CrispEmbed() {
21
+ const { user, account } = useAuth();
22
+ const { whitelabel } = useWhitelabel();
23
+ const { data: subscriptionData } = useActiveSubscription();
24
+ const scriptLoadedRef = useRef(false);
25
+
26
+ const subscription = subscriptionData?.data?.[0] ?? null;
27
+ const isV4 = whitelabel?.id === V4_WHITELABEL_ID;
28
+
29
+ // Load Crisp script (once, with 800ms delay)
30
+ useEffect(() => {
31
+ if (!user || scriptLoadedRef.current) return;
32
+
33
+ const win = window as any;
34
+ win.$crisp = [];
35
+ win.CRISP_WEBSITE_ID = CRISP_WEBSITE_ID;
36
+
37
+ const timeout = setTimeout(() => {
38
+ if (document.querySelector(`script[src="${CRISP_SCRIPT_URL}"]`)) return;
39
+ const s = document.createElement('script');
40
+ s.src = CRISP_SCRIPT_URL;
41
+ s.async = true;
42
+ document.head.appendChild(s);
43
+ scriptLoadedRef.current = true;
44
+ }, CRISP_LOAD_DELAY);
45
+
46
+ return () => clearTimeout(timeout);
47
+ }, [user]);
48
+
49
+ // Identify user
50
+ useEffect(() => {
51
+ const $crisp = (window as any).$crisp;
52
+ if (!user || !$crisp) return;
53
+
54
+ $crisp.push(['set', 'user:email', user.email]);
55
+ $crisp.push(['set', 'user:nickname', `${user.name} ${user.last_name}`.trim()]);
56
+ $crisp.push(['set', 'user:company', account?.name ?? '']);
57
+ $crisp.push(['set', 'user:phone', `${user.ddi}${user.phone}`]);
58
+
59
+ if (user.photo) {
60
+ $crisp.push(['set', 'user:avatar', user.photo]);
61
+ }
62
+
63
+ if (isV4) {
64
+ $crisp.push(['set', 'session:segments', [['company_v4']]]);
65
+ $crisp.push(['set', 'session:data', [[['Company', 'V4']]]]);
66
+ } else {
67
+ const planName = subscription?.plan_name ?? '';
68
+ $crisp.push(['set', 'session:segments', [[`plano_${planName}`]]]);
69
+ $crisp.push(['set', 'session:segments', [[`usuario_${user.profile}`]]]);
70
+ $crisp.push(['set', 'session:data', [[['Plano', planName]]]]);
71
+ $crisp.push(['set', 'session:data', [[['Usuario', user.profile]]]]);
72
+ }
73
+ }, [user, account, isV4, subscription?.plan_name]);
74
+
75
+ return null;
76
+ }
@@ -0,0 +1,114 @@
1
+ 'use client';
2
+
3
+ import { useEffect, useRef } from 'react';
4
+ import { usePathname } from 'next/navigation';
5
+ import { useAuth } from '../../providers/auth.provider';
6
+ import { useWhitelabel } from '../../providers/whitelabel.provider';
7
+ import { useActiveSubscription } from '../../modules/subscriptions/hooks/find-active-subscription.hook';
8
+
9
+ const V4_WHITELABEL_ID = 367568;
10
+
11
+ const FRILL_SCRIPT_URL = 'https://widget.frill.co/v2/container.js';
12
+ const FRILL_KEY = '2f77f232-a120-438e-8ef6-01912ffd1b99';
13
+
14
+ const EXCLUDED_ROUTES = [
15
+ '/login',
16
+ '/forgot-password',
17
+ '/register',
18
+ ];
19
+
20
+ const SURVEYS = [{ key: '7f59dbf6-b665-458a-80e2-778de47efe1c' }];
21
+ const WIDGETS = [
22
+ { key: '4a5ba13b-1150-49fe-aa15-f9a2da0ba909' },
23
+ { key: '720c0912-e6a4-495c-835e-3ff1f59d6dfc' },
24
+ ];
25
+
26
+ function initFrillLoader() {
27
+ const win = window as any;
28
+ if (win.Frill) return;
29
+
30
+ let counter = 0;
31
+ const queue: Record<number, any> = {};
32
+
33
+ win.Frill = function (action: string, params: any) {
34
+ let instance: any;
35
+ const id = counter++;
36
+ const promise: any = new Promise((resolve, reject) => {
37
+ queue[id] = {
38
+ params: [action, params],
39
+ resolve: (f: any) => {
40
+ instance = f;
41
+ resolve(f);
42
+ },
43
+ reject,
44
+ };
45
+ });
46
+ promise.destroy = () => {
47
+ delete queue[id];
48
+ instance?.destroy();
49
+ };
50
+ return promise;
51
+ };
52
+ win.Frill.q = queue;
53
+ }
54
+
55
+ function loadFrillScript() {
56
+ if (document.querySelector(`script[src="${FRILL_SCRIPT_URL}"]`)) return;
57
+ const anchor = document.getElementsByTagName('script')[0];
58
+ const script = document.createElement('script');
59
+ script.type = 'text/javascript';
60
+ script.async = true;
61
+ script.src = FRILL_SCRIPT_URL;
62
+ anchor?.parentNode?.insertBefore(script, anchor);
63
+ }
64
+
65
+ export function FrillEmbed() {
66
+ const pathname = usePathname();
67
+ const { user } = useAuth();
68
+ const { whitelabel } = useWhitelabel();
69
+ const { data: subscriptionData } = useActiveSubscription();
70
+ const containerRef = useRef<any>(null);
71
+
72
+ const subscription = subscriptionData?.data?.[0] ?? null;
73
+ const isExcluded = EXCLUDED_ROUTES.some((route) => pathname.startsWith(route));
74
+ const isV4 = whitelabel?.id === V4_WHITELABEL_ID;
75
+
76
+ useEffect(() => {
77
+ if (isExcluded || !user) return;
78
+
79
+ initFrillLoader();
80
+
81
+ if (document.readyState === 'complete' || document.readyState === 'interactive') {
82
+ loadFrillScript();
83
+ } else {
84
+ document.addEventListener('DOMContentLoaded', loadFrillScript);
85
+ }
86
+
87
+ const userData = {
88
+ id: String(user.id),
89
+ email: user.email,
90
+ name: `${user.name} ${user.last_name}`.trim(),
91
+ attributes: isV4
92
+ ? { company: 'V4' }
93
+ : { profile: user.profile, plan: subscription?.plan_name ?? '' },
94
+ };
95
+
96
+ const config: Record<string, any> = { key: FRILL_KEY, user: userData };
97
+ if (!isV4) {
98
+ config.surveys = SURVEYS;
99
+ config.widgets = WIDGETS;
100
+ }
101
+
102
+ const win = window as any;
103
+ containerRef.current = win.Frill('container', config);
104
+ win.Frill('identify', userData);
105
+
106
+ return () => {
107
+ containerRef.current?.destroy();
108
+ containerRef.current = null;
109
+ document.removeEventListener('DOMContentLoaded', loadFrillScript);
110
+ };
111
+ }, [user, isExcluded, isV4, subscription?.plan_name]);
112
+
113
+ return null;
114
+ }
@@ -3,7 +3,6 @@
3
3
  import { useEffect, useState } from "react";
4
4
  import { Plus, Settings, User, Users } from "lucide-react";
5
5
  import { UserAvatar } from "../ui/data-display/UserAvatar";
6
- import { useQueryClient, useMutation } from "@tanstack/react-query";
7
6
  import { Popover, PopoverContent, PopoverTrigger } from "../ui/overlay/Popover";
8
7
  import { Button } from "../ui/buttons/Button";
9
8
  import {
@@ -16,16 +15,10 @@ import {
16
15
  import { Checkbox } from "../ui/form/Checkbox";
17
16
  import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/overlay/Tooltip";
18
17
  import { cn } from "../../infra/utils/clsx";
19
- import {
20
- useListProjectUsers,
21
- LIST_PROJECT_USERS_BASE_KEY,
22
- } from "../../modules/projects/hooks/list-project-users.hook";
23
- import {
24
- useListAllAccountUsers,
25
- LIST_ALL_ACCOUNT_USERS_BASE_KEY,
26
- } from "../../modules/projects/hooks/list-all-account-users.hook";
27
- import { removeProjectUserAction } from "../../modules/projects/actions/remove-project-user.action";
28
- import { addProjectUserAction } from "../../modules/projects/actions/add-project-user.action";
18
+ import { useListProjectUsers } from "../../modules/projects/hooks/list-project-users.hook";
19
+ import { useListAllAccountUsers } from "../../modules/projects/hooks/list-all-account-users.hook";
20
+ import { useAddProjectUser } from "../../modules/projects/hooks/add-project-user.hook";
21
+ import { useRemoveProjectUser } from "../../modules/projects/hooks/remove-project-user.hook";
29
22
 
30
23
  export interface UsersSelectorPopoverProps {
31
24
  projectId?: number;
@@ -54,7 +47,6 @@ export function UsersSelectorPopover({
54
47
  align,
55
48
  contentClassName,
56
49
  }: UsersSelectorPopoverProps) {
57
- const queryClient = useQueryClient();
58
50
  const [open, setOpen] = useState(false);
59
51
  const [hoveredId, setHoveredId] = useState<number | null>(null);
60
52
  const [searchInput, setSearchInput] = useState("");
@@ -69,29 +61,14 @@ export function UsersSelectorPopover({
69
61
 
70
62
  const accountUsers = useListAllAccountUsers(search, id || undefined);
71
63
  const projectUsers = useListProjectUsers(id, "");
64
+ const addMutation = useAddProjectUser(id);
65
+ const removeMutation = useRemoveProjectUser(id);
72
66
 
73
67
  const allUsers = accountUsers.data?.pages.flatMap((p) => p.data) ?? [];
74
68
  const isLoading = accountUsers.isLoading;
75
69
  const isFetchingMore = accountUsers.isFetchingNextPage;
76
70
  const totalInProject = projectUsers.data?.pages[0]?.total ?? 0;
77
71
 
78
- const invalidate = () => {
79
- queryClient.invalidateQueries({ queryKey: LIST_PROJECT_USERS_BASE_KEY(id) });
80
- queryClient.invalidateQueries({ queryKey: LIST_ALL_ACCOUNT_USERS_BASE_KEY() });
81
- };
82
-
83
- const removeMutation = useMutation({
84
- mutationFn: (userId: number) =>
85
- removeProjectUserAction({ projectId: id, users: [userId] }),
86
- onSuccess: invalidate,
87
- });
88
-
89
- const addMutation = useMutation({
90
- mutationFn: (userId: number) =>
91
- addProjectUserAction({ projectId: id, users: [userId] }),
92
- onSuccess: invalidate,
93
- });
94
-
95
72
  const toggleUser = (userId: number, inProject: boolean, removable: boolean) => {
96
73
  if (inProject) {
97
74
  if (!removable) return;
package/src/index.ts CHANGED
@@ -256,6 +256,10 @@ export {
256
256
  TooltipProvider,
257
257
  } from "./components/ui/overlay/Tooltip";
258
258
 
259
+ // Embeds
260
+ export { FrillEmbed } from "./components/embeds/FrillEmbed";
261
+ export { CrispEmbed, openCrispHelpdesk } from "./components/embeds/CrispEmbed";
262
+
259
263
  // Store
260
264
  export { useMdSidebarStore } from "./store/useMdSidebarStore";
261
265
  export { useModalManager } from "./store/useModalManager";
@@ -0,0 +1,69 @@
1
+ 'use client';
2
+
3
+ import { useQueryClient, useMutation, InfiniteData } from '@tanstack/react-query';
4
+ import { addProjectUserAction } from '../actions/add-project-user.action';
5
+ import { LIST_PROJECT_USERS_BASE_KEY } from './list-project-users.hook';
6
+ import { LIST_ALL_ACCOUNT_USERS_BASE_KEY } from './list-all-account-users.hook';
7
+ import type { UsersPage, AccountUser, ProjectUser } from '../types';
8
+
9
+ export function useAddProjectUser(projectId: number) {
10
+ const queryClient = useQueryClient();
11
+
12
+ return useMutation({
13
+ mutationFn: (userId: number) =>
14
+ addProjectUserAction({ projectId, users: [userId] }),
15
+
16
+ onMutate: async (userId) => {
17
+ await queryClient.cancelQueries({ queryKey: LIST_ALL_ACCOUNT_USERS_BASE_KEY() });
18
+ await queryClient.cancelQueries({ queryKey: LIST_PROJECT_USERS_BASE_KEY(projectId) });
19
+
20
+ const prevAccountUsers = queryClient.getQueriesData<InfiniteData<UsersPage<AccountUser>>>({
21
+ queryKey: LIST_ALL_ACCOUNT_USERS_BASE_KEY(),
22
+ });
23
+ const prevProjectUsers = queryClient.getQueriesData<InfiniteData<UsersPage<ProjectUser>>>({
24
+ queryKey: LIST_PROJECT_USERS_BASE_KEY(projectId),
25
+ });
26
+
27
+ queryClient.setQueriesData<InfiniteData<UsersPage<AccountUser>>>(
28
+ { queryKey: LIST_ALL_ACCOUNT_USERS_BASE_KEY(), exact: false },
29
+ (old) => {
30
+ if (!old) return old;
31
+ return {
32
+ ...old,
33
+ pages: old.pages.map((page) => ({
34
+ ...page,
35
+ data: page.data.map((u) =>
36
+ u.id === userId ? { ...u, in_project: true } : u
37
+ ),
38
+ })),
39
+ };
40
+ }
41
+ );
42
+
43
+ queryClient.setQueriesData<InfiniteData<UsersPage<ProjectUser>>>(
44
+ { queryKey: LIST_PROJECT_USERS_BASE_KEY(projectId), exact: false },
45
+ (old) => {
46
+ if (!old?.pages.length) return old;
47
+ return {
48
+ ...old,
49
+ pages: old.pages.map((page, i) =>
50
+ i === 0 ? { ...page, total: page.total + 1 } : page
51
+ ),
52
+ };
53
+ }
54
+ );
55
+
56
+ return { prevAccountUsers, prevProjectUsers };
57
+ },
58
+
59
+ onError: (_err, _userId, ctx) => {
60
+ ctx?.prevAccountUsers.forEach(([key, data]) => queryClient.setQueryData(key, data));
61
+ ctx?.prevProjectUsers.forEach(([key, data]) => queryClient.setQueryData(key, data));
62
+ },
63
+
64
+ onSettled: () => {
65
+ queryClient.invalidateQueries({ queryKey: LIST_PROJECT_USERS_BASE_KEY(projectId) });
66
+ queryClient.invalidateQueries({ queryKey: LIST_ALL_ACCOUNT_USERS_BASE_KEY() });
67
+ },
68
+ });
69
+ }
@@ -0,0 +1,69 @@
1
+ 'use client';
2
+
3
+ import { useQueryClient, useMutation, InfiniteData } from '@tanstack/react-query';
4
+ import { removeProjectUserAction } from '../actions/remove-project-user.action';
5
+ import { LIST_PROJECT_USERS_BASE_KEY } from './list-project-users.hook';
6
+ import { LIST_ALL_ACCOUNT_USERS_BASE_KEY } from './list-all-account-users.hook';
7
+ import type { UsersPage, AccountUser, ProjectUser } from '../types';
8
+
9
+ export function useRemoveProjectUser(projectId: number) {
10
+ const queryClient = useQueryClient();
11
+
12
+ return useMutation({
13
+ mutationFn: (userId: number) =>
14
+ removeProjectUserAction({ projectId, users: [userId] }),
15
+
16
+ onMutate: async (userId) => {
17
+ await queryClient.cancelQueries({ queryKey: LIST_ALL_ACCOUNT_USERS_BASE_KEY() });
18
+ await queryClient.cancelQueries({ queryKey: LIST_PROJECT_USERS_BASE_KEY(projectId) });
19
+
20
+ const prevAccountUsers = queryClient.getQueriesData<InfiniteData<UsersPage<AccountUser>>>({
21
+ queryKey: LIST_ALL_ACCOUNT_USERS_BASE_KEY(),
22
+ });
23
+ const prevProjectUsers = queryClient.getQueriesData<InfiniteData<UsersPage<ProjectUser>>>({
24
+ queryKey: LIST_PROJECT_USERS_BASE_KEY(projectId),
25
+ });
26
+
27
+ queryClient.setQueriesData<InfiniteData<UsersPage<AccountUser>>>(
28
+ { queryKey: LIST_ALL_ACCOUNT_USERS_BASE_KEY(), exact: false },
29
+ (old) => {
30
+ if (!old) return old;
31
+ return {
32
+ ...old,
33
+ pages: old.pages.map((page) => ({
34
+ ...page,
35
+ data: page.data.map((u) =>
36
+ u.id === userId ? { ...u, in_project: false } : u
37
+ ),
38
+ })),
39
+ };
40
+ }
41
+ );
42
+
43
+ queryClient.setQueriesData<InfiniteData<UsersPage<ProjectUser>>>(
44
+ { queryKey: LIST_PROJECT_USERS_BASE_KEY(projectId), exact: false },
45
+ (old) => {
46
+ if (!old?.pages.length) return old;
47
+ return {
48
+ ...old,
49
+ pages: old.pages.map((page, i) =>
50
+ i === 0 ? { ...page, total: page.total - 1 } : page
51
+ ),
52
+ };
53
+ }
54
+ );
55
+
56
+ return { prevAccountUsers, prevProjectUsers };
57
+ },
58
+
59
+ onError: (_err, _userId, ctx) => {
60
+ ctx?.prevAccountUsers.forEach(([key, data]) => queryClient.setQueryData(key, data));
61
+ ctx?.prevProjectUsers.forEach(([key, data]) => queryClient.setQueryData(key, data));
62
+ },
63
+
64
+ onSettled: () => {
65
+ queryClient.invalidateQueries({ queryKey: LIST_PROJECT_USERS_BASE_KEY(projectId) });
66
+ queryClient.invalidateQueries({ queryKey: LIST_ALL_ACCOUNT_USERS_BASE_KEY() });
67
+ },
68
+ });
69
+ }