analytica-frontend-lib 1.1.22 → 1.1.24

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.d.mts CHANGED
@@ -46,6 +46,7 @@ export { useApiConfig } from './Auth/useApiConfig/index.mjs';
46
46
  export { Quiz, QuizAlternative, QuizConnectDots, QuizContent, QuizDissertative, QuizFooter, QuizHeader, QuizHeaderResult, QuizImageQuestion, QuizListResult, QuizListResultByMateria, QuizMultipleChoice, QuizQuestionList, QuizResultHeaderTitle, QuizResultPerformance, QuizResultTitle, QuizTitle, QuizTrueOrFalse, getStatusBadge } from './Quiz/index.mjs';
47
47
  export { ANSWER_STATUS, Activity, Lesson, QUESTION_DIFFICULTY, QUESTION_STATUS, QUESTION_TYPE, Question, QuestionResult, QuizState, Simulated, UserAnswerItem, useQuizStore } from './Quiz/useQuizStore/index.mjs';
48
48
  export { default as LoadingModal } from './LoadingModal/index.mjs';
49
+ export { default as NotificationCard, NotificationGroup, NotificationItem } from './NotificationCard/index.mjs';
49
50
  import 'react/jsx-runtime';
50
51
 
51
52
  /**
package/dist/index.d.ts CHANGED
@@ -46,6 +46,7 @@ export { useApiConfig } from './Auth/useApiConfig/index.js';
46
46
  export { Quiz, QuizAlternative, QuizConnectDots, QuizContent, QuizDissertative, QuizFooter, QuizHeader, QuizHeaderResult, QuizImageQuestion, QuizListResult, QuizListResultByMateria, QuizMultipleChoice, QuizQuestionList, QuizResultHeaderTitle, QuizResultPerformance, QuizResultTitle, QuizTitle, QuizTrueOrFalse, getStatusBadge } from './Quiz/index.js';
47
47
  export { ANSWER_STATUS, Activity, Lesson, QUESTION_DIFFICULTY, QUESTION_STATUS, QUESTION_TYPE, Question, QuestionResult, QuizState, Simulated, UserAnswerItem, useQuizStore } from './Quiz/useQuizStore/index.js';
48
48
  export { default as LoadingModal } from './LoadingModal/index.js';
49
+ export { default as NotificationCard, NotificationGroup, NotificationItem } from './NotificationCard/index.js';
49
50
  import 'react/jsx-runtime';
50
51
 
51
52
  /**
package/dist/index.js CHANGED
@@ -74,6 +74,7 @@ __export(src_exports, {
74
74
  MultipleChoiceList: () => MultipleChoiceList,
75
75
  NavButton: () => NavButton_default,
76
76
  NotFound: () => NotFound_default,
77
+ NotificationCard: () => NotificationCard_default,
77
78
  ProfileMenuFooter: () => ProfileMenuFooter,
78
79
  ProfileMenuHeader: () => ProfileMenuHeader,
79
80
  ProfileMenuSection: () => ProfileMenuSection,
@@ -7947,28 +7948,58 @@ var handleUserData = (responseData, setUser) => {
7947
7948
  };
7948
7949
  function useUrlAuthentication(options) {
7949
7950
  const location = (0, import_react_router_dom2.useLocation)();
7951
+ const processedRef = (0, import_react26.useRef)(false);
7950
7952
  (0, import_react26.useEffect)(() => {
7951
7953
  const handleAuthentication = async () => {
7954
+ if (processedRef.current) {
7955
+ return;
7956
+ }
7952
7957
  const authParams = getAuthParams(location, options.extractParams);
7953
7958
  if (!hasValidAuthParams(authParams)) {
7954
7959
  return;
7955
7960
  }
7961
+ processedRef.current = true;
7956
7962
  try {
7957
7963
  options.setTokens({
7958
7964
  token: authParams.token,
7959
7965
  refreshToken: authParams.refreshToken
7960
7966
  });
7961
- const response = await options.api.get(options.endpoint, {
7962
- headers: {
7963
- Authorization: `Bearer ${authParams.token}`
7967
+ const maxRetries = options.maxRetries || 3;
7968
+ const retryDelay = options.retryDelay || 1e3;
7969
+ let retries = 0;
7970
+ let sessionData = null;
7971
+ while (retries < maxRetries && !sessionData) {
7972
+ try {
7973
+ const response = await options.api.get(options.endpoint, {
7974
+ headers: {
7975
+ Authorization: `Bearer ${authParams.token}`
7976
+ }
7977
+ });
7978
+ sessionData = response.data.data;
7979
+ break;
7980
+ } catch (error) {
7981
+ retries++;
7982
+ console.warn(
7983
+ `Tentativa ${retries}/${maxRetries} falhou para ${options.endpoint}:`,
7984
+ error
7985
+ );
7986
+ if (retries < maxRetries) {
7987
+ await new Promise(
7988
+ (resolve) => setTimeout(resolve, retryDelay * retries)
7989
+ );
7990
+ } else {
7991
+ throw error;
7992
+ }
7964
7993
  }
7965
- });
7966
- options.setSessionInfo(response.data.data);
7967
- handleProfileSelection(response.data.data, options.setSelectedProfile);
7968
- handleUserData(response.data.data, options.setUser);
7994
+ }
7995
+ options.setSessionInfo(sessionData);
7996
+ handleProfileSelection(sessionData, options.setSelectedProfile);
7997
+ handleUserData(sessionData, options.setUser);
7969
7998
  options.clearParamsFromURL?.();
7970
7999
  } catch (error) {
7971
8000
  console.error("Erro ao obter informa\xE7\xF5es da sess\xE3o:", error);
8001
+ processedRef.current = false;
8002
+ options.onError?.(error);
7972
8003
  }
7973
8004
  };
7974
8005
  handleAuthentication();
@@ -7981,7 +8012,10 @@ function useUrlAuthentication(options) {
7981
8012
  options.api,
7982
8013
  options.endpoint,
7983
8014
  options.extractParams,
7984
- options.clearParamsFromURL
8015
+ options.clearParamsFromURL,
8016
+ options.maxRetries,
8017
+ options.retryDelay,
8018
+ options.onError
7985
8019
  ]);
7986
8020
  }
7987
8021
 
@@ -10019,6 +10053,201 @@ var LoadingModal = (0, import_react29.forwardRef)(
10019
10053
  }
10020
10054
  );
10021
10055
  var loadingModal_default = LoadingModal;
10056
+
10057
+ // src/components/NotificationCard/NotificationCard.tsx
10058
+ var import_phosphor_react21 = require("phosphor-react");
10059
+
10060
+ // src/assets/img/no-notification-result.png
10061
+ var no_notification_result_default = "./no-notification-result-7Y3ACV6V.png";
10062
+
10063
+ // src/components/NotificationCard/NotificationCard.tsx
10064
+ var import_jsx_runtime41 = require("react/jsx-runtime");
10065
+ var SingleNotificationCard = ({
10066
+ title,
10067
+ message,
10068
+ time,
10069
+ isRead,
10070
+ onMarkAsRead,
10071
+ onDelete,
10072
+ onNavigate,
10073
+ actionLabel,
10074
+ className
10075
+ }) => {
10076
+ const handleMarkAsRead = (e) => {
10077
+ e.preventDefault();
10078
+ e.stopPropagation();
10079
+ if (!isRead) {
10080
+ onMarkAsRead();
10081
+ }
10082
+ };
10083
+ const handleDelete = (e) => {
10084
+ e.preventDefault();
10085
+ e.stopPropagation();
10086
+ onDelete();
10087
+ };
10088
+ const handleNavigate = (e) => {
10089
+ e.stopPropagation();
10090
+ if (onNavigate) {
10091
+ onNavigate();
10092
+ }
10093
+ };
10094
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
10095
+ "div",
10096
+ {
10097
+ className: cn(
10098
+ "flex flex-col justify-center items-start p-4 gap-2 w-full bg-background border-b border-border-200",
10099
+ "last:border-b-0",
10100
+ className
10101
+ ),
10102
+ children: [
10103
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "flex items-center gap-2 w-full", children: [
10104
+ !isRead && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "w-[7px] h-[7px] bg-info-300 rounded-full flex-shrink-0" }),
10105
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("h3", { className: "font-bold text-sm leading-4 text-text-950 flex-grow", children: title }),
10106
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(DropdownMenu_default, { children: [
10107
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
10108
+ DropdownMenuTrigger,
10109
+ {
10110
+ className: "flex-shrink-0 inline-flex items-center justify-center font-medium bg-transparent text-text-950 cursor-pointer hover:bg-info-50 w-6 h-6 rounded-lg",
10111
+ "aria-label": "Menu de a\xE7\xF5es",
10112
+ children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_phosphor_react21.DotsThreeVertical, { size: 24 })
10113
+ }
10114
+ ),
10115
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(DropdownMenuContent, { align: "end", className: "min-w-[160px]", children: [
10116
+ !isRead && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
10117
+ DropdownMenuItem,
10118
+ {
10119
+ onClick: handleMarkAsRead,
10120
+ className: "text-text-950",
10121
+ children: "Marcar como lida"
10122
+ }
10123
+ ),
10124
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(DropdownMenuItem, { onClick: handleDelete, className: "text-error-600", children: "Deletar" })
10125
+ ] })
10126
+ ] })
10127
+ ] }),
10128
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("p", { className: "text-sm leading-[21px] text-text-800 w-full", children: message }),
10129
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "flex items-center justify-between w-full", children: [
10130
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: "text-sm font-medium text-text-400", children: time }),
10131
+ onNavigate && actionLabel && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
10132
+ "button",
10133
+ {
10134
+ type: "button",
10135
+ onClick: handleNavigate,
10136
+ className: "text-sm font-medium text-info-600 hover:text-info-700 cursor-pointer",
10137
+ children: actionLabel
10138
+ }
10139
+ )
10140
+ ] })
10141
+ ]
10142
+ }
10143
+ );
10144
+ };
10145
+ var NotificationEmpty = () => {
10146
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "flex flex-col items-center justify-center gap-4 p-6 w-full", children: [
10147
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "w-20 h-20 flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
10148
+ "img",
10149
+ {
10150
+ src: no_notification_result_default,
10151
+ alt: "Sem notifica\xE7\xF5es",
10152
+ width: 82,
10153
+ height: 82,
10154
+ className: "object-contain"
10155
+ }
10156
+ ) }),
10157
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("h3", { className: "text-xl font-semibold text-text-950 text-center leading-[23px]", children: "Nenhuma notifica\xE7\xE3o no momento" }),
10158
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("p", { className: "text-sm font-normal text-text-400 text-center max-w-[316px] leading-[21px]", children: "Voc\xEA est\xE1 em dia com todas as novidades. Volte depois para conferir atualiza\xE7\xF5es!" })
10159
+ ] });
10160
+ };
10161
+ var NotificationList = ({
10162
+ groupedNotifications = [],
10163
+ loading = false,
10164
+ error = null,
10165
+ onRetry,
10166
+ onMarkAsReadById,
10167
+ onDeleteById,
10168
+ onNavigateById,
10169
+ getActionLabel,
10170
+ renderEmpty,
10171
+ className
10172
+ }) => {
10173
+ if (error) {
10174
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "flex flex-col items-center gap-4 p-6 w-full", children: [
10175
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("p", { className: "text-sm text-error-600", children: error }),
10176
+ onRetry && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
10177
+ "button",
10178
+ {
10179
+ type: "button",
10180
+ onClick: onRetry,
10181
+ className: "text-sm text-info-600 hover:text-info-700",
10182
+ children: "Tentar novamente"
10183
+ }
10184
+ )
10185
+ ] });
10186
+ }
10187
+ if (loading) {
10188
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "flex flex-col gap-0 w-full", children: ["skeleton-first", "skeleton-second", "skeleton-third"].map(
10189
+ (skeletonId) => /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
10190
+ SkeletonCard,
10191
+ {
10192
+ className: "p-4 border-b border-border-200"
10193
+ },
10194
+ skeletonId
10195
+ )
10196
+ ) });
10197
+ }
10198
+ if (!groupedNotifications || groupedNotifications.length === 0) {
10199
+ return renderEmpty ? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "w-full", children: renderEmpty() }) : /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(NotificationEmpty, {});
10200
+ }
10201
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: cn("flex flex-col gap-0 w-full", className), children: groupedNotifications.map((group, idx) => /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "flex flex-col", children: [
10202
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "flex items-end px-4 py-6 pb-4", children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("h4", { className: "text-lg font-bold text-text-500 flex-grow", children: group.label }) }),
10203
+ group.notifications.map((notification) => /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
10204
+ SingleNotificationCard,
10205
+ {
10206
+ title: notification.title,
10207
+ message: notification.message,
10208
+ time: notification.time,
10209
+ isRead: notification.isRead,
10210
+ onMarkAsRead: () => onMarkAsReadById?.(notification.id),
10211
+ onDelete: () => onDeleteById?.(notification.id),
10212
+ onNavigate: notification.entityType && notification.entityId && onNavigateById ? () => onNavigateById(
10213
+ notification.entityType,
10214
+ notification.entityId
10215
+ ) : void 0,
10216
+ actionLabel: getActionLabel?.(notification.entityType)
10217
+ },
10218
+ notification.id
10219
+ ))
10220
+ ] }, `${group.label}-${idx}`)) });
10221
+ };
10222
+ var NotificationCard = (props) => {
10223
+ if (props.groupedNotifications !== void 0 || props.notifications !== void 0 || props.loading || props.error) {
10224
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
10225
+ NotificationList,
10226
+ {
10227
+ ...props,
10228
+ groupedNotifications: props.groupedNotifications ?? (props.notifications ? [{ label: "Notifica\xE7\xF5es", notifications: props.notifications }] : [])
10229
+ }
10230
+ );
10231
+ }
10232
+ if (props.title !== void 0 && props.message !== void 0 && props.time !== void 0 && props.isRead !== void 0 && props.onMarkAsRead && props.onDelete) {
10233
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
10234
+ SingleNotificationCard,
10235
+ {
10236
+ title: props.title,
10237
+ message: props.message,
10238
+ time: props.time,
10239
+ isRead: props.isRead,
10240
+ onMarkAsRead: props.onMarkAsRead,
10241
+ onDelete: props.onDelete,
10242
+ onNavigate: props.onNavigate,
10243
+ actionLabel: props.actionLabel,
10244
+ className: props.className
10245
+ }
10246
+ );
10247
+ }
10248
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "flex flex-col items-center gap-4 p-6 w-full", children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("p", { className: "text-sm text-text-600", children: "Nenhuma notifica\xE7\xE3o configurada" }) });
10249
+ };
10250
+ var NotificationCard_default = NotificationCard;
10022
10251
  // Annotate the CommonJS export names for ESM import in node:
10023
10252
  0 && (module.exports = {
10024
10253
  ANSWER_STATUS,
@@ -10065,6 +10294,7 @@ var loadingModal_default = LoadingModal;
10065
10294
  MultipleChoiceList,
10066
10295
  NavButton,
10067
10296
  NotFound,
10297
+ NotificationCard,
10068
10298
  ProfileMenuFooter,
10069
10299
  ProfileMenuHeader,
10070
10300
  ProfileMenuSection,