analytica-frontend-lib 1.1.34 → 1.1.36

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
@@ -8060,6 +8060,15 @@ var ANSWER_STATUS = /* @__PURE__ */ ((ANSWER_STATUS2) => {
8060
8060
  ANSWER_STATUS2["NAO_RESPONDIDO"] = "NAO_RESPONDIDO";
8061
8061
  return ANSWER_STATUS2;
8062
8062
  })(ANSWER_STATUS || {});
8063
+ var SUBTYPE_ENUM = /* @__PURE__ */ ((SUBTYPE_ENUM2) => {
8064
+ SUBTYPE_ENUM2["PROVA"] = "PROVA";
8065
+ SUBTYPE_ENUM2["ENEM_PROVA_1"] = "ENEM_PROVA_1";
8066
+ SUBTYPE_ENUM2["ENEM_PROVA_2"] = "ENEM_PROVA_2";
8067
+ SUBTYPE_ENUM2["VESTIBULAR"] = "VESTIBULAR";
8068
+ SUBTYPE_ENUM2["SIMULADO"] = "SIMULADO";
8069
+ SUBTYPE_ENUM2["SIMULADAO"] = "SIMULADAO";
8070
+ return SUBTYPE_ENUM2;
8071
+ })(SUBTYPE_ENUM || {});
8063
8072
  var MINUTE_INTERVAL_MS = 6e4;
8064
8073
  var useQuizStore = create7()(
8065
8074
  devtools(
@@ -8745,26 +8754,65 @@ var QuizTitle = forwardRef19(
8745
8754
  formatTime: formatTime2,
8746
8755
  isStarted
8747
8756
  } = useQuizStore();
8757
+ const [showExitConfirmation, setShowExitConfirmation] = useState17(false);
8748
8758
  const totalQuestions = getTotalQuestions();
8749
8759
  const quizTitle = getQuizTitle();
8750
- return /* @__PURE__ */ jsxs32(
8751
- "div",
8752
- {
8753
- ref,
8754
- className: cn(
8755
- "flex flex-row justify-center items-center relative p-2",
8756
- className
8757
- ),
8758
- ...props,
8759
- children: [
8760
- /* @__PURE__ */ jsxs32("span", { className: "flex flex-col gap-2 text-center", children: [
8761
- /* @__PURE__ */ jsx39("p", { className: "text-text-950 font-bold text-md", children: quizTitle }),
8762
- /* @__PURE__ */ jsx39("p", { className: "text-text-600 text-xs", children: totalQuestions > 0 ? `${currentQuestionIndex + 1} de ${totalQuestions}` : "0 de 0" })
8763
- ] }),
8764
- /* @__PURE__ */ jsx39("span", { className: "absolute right-2", children: /* @__PURE__ */ jsx39(Badge_default, { variant: "outlined", action: "info", iconLeft: /* @__PURE__ */ jsx39(Clock2, {}), children: isStarted ? formatTime2(timeElapsed) : "00:00" }) })
8765
- ]
8760
+ const handleBackClick = () => {
8761
+ if (isStarted) {
8762
+ setShowExitConfirmation(true);
8763
+ } else {
8764
+ window.history.back();
8766
8765
  }
8767
- );
8766
+ };
8767
+ const handleConfirmExit = () => {
8768
+ setShowExitConfirmation(false);
8769
+ window.history.back();
8770
+ };
8771
+ const handleCancelExit = () => {
8772
+ setShowExitConfirmation(false);
8773
+ };
8774
+ return /* @__PURE__ */ jsxs32(Fragment9, { children: [
8775
+ /* @__PURE__ */ jsxs32(
8776
+ "div",
8777
+ {
8778
+ ref,
8779
+ className: cn(
8780
+ "flex flex-row justify-between items-center relative p-2",
8781
+ className
8782
+ ),
8783
+ ...props,
8784
+ children: [
8785
+ /* @__PURE__ */ jsx39(
8786
+ IconButton_default,
8787
+ {
8788
+ icon: /* @__PURE__ */ jsx39(CaretLeft3, { size: 24 }),
8789
+ size: "md",
8790
+ "aria-label": "Voltar",
8791
+ onClick: handleBackClick
8792
+ }
8793
+ ),
8794
+ /* @__PURE__ */ jsxs32("span", { className: "flex flex-col gap-2 text-center", children: [
8795
+ /* @__PURE__ */ jsx39("p", { className: "text-text-950 font-bold text-md", children: quizTitle }),
8796
+ /* @__PURE__ */ jsx39("p", { className: "text-text-600 text-xs", children: totalQuestions > 0 ? `${currentQuestionIndex + 1} de ${totalQuestions}` : "0 de 0" })
8797
+ ] }),
8798
+ /* @__PURE__ */ jsx39("span", { className: "flex flex-row items-center justify-center", children: /* @__PURE__ */ jsx39(Badge_default, { variant: "outlined", action: "info", iconLeft: /* @__PURE__ */ jsx39(Clock2, {}), children: isStarted ? formatTime2(timeElapsed) : "00:00" }) })
8799
+ ]
8800
+ }
8801
+ ),
8802
+ /* @__PURE__ */ jsx39(
8803
+ AlertDialog,
8804
+ {
8805
+ isOpen: showExitConfirmation,
8806
+ onChangeOpen: setShowExitConfirmation,
8807
+ title: "Deseja sair?",
8808
+ description: "Se voc\xEA sair do simulado agora, todas as respostas ser\xE3o perdidas.",
8809
+ cancelButtonLabel: "Voltar e revisar",
8810
+ submitButtonLabel: "Sair Mesmo Assim",
8811
+ onSubmit: handleConfirmExit,
8812
+ onCancel: handleCancelExit
8813
+ }
8814
+ )
8815
+ ] });
8768
8816
  }
8769
8817
  );
8770
8818
  var QuizSubTitle = forwardRef19(
@@ -9848,17 +9896,21 @@ var QuizFooter = forwardRef19(
9848
9896
  ] });
