analytica-frontend-lib 1.0.68 → 1.0.70

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/index.mjs CHANGED
@@ -5030,8 +5030,314 @@ var SkeletonTable = forwardRef13(
5030
5030
  ] });
5031
5031
  }
5032
5032
  );
5033
+
5034
+ // src/components/Auth/Auth.tsx
5035
+ import {
5036
+ createContext,
5037
+ useContext,
5038
+ useEffect as useEffect6,
5039
+ useState as useState9,
5040
+ useCallback,
5041
+ useMemo as useMemo3
5042
+ } from "react";
5043
+ import { useLocation, Navigate } from "react-router-dom";
5044
+ import { Fragment as Fragment6, jsx as jsx28 } from "react/jsx-runtime";
5045
+ var AuthContext = createContext(void 0);
5046
+ var AuthProvider = ({
5047
+ children,
5048
+ checkAuthFn,
5049
+ signOutFn,
5050
+ initialAuthState = {},
5051
+ getUserFn,
5052
+ getSessionFn,
5053
+ getTokensFn
5054
+ }) => {
5055
+ const [authState, setAuthState] = useState9({
5056
+ isAuthenticated: false,
5057
+ isLoading: true,
5058
+ ...initialAuthState
5059
+ });
5060
+ const checkAuth = useCallback(async () => {
5061
+ try {
5062
+ setAuthState((prev) => ({ ...prev, isLoading: true }));
5063
+ if (!checkAuthFn) {
5064
+ setAuthState((prev) => ({
5065
+ ...prev,
5066
+ isAuthenticated: false,
5067
+ isLoading: false
5068
+ }));
5069
+ return false;
5070
+ }
5071
+ const isAuth = await checkAuthFn();
5072
+ setAuthState((prev) => ({
5073
+ ...prev,
5074
+ isAuthenticated: isAuth,
5075
+ isLoading: false,
5076
+ user: getUserFn ? getUserFn() : prev.user,
5077
+ sessionInfo: getSessionFn ? getSessionFn() : prev.sessionInfo,
5078
+ tokens: getTokensFn ? getTokensFn() : prev.tokens
5079
+ }));
5080
+ return isAuth;
5081
+ } catch (error) {
5082
+ console.error("Erro ao verificar autentica\xE7\xE3o:", error);
5083
+ setAuthState((prev) => ({
5084
+ ...prev,
5085
+ isAuthenticated: false,
5086
+ isLoading: false
5087
+ }));
5088
+ return false;
5089
+ }
5090
+ }, [checkAuthFn, getUserFn, getSessionFn, getTokensFn]);
5091
+ const signOut = useCallback(() => {
5092
+ if (signOutFn) {
5093
+ signOutFn();
5094
+ }
5095
+ setAuthState((prev) => ({
5096
+ ...prev,
5097
+ isAuthenticated: false,
5098
+ user: void 0,
5099
+ sessionInfo: void 0,
5100
+ tokens: void 0
5101
+ }));
5102
+ }, [signOutFn]);
5103
+ useEffect6(() => {
5104
+ checkAuth();
5105
+ }, [checkAuth]);
5106
+ const contextValue = useMemo3(
5107
+ () => ({
5108
+ ...authState,
5109
+ checkAuth,
5110
+ signOut
5111
+ }),
5112
+ [authState, checkAuth, signOut]
5113
+ );
5114
+ return /* @__PURE__ */ jsx28(AuthContext.Provider, { value: contextValue, children });
5115
+ };
5116
+ var useAuth = () => {
5117
+ const context = useContext(AuthContext);
5118
+ if (context === void 0) {
5119
+ throw new Error("useAuth deve ser usado dentro de um AuthProvider");
5120
+ }
5121
+ return context;
5122
+ };
5123
+ var ProtectedRoute = ({
5124
+ children,
5125
+ redirectTo = "/",
5126
+ loadingComponent,
5127
+ additionalCheck
5128
+ }) => {
5129
+ const { isAuthenticated, isLoading, ...authState } = useAuth();
5130
+ const defaultLoadingComponent = /* @__PURE__ */ jsx28("div", { className: "flex items-center justify-center min-h-screen", children: /* @__PURE__ */ jsx28("div", { className: "text-text-950 text-lg", children: "Carregando..." }) });
5131
+ if (isLoading) {
5132
+ return /* @__PURE__ */ jsx28(Fragment6, { children: loadingComponent || defaultLoadingComponent });
5133
+ }
5134
+ if (!isAuthenticated) {
5135
+ return /* @__PURE__ */ jsx28(Navigate, { to: redirectTo, replace: true });
5136
+ }
5137
+ if (additionalCheck && !additionalCheck({ isAuthenticated, isLoading, ...authState })) {
5138
+ return /* @__PURE__ */ jsx28(Navigate, { to: redirectTo, replace: true });
5139
+ }
5140
+ return /* @__PURE__ */ jsx28(Fragment6, { children });
5141
+ };
5142
+ var PublicRoute = ({
5143
+ children,
5144
+ redirectTo = "/painel",
5145
+ redirectIfAuthenticated = false,
5146
+ checkAuthBeforeRender = false
5147
+ }) => {
5148
+ const { isAuthenticated, isLoading } = useAuth();
5149
+ if (checkAuthBeforeRender && isLoading) {
5150
+ return /* @__PURE__ */ jsx28("div", { className: "flex items-center justify-center min-h-screen", children: /* @__PURE__ */ jsx28("div", { className: "text-text-950 text-lg", children: "Carregando..." }) });
5151
+ }
5152
+ if (isAuthenticated && redirectIfAuthenticated) {
5153
+ return /* @__PURE__ */ jsx28(Navigate, { to: redirectTo, replace: true });
5154
+ }
5155
+ return /* @__PURE__ */ jsx28(Fragment6, { children });
5156
+ };
5157
+ var withAuth = (Component, options = {}) => {
5158
+ return (props) => /* @__PURE__ */ jsx28(ProtectedRoute, { ...options, children: /* @__PURE__ */ jsx28(Component, { ...props }) });
5159
+ };
5160
+ var useAuthGuard = (options = {}) => {
5161
+ const authState = useAuth();
5162
+ const { requireAuth = true, customCheck } = options;
5163
+ const canAccess = !authState.isLoading && (requireAuth ? authState.isAuthenticated && (!customCheck || customCheck(authState)) : !authState.isAuthenticated || !customCheck || customCheck(authState));
5164
+ return {
5165
+ canAccess,
5166
+ isLoading: authState.isLoading,
5167
+ authState
5168
+ };
5169
+ };
5170
+ var useRouteAuth = (fallbackPath = "/") => {
5171
+ const { isAuthenticated, isLoading } = useAuth();
5172
+ const location = useLocation();
5173
+ const redirectToLogin = () => /* @__PURE__ */ jsx28(Navigate, { to: fallbackPath, state: { from: location }, replace: true });
5174
+ return {
5175
+ isAuthenticated,
5176
+ isLoading,
5177
+ redirectToLogin
5178
+ };
5179
+ };
5180
+
5181
+ // src/components/Tab/Tab.tsx
5182
+ import { forwardRef as forwardRef14 } from "react";
5183
+ import { Fragment as Fragment7, jsx as jsx29, jsxs as jsxs23 } from "react/jsx-runtime";
5184
+ var TAB_SIZE_CLASSES = {
5185
+ small: {
5186
+ container: "h-10 gap-1",
5187
+ tab: "px-3 py-2 text-sm",
5188
+ indicator: "h-0.5"
5189
+ },
5190
+ medium: {
5191
+ container: "h-12 gap-2",
5192
+ tab: "px-4 py-4 text-sm",
5193
+ indicator: "h-1"
5194
+ },
5195
+ large: {
5196
+ container: "h-14 gap-2",
5197
+ tab: "px-6 py-4 text-base",
5198
+ indicator: "h-1"
5199
+ }
5200
+ };
5201
+ var RESPONSIVE_WIDTH_CLASSES = {
5202
+ twoTabs: "w-[115px] sm:w-[204px]",
5203
+ threeTabs: "w-[100px] sm:w-[160px]",
5204
+ fourTabs: "w-[80px] sm:w-[140px]",
5205
+ fiveTabs: "w-[70px] sm:w-[120px]",
5206
+ default: "flex-1"
5207
+ };
5208
+ var Tab = forwardRef14(
5209
+ ({
5210
+ tabs,
5211
+ activeTab,
5212
+ onTabChange,
5213
+ size = "medium",
5214
+ responsive = true,
5215
+ className = "",
5216
+ ...props
5217
+ }, ref) => {
5218
+ const sizeClasses = TAB_SIZE_CLASSES[size];
5219
+ const getResponsiveWidthClass = (tabCount) => {
5220
+ if (!responsive) return RESPONSIVE_WIDTH_CLASSES.default;
5221
+ switch (tabCount) {
5222
+ case 2:
5223
+ return RESPONSIVE_WIDTH_CLASSES.twoTabs;
5224
+ case 3:
5225
+ return RESPONSIVE_WIDTH_CLASSES.threeTabs;
5226
+ case 4:
5227
+ return RESPONSIVE_WIDTH_CLASSES.fourTabs;
5228
+ case 5:
5229
+ return RESPONSIVE_WIDTH_CLASSES.fiveTabs;
5230
+ default:
5231
+ return RESPONSIVE_WIDTH_CLASSES.default;
5232
+ }
5233
+ };
5234
+ const handleTabClick = (tabId) => {
5235
+ const tab = tabs.find((t) => t.id === tabId);
5236
+ if (tab && !tab.disabled) {
5237
+ onTabChange(tabId);
5238
+ }
5239
+ };
5240
+ const wrapAroundIndex = (index, maxLength) => {
5241
+ if (index < 0) return maxLength - 1;
5242
+ if (index >= maxLength) return 0;
5243
+ return index;
5244
+ };
5245
+ const findNextValidTab = (startIndex, direction) => {
5246
+ let nextIndex = wrapAroundIndex(startIndex + direction, tabs.length);
5247
+ let attempts = 0;
5248
+ while (tabs[nextIndex]?.disabled && attempts < tabs.length) {
5249
+ nextIndex = wrapAroundIndex(nextIndex + direction, tabs.length);
5250
+ attempts++;
5251
+ }
5252
+ return nextIndex;
5253
+ };
5254
+ const handleArrowNavigation = (direction) => {
5255
+ const currentIndex = tabs.findIndex((tab) => tab.id === activeTab);
5256
+ const nextIndex = findNextValidTab(currentIndex, direction);
5257
+ if (!tabs[nextIndex]?.disabled && nextIndex !== currentIndex) {
5258
+ handleTabClick(tabs[nextIndex].id);
5259
+ }
5260
+ };
5261
+ const handleKeyDown = (event, tabId) => {
5262
+ if (event.key === "Enter" || event.key === " ") {
5263
+ event.preventDefault();
5264
+ handleTabClick(tabId);
5265
+ return;
5266
+ }
5267
+ if (event.key === "ArrowLeft" || event.key === "ArrowRight") {
5268
+ event.preventDefault();
5269
+ const direction = event.key === "ArrowLeft" ? -1 : 1;
5270
+ handleArrowNavigation(direction);
5271
+ }
5272
+ };
5273
+ const getTabClassNames = (isDisabled, isActive) => {
5274
+ if (isDisabled) {
5275
+ return "text-text-400 cursor-not-allowed opacity-50";
5276
+ }
5277
+ if (isActive) {
5278
+ return "text-text-950";
5279
+ }
5280
+ return "text-text-700 hover:text-text-800";
5281
+ };
5282
+ const tabWidthClass = getResponsiveWidthClass(tabs.length);
5283
+ const containerWidth = responsive && tabs.length <= 2 ? "w-[240px] sm:w-[416px]" : "w-full";
5284
+ return /* @__PURE__ */ jsx29(
5285
+ "div",
5286
+ {
5287
+ ref,
5288
+ className: `flex flex-row items-start ${sizeClasses.container} ${containerWidth} ${className}`,
5289
+ role: "tablist",
5290
+ ...props,
5291
+ children: tabs.map((tab) => {
5292
+ const isActive = tab.id === activeTab;
5293
+ const isDisabled = Boolean(tab.disabled);
5294
+ const tabClassNames = getTabClassNames(isDisabled, isActive);
5295
+ return /* @__PURE__ */ jsxs23(
5296
+ "button",
5297
+ {
5298
+ type: "button",
5299
+ role: "tab",
5300
+ "aria-selected": isActive,
5301
+ "aria-disabled": isDisabled,
5302
+ tabIndex: isActive ? 0 : -1,
5303
+ className: `
5304
+ relative flex flex-row justify-center items-center gap-2 rounded transition-colors isolate
5305
+ ${sizeClasses.tab}
5306
+ ${tabWidthClass}
5307
+ ${tabClassNames}
5308
+ ${!isDisabled && !isActive ? "hover:bg-background-50" : ""}
5309
+ focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-500 focus-visible:ring-offset-2
5310
+ `,
5311
+ onClick: () => handleTabClick(tab.id),
5312
+ onKeyDown: (e) => handleKeyDown(e, tab.id),
5313
+ disabled: isDisabled,
5314
+ "data-testid": `tab-${tab.id}`,
5315
+ children: [
5316
+ /* @__PURE__ */ jsx29("span", { className: "font-bold leading-4 tracking-[0.2px] truncate", children: responsive && tab.mobileLabel ? /* @__PURE__ */ jsxs23(Fragment7, { children: [
5317
+ /* @__PURE__ */ jsx29("span", { className: "sm:hidden", children: tab.mobileLabel }),
5318
+ /* @__PURE__ */ jsx29("span", { className: "hidden sm:inline", children: tab.label })
5319
+ ] }) : tab.label }),
5320
+ isActive && /* @__PURE__ */ jsx29(
5321
+ "div",
5322
+ {
5323
+ className: `absolute bottom-0 left-2 right-2 bg-primary-700 rounded-lg z-[2] ${sizeClasses.indicator}`,
5324
+ "data-testid": "active-indicator"
5325
+ }
5326
+ )
5327
+ ]
5328
+ },
5329
+ tab.id
5330
+ );
5331
+ })
5332
+ }
5333
+ );
5334
+ }
5335
+ );
5336
+ Tab.displayName = "Tab";
5337
+ var Tab_default = Tab;
5033
5338
  export {
5034
5339
  Alert_default as Alert,
5340
+ AuthProvider,
5035
5341
  Badge_default as Badge,
5036
5342
  Button_default as Button,
5037
5343
  Calendar_default as Calendar,
@@ -5067,6 +5373,8 @@ export {
5067
5373
  ProfileMenuTrigger,
5068
5374
  ProgressBar_default as ProgressBar,
5069
5375
  ProgressCircle_default as ProgressCircle,
5376
+ ProtectedRoute,
5377
+ PublicRoute,
5070
5378
  Radio_default as Radio,
5071
5379
  Select_default as Select,
5072
5380
  SelectContent,
@@ -5083,11 +5391,16 @@ export {
5083
5391
  SkeletonTable,
5084
5392
  SkeletonText,
5085
5393
  Stepper_default as Stepper,
5394
+ Tab_default as Tab,
5086
5395
  Table_default as Table,
5087
5396
  Text_default as Text,
5088
5397
  TextArea_default as TextArea,
5089
5398
  Toast_default as Toast,
5090
5399
  Toaster_default as Toaster,
5091
- ToastStore_default as useToastStore
5400
+ useAuth,
5401
+ useAuthGuard,
5402
+ useRouteAuth,
5403
+ ToastStore_default as useToastStore,
5404
+ withAuth
5092
5405
  };
5093
5406
  //# sourceMappingURL=index.mjs.map