9849
9897
  }
9850
9898
  );
9851
- var QuizBadge = ({ subtype }) => {
9899
+ var QuizBadge = ({
9900
+ subtype
9901
+ }) => {
9852
9902
  switch (subtype) {
9853
- case "PROVA":
9854
- return /* @__PURE__ */ jsx39(Badge_default, { variant: "solid", action: "info", "data-testid": "quiz-badge", children: "Prova" });
9855
- case "ENEM":
9856
- return /* @__PURE__ */ jsx39(Badge_default, { variant: "solid", action: "info", "data-testid": "quiz-badge", children: "Enem" });
9857
- case "VESTIBULAR":
9858
- return /* @__PURE__ */ jsx39(Badge_default, { variant: "solid", action: "info", "data-testid": "quiz-badge", children: "Vestibular" });
9859
- case "SIMULADO":
9860
- case null:
9861
- return /* @__PURE__ */ jsx39(Badge_default, { variant: "solid", action: "info", "data-testid": "quiz-badge", children: "Simulado" });
9903
+ case "PROVA" /* PROVA */:
9904
+ return /* @__PURE__ */ jsx39(Badge_default, { variant: "examsOutlined", action: "exam2", "data-testid": "quiz-badge", children: "Prova" });
9905
+ case "ENEM_PROVA_1" /* ENEM_PROVA_1 */:
9906
+ case "ENEM_PROVA_2" /* ENEM_PROVA_2 */:
9907
+ return /* @__PURE__ */ jsx39(Badge_default, { variant: "examsOutlined", action: "exam1", "data-testid": "quiz-badge", children: "Enem" });
9908
+ case "VESTIBULAR" /* VESTIBULAR */:
9909
+ return /* @__PURE__ */ jsx39(Badge_default, { variant: "examsOutlined", action: "exam4", "data-testid": "quiz-badge", children: "Vestibular" });
9910
+ case "SIMULADO" /* SIMULADO */:
9911
+ case "SIMULADAO" /* SIMULADAO */:
9912
+ case void 0:
9913
+ return /* @__PURE__ */ jsx39(Badge_default, { variant: "examsOutlined", action: "exam3", "data-testid": "quiz-badge", children: "Simulad\xE3o" });
9862
9914
  default:
9863
9915
  return /* @__PURE__ */ jsx39(Badge_default, { variant: "solid", action: "info", "data-testid": "quiz-badge", children: subtype });
9864
9916
  }
@@ -9874,7 +9926,7 @@ var QuizResultHeaderTitle = forwardRef19(({ className, ...props }, ref) => {
9874
9926
  ...props,
9875
9927
  children: [
9876
9928
  /* @__PURE__ */ jsx39("p", { className: "text-text-950 font-bold text-2xl", children: "Resultado" }),
9877
- /* @__PURE__ */ jsx39(QuizBadge, { subtype: activeQuiz?.quiz.subtype || null })
9929
+ /* @__PURE__ */ jsx39(QuizBadge, { subtype: activeQuiz?.quiz.subtype || void 0 })
9878
9930
  ]
9879
9931
  }
9880
9932
  );
@@ -10154,8 +10206,283 @@ var LoadingModal = forwardRef20(
10154
10206
  var loadingModal_default = LoadingModal;
10155
10207
 
10156
10208
  // src/components/NotificationCard/NotificationCard.tsx
10157
- import { DotsThreeVertical as DotsThreeVertical3 } from "phosphor-react";
10158
- import { jsx as jsx41, jsxs as jsxs34 } from "react/jsx-runtime";
10209
+ import { DotsThreeVertical as DotsThreeVertical3, Bell as Bell2 } from "phosphor-react";
10210
+ import { useState as useState18, useEffect as useEffect16 } from "react";
10211
+
10212
+ // src/store/notificationStore.ts
10213
+ import { create as create8 } from "zustand";
10214
+ import { devtools as devtools2 } from "zustand/middleware";
10215
+
10216
+ // src/types/notifications.ts
10217
+ var NotificationEntityType = /* @__PURE__ */ ((NotificationEntityType2) => {
10218
+ NotificationEntityType2["ACTIVITY"] = "ACTIVITY";
10219
+ NotificationEntityType2["TRAIL"] = "TRAIL";
10220
+ NotificationEntityType2["GOAL"] = "GOAL";
10221
+ return NotificationEntityType2;
10222
+ })(NotificationEntityType || {});
10223
+
10224
+ // src/store/notificationStore.ts
10225
+ var mapBackendNotification = (backendNotification) => {
10226
+ let type = "GENERAL";
10227
+ let entityType = null;
10228
+ if (backendNotification.entityType) {
10229
+ const backendEntityType = backendNotification.entityType.toUpperCase();
10230
+ switch (backendEntityType) {
10231
+ case "ACTIVITY" /* ACTIVITY */:
10232
+ type = "ACTIVITY";
10233
+ entityType = "ACTIVITY" /* ACTIVITY */;
10234
+ break;
10235
+ case "TRAIL" /* TRAIL */:
10236
+ type = "TRAIL";
10237
+ entityType = "TRAIL" /* TRAIL */;
10238
+ break;
10239
+ case "GOAL" /* GOAL */:
10240
+ type = "GOAL";
10241
+ entityType = "GOAL" /* GOAL */;
10242
+ break;
10243
+ default:
10244
+ break;
10245
+ }
10246
+ }
10247
+ return {
10248
+ id: backendNotification.id,
10249
+ title: backendNotification.title,
10250
+ message: backendNotification.description,
10251
+ type,
10252
+ isRead: backendNotification.read,
10253
+ createdAt: new Date(backendNotification.createdAt),
10254
+ entityType,
10255
+ entityId: backendNotification.entityId,
10256
+ sender: backendNotification.sender,
10257
+ activity: backendNotification.activity,
10258
+ goal: backendNotification.goal
10259
+ };
10260
+ };
10261
+ var groupNotificationsByTime = (notifications) => {
10262
+ const now = /* @__PURE__ */ new Date();
10263
+ const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
10264
+ const lastWeek = new Date(today.getTime() - 7 * 24 * 60 * 60 * 1e3);
10265
+ const sortDesc = (a, b) => +new Date(b.createdAt) - +new Date(a.createdAt);
10266
+ const todayNotifications = notifications.filter((notification) => new Date(notification.createdAt) >= today).sort(sortDesc);
10267
+ const lastWeekNotifications = notifications.filter(
10268
+ (notification) => new Date(notification.createdAt) >= lastWeek && new Date(notification.createdAt) < today
10269
+ ).sort(sortDesc);
10270
+ const olderNotifications = notifications.filter((notification) => new Date(notification.createdAt) < lastWeek).sort(sortDesc);
10271
+ const groups = [];
10272
+ if (todayNotifications.length > 0) {
10273
+ groups.push({
10274
+ label: "Hoje",
10275
+ notifications: todayNotifications
10276
+ });
10277
+ }
10278
+ if (lastWeekNotifications.length > 0) {
10279
+ groups.push({
10280
+ label: "\xDAltima semana",
10281
+ notifications: lastWeekNotifications
10282
+ });
10283
+ }
10284
+ if (olderNotifications.length > 0) {
10285
+ groups.push({
10286
+ label: "Mais antigas",
10287
+ notifications: olderNotifications
10288
+ });
10289
+ }
10290
+ return groups;
10291
+ };
10292
+ var formatTimeAgo = (date) => {
10293
+ const now = /* @__PURE__ */ new Date();
10294
+ const diffInMs = now.getTime() - new Date(date).getTime();
10295
+ const diffInHours = Math.floor(diffInMs / (1e3 * 60 * 60));
10296
+ const diffInDays = Math.floor(diffInMs / (1e3 * 60 * 60 * 24));
10297
+ if (diffInHours < 24) {
10298
+ return `H\xE1 ${diffInHours}h`;
10299
+ } else if (diffInDays < 30) {
10300
+ const day = new Date(date).getDate();
10301
+ const months = [
10302
+ "Jan",
10303
+ "Fev",
10304
+ "Mar",
10305
+ "Abr",
10306
+ "Mai",
10307
+ "Jun",
10308
+ "Jul",
10309
+ "Ago",
10310
+ "Set",
10311
+ "Out",
10312
+ "Nov",
10313
+ "Dez"
10314
+ ];
10315
+ const month = months[new Date(date).getMonth()];
10316
+ return `${day} ${month}`;
10317
+ }
10318
+ return new Date(date).toLocaleDateString("pt-BR");
10319
+ };
10320
+ var createNotificationStore = (apiClient) => {
10321
+ return create8()(
10322
+ devtools2(
10323
+ (set, get) => ({
10324
+ // Initial state
10325
+ notifications: [],
10326
+ unreadCount: 0,
10327
+ loading: false,
10328
+ error: null,
10329
+ hasMore: true,
10330
+ currentPage: 1,
10331
+ // Actions
10332
+ fetchNotifications: async (params = {}) => {
10333
+ set({ loading: true, error: null });
10334
+ try {
10335
+ const response = await apiClient.get(
10336
+ "/notifications",
10337
+ { params: { ...params } }
10338
+ );
10339
+ const mappedNotifications = response.data.notifications.map(
10340
+ mapBackendNotification
10341
+ );
10342
+ const page = response.data.pagination.page;
10343
+ const totalPages = response.data.pagination.totalPages;
10344
+ const merged = params.page && params.page > 1 ? [...get().notifications, ...mappedNotifications] : mappedNotifications;
10345
+ const deduped = Array.from(
10346
+ new Map(merged.map((n) => [n.id, n])).values()
10347
+ );
10348
+ set({
10349
+ notifications: deduped,
10350
+ unreadCount: deduped.filter((n) => !n.isRead).length,
10351
+ hasMore: page < totalPages,
10352
+ currentPage: page,
10353
+ loading: false
10354
+ });
10355
+ } catch (error) {
10356
+ console.error("Error fetching notifications:", error);
10357
+ set({
10358
+ error: "Erro ao carregar notifica\xE7\xF5es",
10359
+ loading: false
10360
+ });
10361
+ }
10362
+ },
10363
+ markAsRead: async (id) => {
10364
+ const { notifications } = get();
10365
+ const notification = notifications.find((n) => n.id === id);
10366
+ if (notification?.isRead) {
10367
+ return;
10368
+ }
10369
+ try {
10370
+ await apiClient.patch(`/notifications/${id}`, { read: true });
10371
+ const updatedNotifications = notifications.map(
10372
+ (notification2) => notification2.id === id ? { ...notification2, isRead: true } : notification2
10373
+ );
10374
+ const unreadCount = updatedNotifications.filter(
10375
+ (n) => !n.isRead
10376
+ ).length;
10377
+ set({
10378
+ notifications: updatedNotifications,
10379
+ unreadCount
10380
+ });
10381
+ } catch (error) {
10382
+ console.error("Error marking notification as read:", error);
10383
+ set({ error: "Erro ao marcar notifica\xE7\xE3o como lida" });
10384
+ }
10385
+ },
10386
+ markAllAsRead: async () => {
10387
+ const { notifications } = get();
10388
+ try {
10389
+ const unreadNotifications = notifications.filter((n) => !n.isRead);
10390
+ await Promise.all(
10391
+ unreadNotifications.map(
10392
+ (notification) => apiClient.patch(`/notifications/${notification.id}`, {
10393
+ read: true
10394
+ })
10395
+ )
10396
+ );
10397
+ const updatedNotifications = notifications.map((notification) => ({
10398
+ ...notification,
10399
+ isRead: true
10400
+ }));
10401
+ set({
10402
+ notifications: updatedNotifications,
10403
+ unreadCount: 0
10404
+ });
10405
+ } catch (error) {
10406
+ console.error("Error marking all notifications as read:", error);
10407
+ set({ error: "Erro ao marcar todas as notifica\xE7\xF5es como lidas" });
10408
+ }
10409
+ },
10410
+ deleteNotification: async (id) => {
10411
+ const { notifications } = get();
10412
+ try {
10413
+ await apiClient.delete(`/notifications/${id}`);
10414
+ const updatedNotifications = notifications.filter(
10415
+ (notification) => notification.id !== id
10416
+ );
10417
+ const unreadCount = updatedNotifications.filter(
10418
+ (n) => !n.isRead
10419
+ ).length;
10420
+ set({
10421
+ notifications: updatedNotifications,
10422
+ unreadCount
10423
+ });
10424
+ } catch (error) {
10425
+ console.error("Error deleting notification:", error);
10426
+ set({ error: "Erro ao deletar notifica\xE7\xE3o" });
10427
+ }
10428
+ },
10429
+ clearNotifications: () => {
10430
+ set({
10431
+ notifications: [],
10432
+ unreadCount: 0,
10433
+ hasMore: false,
10434
+ currentPage: 1
10435
+ });
10436
+ },
10437
+ resetError: () => {
10438
+ set({ error: null });
10439
+ },
10440
+ getGroupedNotifications: () => {
10441
+ const { notifications } = get();
10442
+ return groupNotificationsByTime(notifications);
10443
+ }
10444
+ }),
10445
+ {
10446
+ name: "notification-store"
10447
+ }
10448
+ )
10449
+ );
10450
+ };
10451
+
10452
+ // src/components/NotificationCard/NotificationCard.tsx
10453
+ import { Fragment as Fragment10, jsx as jsx41, jsxs as jsxs34 } from "react/jsx-runtime";
10454
+ var NotificationEmpty = ({
10455
+ emptyStateImage,
10456
+ emptyStateTitle = "Nenhuma notifica\xE7\xE3o no momento",
10457
+ emptyStateDescription = "Voc\xEA est\xE1 em dia com todas as novidades. Volte depois para conferir atualiza\xE7\xF5es!"
10458
+ }) => {
10459
+ return /* @__PURE__ */ jsxs34("div", { className: "flex flex-col items-center justify-center gap-4 p-6 w-full", children: [
10460
+ emptyStateImage && /* @__PURE__ */ jsx41("div", { className: "w-20 h-20 flex items-center justify-center", children: /* @__PURE__ */ jsx41(
10461
+ "img",
10462
+ {
10463
+ src: emptyStateImage,
10464
+ alt: "Sem notifica\xE7\xF5es",
10465
+ width: 82,
10466
+ height: 82,
10467
+ className: "object-contain"
10468
+ }
10469
+ ) }),
10470
+ /* @__PURE__ */ jsx41("h3", { className: "text-xl font-semibold text-text-950 text-center leading-[23px]", children: emptyStateTitle }),
10471
+ /* @__PURE__ */ jsx41("p", { className: "text-sm font-normal text-text-400 text-center max-w-[316px] leading-[21px]", children: emptyStateDescription })
10472
+ ] });
10473
+ };
10474
+ var NotificationHeader = ({
10475
+ unreadCount,
10476
+ variant = "modal"
10477
+ }) => {
10478
+ return /* @__PURE__ */ jsxs34("div", { className: "flex items-center justify-between", children: [
10479
+ variant === "modal" ? /* @__PURE__ */ jsx41(Text_default, { size: "sm", weight: "bold", className: "text-text-950", children: "Notifica\xE7\xF5es" }) : /* @__PURE__ */ jsx41("h3", { className: "text-sm font-semibold text-text-950", children: "Notifica\xE7\xF5es" }),
10480
+ unreadCount > 0 && /* @__PURE__ */ jsxs34("span", { className: "px-2 py-1 bg-info-100 text-info-700 text-xs rounded-full", children: [
10481
+ unreadCount,
10482
+ " n\xE3o lidas"
10483
+ ] })
10484
+ ] });
10485
+ };
10159
10486
  var SingleNotificationCard = ({
10160
10487
  title,
10161
10488
  message,
@@ -10274,7 +10601,7 @@ var NotificationList = ({
10274
10601
  ) });
10275
10602
  }
10276
10603
  if (!groupedNotifications || groupedNotifications.length === 0) {
10277
- return renderEmpty ? /* @__PURE__ */ jsx41("div", { className: "w-full", children: renderEmpty() }) : /* @__PURE__ */ jsx41("div", { className: "flex flex-col items-center justify-center gap-4 p-6 w-full", children: /* @__PURE__ */ jsx41("p", { className: "text-sm text-text-400", children: "Nenhuma notifica\xE7\xE3o encontrada" }) });
10604
+ return renderEmpty ? /* @__PURE__ */ jsx41("div", { className: "w-full", children: renderEmpty() }) : /* @__PURE__ */ jsx41(NotificationEmpty, {});
10278
10605
  }
10279
10606
  return /* @__PURE__ */ jsx41("div", { className: cn("flex flex-col gap-0 w-full", className), children: groupedNotifications.map((group, idx) => /* @__PURE__ */ jsxs34("div", { className: "flex flex-col", children: [
10280
10607
  /* @__PURE__ */ jsx41("div", { className: "flex items-end px-4 py-6 pb-4", children: /* @__PURE__ */ jsx41("h4", { className: "text-lg font-bold text-text-500 flex-grow", children: group.label }) }),
@@ -10283,49 +10610,234 @@ var NotificationList = ({
10283
10610
  {
10284
10611
  title: notification.title,
10285
10612
  message: notification.message,
10286
- time: notification.time,
10613
+ time: notification.time ?? formatTimeAgo(new Date(notification.createdAt)),
10287
10614
  isRead: notification.isRead,
10288
10615
  onMarkAsRead: () => onMarkAsReadById?.(notification.id),
10289
10616
  onDelete: () => onDeleteById?.(notification.id),
10290
10617
  onNavigate: notification.entityType && notification.entityId && onNavigateById ? () => onNavigateById(
10291
- notification.entityType,
10292
- notification.entityId
10618
+ notification.entityType ?? void 0,
10619
+ notification.entityId ?? void 0
10293
10620
  ) : void 0,
10294
- actionLabel: getActionLabel?.(notification.entityType)
10621
+ actionLabel: getActionLabel?.(
10622
+ notification.entityType ?? void 0
10623
+ )
10295
10624
  },
10296
10625
  notification.id
10297
10626
  ))
10298
10627
  ] }, `${group.label}-${idx}`)) });
10299
10628
  };
10300
- var NotificationCard = (props) => {
10301
- if (props.groupedNotifications !== void 0 || props.notifications !== void 0 || props.loading || props.error) {
10302
- return /* @__PURE__ */ jsx41(
10303
- NotificationList,
10629
+ var NotificationCenter = ({
10630
+ isActive,
10631
+ onToggleActive,
10632
+ unreadCount = 0,
10633
+ groupedNotifications = [],
10634
+ loading = false,
10635
+ error = null,
10636
+ onRetry,
10637
+ onMarkAsReadById,
10638
+ onDeleteById,
10639
+ onNavigateById,
10640
+ getActionLabel,
10641
+ onFetchNotifications,
10642
+ onMarkAllAsRead,
10643
+ emptyStateImage,
10644
+ emptyStateTitle,
10645
+ emptyStateDescription,
10646
+ className
10647
+ }) => {
10648
+ const { isMobile } = useMobile();
10649
+ const [isModalOpen, setIsModalOpen] = useState18(false);
10650
+ const handleMobileClick = () => {
10651
+ setIsModalOpen(true);
10652
+ onFetchNotifications?.();
10653
+ };
10654
+ const handleDesktopClick = () => {
10655
+ onToggleActive?.();
10656
+ };
10657
+ useEffect16(() => {
10658
+ if (isActive) {
10659
+ onFetchNotifications?.();
10660
+ }
10661
+ }, [isActive, onFetchNotifications]);
10662
+ const handleNavigate = (entityType, entityId, onCleanup) => {
10663
+ onCleanup?.();
10664
+ onNavigateById?.(entityType, entityId);
10665
+ };
10666
+ const renderEmptyState = () => /* @__PURE__ */ jsx41(
10667
+ NotificationEmpty,
10668
+ {
10669
+ emptyStateImage,
10670
+ emptyStateTitle,
10671
+ emptyStateDescription
10672
+ }
10673
+ );
10674
+ if (isMobile) {
10675
+ return /* @__PURE__ */ jsxs34(Fragment10, { children: [
10676
+ /* @__PURE__ */ jsx41(
10677
+ IconButton_default,
10678
+ {
10679
+ active: isModalOpen,
10680
+ onClick: handleMobileClick,
10681
+ icon: /* @__PURE__ */ jsx41(Bell2, { size: 24, className: "text-primary" }),
10682
+ className
10683
+ }
10684
+ ),
10685
+ /* @__PURE__ */ jsx41(
10686
+ Modal_default,
10687
+ {
10688
+ isOpen: isModalOpen,
10689
+ onClose: () => setIsModalOpen(false),
10690
+ title: "Notifica\xE7\xF5es",
10691
+ size: "md",
10692
+ hideCloseButton: false,
10693
+ closeOnBackdropClick: true,
10694
+ closeOnEscape: true,
10695
+ children: /* @__PURE__ */ jsxs34("div", { className: "flex flex-col h-full max-h-[80vh]", children: [
10696
+ /* @__PURE__ */ jsx41("div", { className: "px-0 pb-3 border-b border-border-200", children: /* @__PURE__ */ jsxs34("div", { className: "flex items-center justify-between", children: [
10697
+ /* @__PURE__ */ jsx41(NotificationHeader, { unreadCount, variant: "modal" }),
10698
+ unreadCount > 0 && onMarkAllAsRead && /* @__PURE__ */ jsx41(
10699
+ "button",
10700
+ {
10701
+ type: "button",
10702
+ onClick: onMarkAllAsRead,
10703
+ className: "text-sm font-medium text-info-600 hover:text-info-700 cursor-pointer",
10704
+ children: "Marcar todas como lidas"
10705
+ }
10706
+ )
10707
+ ] }) }),
10708
+ /* @__PURE__ */ jsx41("div", { className: "flex-1 overflow-y-auto", children: /* @__PURE__ */ jsx41(
10709
+ NotificationList,
10710
+ {
10711
+ groupedNotifications,
10712
+ loading,
10713
+ error,
10714
+ onRetry,
10715
+ onMarkAsReadById,
10716
+ onDeleteById,
10717
+ onNavigateById: (entityType, entityId) => handleNavigate(
10718
+ entityType,
10719
+ entityId,
10720
+ () => setIsModalOpen(false)
10721
+ ),
10722
+ getActionLabel,
10723
+ renderEmpty: renderEmptyState
10724
+ }
10725
+ ) })
10726
+ ] })
10727
+ }
10728
+ )
10729
+ ] });
10730
+ }
10731
+ return /* @__PURE__ */ jsxs34(DropdownMenu_default, { children: [
10732
+ /* @__PURE__ */ jsx41(DropdownMenuTrigger, { className: "text-primary cursor-pointer", children: /* @__PURE__ */ jsx41(
10733
+ IconButton_default,
10304
10734
  {
10305
- ...props,
10306
- groupedNotifications: props.groupedNotifications ?? (props.notifications ? [{ label: "Notifica\xE7\xF5es", notifications: props.notifications }] : [])
10735
+ active: isActive,
10736
+ onClick: handleDesktopClick,
10737
+ icon: /* @__PURE__ */ jsx41(
10738
+ Bell2,
10739
+ {
10740
+ size: 24,
10741
+ className: isActive ? "text-primary-950" : "text-primary"
10742
+ }
10743
+ ),
10744
+ className
10307
10745
  }
10308
- );
10309
- }
10310
- if (props.title !== void 0 && props.message !== void 0 && props.time !== void 0 && props.isRead !== void 0 && props.onMarkAsRead && props.onDelete) {
10311
- return /* @__PURE__ */ jsx41(
10312
- SingleNotificationCard,
10746
+ ) }),
10747
+ /* @__PURE__ */ jsx41(
10748
+ DropdownMenuContent,
10313
10749
  {
10314
- title: props.title,
10315
- message: props.message,
10316
- time: props.time,
10317
- isRead: props.isRead,
10318
- onMarkAsRead: props.onMarkAsRead,
10319
- onDelete: props.onDelete,
10320
- onNavigate: props.onNavigate,
10321
- actionLabel: props.actionLabel,
10322
- className: props.className
10750
+ className: "min-w-[320px] max-w-[400px] max-h-[500px] overflow-hidden",
10751
+ side: "bottom",
10752
+ align: "end",
10753
+ children: /* @__PURE__ */ jsxs34("div", { className: "flex flex-col", children: [
10754
+ /* @__PURE__ */ jsx41("div", { className: "px-4 py-3 border-b border-border-200", children: /* @__PURE__ */ jsxs34("div", { className: "flex items-center justify-between", children: [
10755
+ /* @__PURE__ */ jsx41(
10756
+ NotificationHeader,
10757
+ {
10758
+ unreadCount,
10759
+ variant: "dropdown"
10760
+ }
10761
+ ),
10762
+ unreadCount > 0 && onMarkAllAsRead && /* @__PURE__ */ jsx41(
10763
+ "button",
10764
+ {
10765
+ type: "button",
10766
+ onClick: onMarkAllAsRead,
10767
+ className: "text-sm font-medium text-info-600 hover:text-info-700 cursor-pointer",
10768
+ children: "Marcar todas como lidas"
10769
+ }
10770
+ )
10771
+ ] }) }),
10772
+ /* @__PURE__ */ jsx41("div", { className: "max-h-[350px] overflow-y-auto", children: /* @__PURE__ */ jsx41(
10773
+ NotificationList,
10774
+ {
10775
+ groupedNotifications,
10776
+ loading,
10777
+ error,
10778
+ onRetry,
10779
+ onMarkAsReadById,
10780
+ onDeleteById,
10781
+ onNavigateById: (entityType, entityId) => handleNavigate(entityType, entityId, onToggleActive),
10782
+ getActionLabel,
10783
+ renderEmpty: renderEmptyState
10784
+ }
10785
+ ) })
10786
+ ] })
10323
10787
  }
10324
- );
10788
+ )
10789
+ ] });
10790
+ };
10791
+ var NotificationCard = (props) => {
10792
+ switch (props.mode) {
10793
+ case "single":
10794
+ return /* @__PURE__ */ jsx41(
10795
+ SingleNotificationCard,
10796
+ {
10797
+ title: props.title,
10798
+ message: props.message,
10799
+ time: props.time,
10800
+ isRead: props.isRead,
10801
+ onMarkAsRead: props.onMarkAsRead,
10802
+ onDelete: props.onDelete,
10803
+ onNavigate: props.onNavigate,
10804
+ actionLabel: props.actionLabel,
10805
+ className: props.className
10806
+ }
10807
+ );
10808
+ case "list":
10809
+ return /* @__PURE__ */ jsx41(
10810
+ NotificationList,
10811
+ {
10812
+ groupedNotifications: props.groupedNotifications ?? (props.notifications ? [
10813
+ {
10814
+ label: "Notifica\xE7\xF5es",
10815
+ notifications: props.notifications
10816
+ }
10817
+ ] : []),
10818
+ loading: props.loading,
10819
+ error: props.error,
10820
+ onRetry: props.onRetry,
10821
+ onMarkAsReadById: props.onMarkAsReadById,
10822
+ onDeleteById: props.onDeleteById,
10823
+ onNavigateById: props.onNavigateById,
10824
+ getActionLabel: props.getActionLabel,
10825
+ renderEmpty: props.renderEmpty,
10826
+ className: props.className
10827
+ }
10828
+ );
10829
+ case "center":
10830
+ return /* @__PURE__ */ jsx41(NotificationCenter, { ...props });
10831
+ default:
10832
+ return /* @__PURE__ */ jsx41("div", { className: "flex flex-col items-center gap-4 p-6 w-full", children: /* @__PURE__ */ jsx41("p", { className: "text-sm text-text-600", children: "Modo de notifica\xE7\xE3o n\xE3o reconhecido" }) });
10325
10833
  }
10326
- return /* @__PURE__ */ jsx41("div", { className: "flex flex-col items-center gap-4 p-6 w-full", children: /* @__PURE__ */ jsx41("p", { className: "text-sm text-text-600", children: "Nenhuma notifica\xE7\xE3o configurada" }) });
10327
10834
  };
10328
10835
  var NotificationCard_default = NotificationCard;
10836
+
10837
+ // src/hooks/useNotificationStore.ts
10838
+ var createUseNotificationStore = (apiClient) => {
10839
+ return createNotificationStore(apiClient);
10840
+ };
10329
10841
  export {
10330
10842
  ANSWER_STATUS,
10331
10843
  Alert_default as Alert,
@@ -10372,6 +10884,7 @@ export {
10372
10884
  NavButton_default as NavButton,
10373
10885
  NotFound_default as NotFound,
10374
10886
  NotificationCard_default as NotificationCard,
10887
+ NotificationEntityType,
10375
10888
  ProfileMenuFooter,
10376
10889
  ProfileMenuHeader,
10377
10890
  ProfileMenuSection,
@@ -10404,6 +10917,7 @@ export {
10404
10917
  Radio_default as Radio,
10405
10918
  RadioGroup,
10406
10919
  RadioGroupItem,
10920
+ SUBTYPE_ENUM,
10407
10921
  Search_default as Search,
10408
10922
  Select_default as Select,
10409
10923
  SelectContent,
@@ -10427,7 +10941,10 @@ export {
10427
10941
  Toaster_default as Toaster,
10428
10942
  VideoPlayer_default as VideoPlayer,
10429
10943
  Whiteboard_default as Whiteboard,
10944
+ createNotificationStore,
10945
+ createUseNotificationStore,
10430
10946
  createZustandAuthAdapter,
10947
+ formatTimeAgo,
10431
10948
  getDeviceType,
10432
10949
  getRootDomain,
10433
10950
  getStatusBadge,