analytica-frontend-lib 1.2.52 → 1.2.53

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.
Files changed (39) hide show
  1. package/dist/ActivitiesHistory/index.css +33 -0
  2. package/dist/ActivitiesHistory/index.css.map +1 -1
  3. package/dist/ActivityCardQuestionBanks/index.css +33 -0
  4. package/dist/ActivityCardQuestionBanks/index.css.map +1 -1
  5. package/dist/ActivityCardQuestionPreview/index.css +33 -0
  6. package/dist/ActivityCardQuestionPreview/index.css.map +1 -1
  7. package/dist/ActivityDetails/index.css +33 -0
  8. package/dist/ActivityDetails/index.css.map +1 -1
  9. package/dist/ActivityFilters/index.css +33 -0
  10. package/dist/ActivityFilters/index.css.map +1 -1
  11. package/dist/ActivityPreview/index.css +33 -0
  12. package/dist/ActivityPreview/index.css.map +1 -1
  13. package/dist/AlertManager/index.css +33 -0
  14. package/dist/AlertManager/index.css.map +1 -1
  15. package/dist/RecommendedLessonsHistory/index.css +33 -0
  16. package/dist/RecommendedLessonsHistory/index.css.map +1 -1
  17. package/dist/SendActivityModal/SendActivityModal.css +33 -0
  18. package/dist/SendActivityModal/SendActivityModal.css.map +1 -1
  19. package/dist/SendActivityModal/index.css +33 -0
  20. package/dist/SendActivityModal/index.css.map +1 -1
  21. package/dist/TableProvider/index.css +33 -0
  22. package/dist/TableProvider/index.css.map +1 -1
  23. package/dist/hooks/useChat.d.ts +112 -0
  24. package/dist/hooks/useChat.d.ts.map +1 -0
  25. package/dist/hooks/useChatRooms.d.ts +76 -0
  26. package/dist/hooks/useChatRooms.d.ts.map +1 -0
  27. package/dist/index.css +33 -0
  28. package/dist/index.css.map +1 -1
  29. package/dist/index.d.ts +8 -0
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +709 -0
  32. package/dist/index.js.map +1 -1
  33. package/dist/index.mjs +706 -0
  34. package/dist/index.mjs.map +1 -1
  35. package/dist/styles.css +33 -0
  36. package/dist/styles.css.map +1 -1
  37. package/dist/types/chat.d.ts +164 -0
  38. package/dist/types/chat.d.ts.map +1 -0
  39. package/package.json +2 -1
package/dist/index.mjs CHANGED
@@ -25003,6 +25003,704 @@ var ActivitiesHistory = ({
25003
25003
  }
25004
25004
  );
25005
25005
  };
25006
+
25007
+ // src/hooks/useChat.ts
25008
+ import { useState as useState50, useEffect as useEffect46, useCallback as useCallback27, useRef as useRef28 } from "react";
25009
+ var WS_STATES = {
25010
+ CONNECTING: 0,
25011
+ OPEN: 1,
25012
+ CLOSING: 2,
25013
+ CLOSED: 3
25014
+ };
25015
+ function useChat({
25016
+ wsUrl,
25017
+ token,
25018
+ roomId,
25019
+ userId,
25020
+ onConnect,
25021
+ onDisconnect,
25022
+ onError,
25023
+ autoReconnect = true,
25024
+ reconnectInterval = 3e3,
25025
+ maxReconnectAttempts = 5
25026
+ }) {
25027
+ const [isConnected, setIsConnected] = useState50(false);
25028
+ const [messages, setMessages] = useState50([]);
25029
+ const [participants, setParticipants] = useState50([]);
25030
+ const [error, setError] = useState50(null);
25031
+ const wsRef = useRef28(null);
25032
+ const reconnectAttemptsRef = useRef28(0);
25033
+ const reconnectTimeoutRef = useRef28(
25034
+ null
25035
+ );
25036
+ const isManualDisconnectRef = useRef28(false);
25037
+ const sendWsMessage = useCallback27((message) => {
25038
+ if (wsRef.current?.readyState === WS_STATES.OPEN) {
25039
+ wsRef.current.send(JSON.stringify(message));
25040
+ }
25041
+ }, []);
25042
+ const sendMessage = useCallback27(
25043
+ (content) => {
25044
+ const trimmedContent = content.trim();
25045
+ if (!trimmedContent) return;
25046
+ sendWsMessage({
25047
+ type: "message",
25048
+ payload: { content: trimmedContent }
25049
+ });
25050
+ },
25051
+ [sendWsMessage]
25052
+ );
25053
+ const leave = useCallback27(() => {
25054
+ isManualDisconnectRef.current = true;
25055
+ sendWsMessage({ type: "leave" });
25056
+ wsRef.current?.close(1e3, "User left");
25057
+ }, [sendWsMessage]);
25058
+ const handleMessage = useCallback27(
25059
+ (event) => {
25060
+ try {
25061
+ const data = JSON.parse(event.data);
25062
+ switch (data.type) {
25063
+ case "history":
25064
+ if (data.payload.messages) {
25065
+ setMessages(data.payload.messages);
25066
+ }
25067
+ break;
25068
+ case "participants":
25069
+ if (data.payload.participants) {
25070
+ setParticipants(data.payload.participants);
25071
+ }
25072
+ break;
25073
+ case "new_message":
25074
+ if (data.payload.message) {
25075
+ setMessages((prev) => [...prev, data.payload.message]);
25076
+ }
25077
+ break;
25078
+ case "user_joined":
25079
+ if (data.payload.user) {
25080
+ const user = data.payload.user;
25081
+ setParticipants((prev) => {
25082
+ const exists = prev.some(
25083
+ (p) => p.userInstitutionId === user.userInstitutionId
25084
+ );
25085
+ if (exists) {
25086
+ return prev.map(
25087
+ (p) => p.userInstitutionId === user.userInstitutionId ? { ...p, isOnline: true } : p
25088
+ );
25089
+ }
25090
+ return [
25091
+ ...prev,
25092
+ {
25093
+ userInstitutionId: user.userInstitutionId,
25094
+ name: user.name,
25095
+ photo: user.photo,
25096
+ role: user.role,
25097
+ isOnline: true
25098
+ }
25099
+ ];
25100
+ });
25101
+ }
25102
+ break;
25103
+ case "user_left":
25104
+ if (data.payload.user) {
25105
+ const user = data.payload.user;
25106
+ setParticipants(
25107
+ (prev) => prev.map(
25108
+ (p) => p.userInstitutionId === user.userInstitutionId ? { ...p, isOnline: false } : p
25109
+ )
25110
+ );
25111
+ }
25112
+ break;
25113
+ case "error": {
25114
+ const errorMessage = data.payload.message_text || "Erro desconhecido";
25115
+ setError(new Error(errorMessage));
25116
+ onError?.(new Error(errorMessage));
25117
+ break;
25118
+ }
25119
+ }
25120
+ } catch (err) {
25121
+ console.error("Error parsing WebSocket message:", err);
25122
+ }
25123
+ },
25124
+ [onError]
25125
+ );
25126
+ const connect = useCallback27(() => {
25127
+ const url = new URL(wsUrl);
25128
+ url.searchParams.set("roomId", roomId);
25129
+ url.searchParams.set("token", token);
25130
+ if (wsRef.current) {
25131
+ wsRef.current.close();
25132
+ }
25133
+ const ws = new WebSocket(url.toString());
25134
+ wsRef.current = ws;
25135
+ ws.onopen = () => {
25136
+ setIsConnected(true);
25137
+ setError(null);
25138
+ reconnectAttemptsRef.current = 0;
25139
+ onConnect?.();
25140
+ };
25141
+ ws.onmessage = handleMessage;
25142
+ ws.onerror = () => {
25143
+ const error2 = new Error("Erro na conex\xE3o WebSocket");
25144
+ setError(error2);
25145
+ onError?.(error2);
25146
+ };
25147
+ ws.onclose = (event) => {
25148
+ setIsConnected(false);
25149
+ onDisconnect?.();
25150
+ if (autoReconnect && !isManualDisconnectRef.current && reconnectAttemptsRef.current < maxReconnectAttempts && event.code !== 4001 && // Unauthorized
25151
+ event.code !== 4002 && // Missing roomId
25152
+ event.code !== 4003) {
25153
+ reconnectAttemptsRef.current += 1;
25154
+ reconnectTimeoutRef.current = setTimeout(() => {
25155
+ connect();
25156
+ }, reconnectInterval);
25157
+ }
25158
+ };
25159
+ }, [
25160
+ wsUrl,
25161
+ roomId,
25162
+ token,
25163
+ handleMessage,
25164
+ onConnect,
25165
+ onDisconnect,
25166
+ onError,
25167
+ autoReconnect,
25168
+ reconnectInterval,
25169
+ maxReconnectAttempts
25170
+ ]);
25171
+ const reconnect = useCallback27(() => {
25172
+ isManualDisconnectRef.current = false;
25173
+ reconnectAttemptsRef.current = 0;
25174
+ connect();
25175
+ }, [connect]);
25176
+ useEffect46(() => {
25177
+ isManualDisconnectRef.current = false;
25178
+ connect();
25179
+ return () => {
25180
+ isManualDisconnectRef.current = true;
25181
+ if (reconnectTimeoutRef.current) {
25182
+ clearTimeout(reconnectTimeoutRef.current);
25183
+ }
25184
+ wsRef.current?.close(1e3, "Component unmounted");
25185
+ };
25186
+ }, [connect]);
25187
+ return {
25188
+ isConnected,
25189
+ messages,
25190
+ participants,
25191
+ sendMessage,
25192
+ leave,
25193
+ error,
25194
+ reconnect,
25195
+ currentUserId: userId
25196
+ };
25197
+ }
25198
+ function createUseChat(baseWsUrl) {
25199
+ return (options) => useChat({ ...options, wsUrl: baseWsUrl });
25200
+ }
25201
+
25202
+ // src/hooks/useChatRooms.ts
25203
+ import { useState as useState51, useCallback as useCallback28 } from "react";
25204
+ function useChatRooms({
25205
+ apiClient
25206
+ }) {
25207
+ const [rooms, setRooms] = useState51([]);
25208
+ const [availableUsers, setAvailableUsers] = useState51([]);
25209
+ const [loading, setLoading] = useState51(false);
25210
+ const [error, setError] = useState51(null);
25211
+ const fetchRooms = useCallback28(async () => {
25212
+ setLoading(true);
25213
+ setError(null);
25214
+ try {
25215
+ const response = await apiClient.get("/chat/rooms");
25216
+ setRooms(response.data.rooms);
25217
+ } catch (err) {
25218
+ const error2 = err instanceof Error ? err : new Error("Erro ao carregar salas");
25219
+ setError(error2);
25220
+ console.error("Error fetching chat rooms:", err);
25221
+ } finally {
25222
+ setLoading(false);
25223
+ }
25224
+ }, [apiClient]);
25225
+ const fetchAvailableUsers = useCallback28(async () => {
25226
+ setLoading(true);
25227
+ setError(null);
25228
+ try {
25229
+ const response = await apiClient.get(
25230
+ "/chat/available-users"
25231
+ );
25232
+ setAvailableUsers(response.data.users);
25233
+ } catch (err) {
25234
+ const error2 = err instanceof Error ? err : new Error("Erro ao carregar usu\xE1rios");
25235
+ setError(error2);
25236
+ console.error("Error fetching available users:", err);
25237
+ } finally {
25238
+ setLoading(false);
25239
+ }
25240
+ }, [apiClient]);
25241
+ const createRoom = useCallback28(
25242
+ async (participantIds) => {
25243
+ setLoading(true);
25244
+ setError(null);
25245
+ try {
25246
+ const response = await apiClient.post(
25247
+ "/chat/rooms",
25248
+ {
25249
+ participantIds
25250
+ }
25251
+ );
25252
+ await fetchRooms();
25253
+ return response.data.room;
25254
+ } catch (err) {
25255
+ const error2 = err instanceof Error ? err : new Error("Erro ao criar sala");
25256
+ setError(error2);
25257
+ console.error("Error creating chat room:", err);
25258
+ return null;
25259
+ } finally {
25260
+ setLoading(false);
25261
+ }
25262
+ },
25263
+ [apiClient, fetchRooms]
25264
+ );
25265
+ const clearError = useCallback28(() => {
25266
+ setError(null);
25267
+ }, []);
25268
+ return {
25269
+ rooms,
25270
+ availableUsers,
25271
+ loading,
25272
+ error,
25273
+ fetchRooms,
25274
+ fetchAvailableUsers,
25275
+ createRoom,
25276
+ clearError
25277
+ };
25278
+ }
25279
+ function createUseChatRooms(apiClient) {
25280
+ return () => useChatRooms({ apiClient });
25281
+ }
25282
+
25283
+ // src/types/chat.ts
25284
+ var PROFILE_ROLES = /* @__PURE__ */ ((PROFILE_ROLES2) => {
25285
+ PROFILE_ROLES2["SUPER_ADMIN"] = "SUPER_ADMIN";
25286
+ PROFILE_ROLES2["GENERAL_MANAGER"] = "GENERAL_MANAGER";
25287
+ PROFILE_ROLES2["REGIONAL_MANAGER"] = "REGIONAL_MANAGER";
25288
+ PROFILE_ROLES2["UNIT_MANAGER"] = "UNIT_MANAGER";
25289
+ PROFILE_ROLES2["TEACHER"] = "TEACHER";
25290
+ PROFILE_ROLES2["STUDENT"] = "STUDENT";
25291
+ return PROFILE_ROLES2;
25292
+ })(PROFILE_ROLES || {});
25293
+ var CHAT_MESSAGE_TYPES = {
25294
+ TEXT: "text",
25295
+ SYSTEM: "system"
25296
+ };
25297
+
25298
+ // src/components/Chat/Chat.tsx
25299
+ import { useState as useState52, useEffect as useEffect47, useCallback as useCallback29 } from "react";
25300
+ import {
25301
+ PaperPlaneTiltIcon as PaperPlaneTiltIcon2,
25302
+ XIcon,
25303
+ PlusIcon,
25304
+ UsersIcon
25305
+ } from "@phosphor-icons/react";
25306
+ import { jsx as jsx104, jsxs as jsxs83 } from "react/jsx-runtime";
25307
+ var RoomItem = ({
25308
+ room,
25309
+ onClick,
25310
+ isActive
25311
+ }) => /* @__PURE__ */ jsx104(
25312
+ Button_default,
25313
+ {
25314
+ variant: "link",
25315
+ onClick,
25316
+ className: cn(
25317
+ "w-full p-3 rounded-lg text-left transition-colors justify-start h-auto",
25318
+ "hover:bg-background-100",
25319
+ isActive && "bg-primary-50 border-l-4 border-primary-500"
25320
+ ),
25321
+ children: /* @__PURE__ */ jsxs83("div", { className: "flex items-start gap-3 w-full", children: [
25322
+ /* @__PURE__ */ jsx104("div", { className: "w-10 h-10 rounded-full bg-primary-100 flex items-center justify-center flex-shrink-0", children: /* @__PURE__ */ jsx104(UsersIcon, { size: 20, className: "text-primary-600" }) }),
25323
+ /* @__PURE__ */ jsxs83("div", { className: "flex-1 min-w-0", children: [
25324
+ /* @__PURE__ */ jsx104(Text_default, { size: "sm", weight: "semibold", className: "text-text-900 truncate", children: room.name }),
25325
+ room.lastMessage && /* @__PURE__ */ jsxs83(Text_default, { size: "xs", className: "text-text-500 truncate mt-1", children: [
25326
+ room.lastMessage.senderName,
25327
+ ": ",
25328
+ room.lastMessage.content
25329
+ ] }),
25330
+ /* @__PURE__ */ jsxs83(Text_default, { size: "xs", className: "text-text-400 mt-1", children: [
25331
+ room.participantCount,
25332
+ " participantes"
25333
+ ] })
25334
+ ] })
25335
+ ] })
25336
+ }
25337
+ );
25338
+ var MessageBubble = ({
25339
+ message,
25340
+ isOwn
25341
+ }) => /* @__PURE__ */ jsxs83("div", { className: cn("flex gap-2 mb-3", isOwn && "flex-row-reverse"), children: [
25342
+ !isOwn && /* @__PURE__ */ jsx104("div", { className: "w-8 h-8 rounded-full bg-gray-200 flex items-center justify-center flex-shrink-0", children: message.senderPhoto ? /* @__PURE__ */ jsx104(
25343
+ "img",
25344
+ {
25345
+ src: message.senderPhoto,
25346
+ alt: message.senderName,
25347
+ className: "w-8 h-8 rounded-full object-cover"
25348
+ }
25349
+ ) : /* @__PURE__ */ jsx104(Text_default, { size: "xs", weight: "bold", className: "text-gray-600", children: message.senderName.charAt(0).toUpperCase() }) }),
25350
+ /* @__PURE__ */ jsxs83("div", { className: cn("max-w-[70%]", isOwn && "items-end"), children: [
25351
+ !isOwn && /* @__PURE__ */ jsx104(Text_default, { size: "xs", className: "text-text-500 mb-1", children: message.senderName }),
25352
+ /* @__PURE__ */ jsx104(
25353
+ "div",
25354
+ {
25355
+ className: cn(
25356
+ "px-4 py-2 rounded-2xl",
25357
+ isOwn ? "bg-primary-500 text-white rounded-br-md" : "bg-background-100 text-text-900 rounded-bl-md"
25358
+ ),
25359
+ children: /* @__PURE__ */ jsx104(Text_default, { size: "sm", children: message.content })
25360
+ }
25361
+ ),
25362
+ /* @__PURE__ */ jsx104(
25363
+ Text_default,
25364
+ {
25365
+ size: "xs",
25366
+ className: cn("text-text-400 mt-1", isOwn && "text-right"),
25367
+ children: new Date(message.createdAt).toLocaleTimeString("pt-BR", {
25368
+ hour: "2-digit",
25369
+ minute: "2-digit"
25370
+ })
25371
+ }
25372
+ )
25373
+ ] })
25374
+ ] });
25375
+ var ParticipantItem = ({ participant }) => /* @__PURE__ */ jsxs83("div", { className: "flex items-center gap-2 py-2", children: [
25376
+ /* @__PURE__ */ jsxs83("div", { className: "relative", children: [
25377
+ /* @__PURE__ */ jsx104("div", { className: "w-8 h-8 rounded-full bg-gray-200 flex items-center justify-center", children: participant.photo ? /* @__PURE__ */ jsx104(
25378
+ "img",
25379
+ {
25380
+ src: participant.photo,
25381
+ alt: participant.name,
25382
+ className: "w-8 h-8 rounded-full object-cover"
25383
+ }
25384
+ ) : /* @__PURE__ */ jsx104(Text_default, { size: "xs", weight: "bold", className: "text-gray-600", children: participant.name.charAt(0).toUpperCase() }) }),
25385
+ participant.isOnline && /* @__PURE__ */ jsx104("div", { className: "absolute bottom-0 right-0 w-3 h-3 bg-green-500 rounded-full border-2 border-white" })
25386
+ ] }),
25387
+ /* @__PURE__ */ jsxs83("div", { className: "flex-1 min-w-0", children: [
25388
+ /* @__PURE__ */ jsx104(Text_default, { size: "sm", className: "text-text-900 truncate", children: participant.name }),
25389
+ /* @__PURE__ */ jsx104(Text_default, { size: "xs", className: "text-text-500", children: participant.role })
25390
+ ] })
25391
+ ] });
25392
+ var UserSelector = ({
25393
+ users,
25394
+ selectedIds,
25395
+ onToggle
25396
+ }) => /* @__PURE__ */ jsx104("div", { className: "space-y-2 max-h-64 overflow-y-auto", children: users.map((user) => /* @__PURE__ */ jsxs83(
25397
+ Button_default,
25398
+ {
25399
+ variant: "link",
25400
+ onClick: () => onToggle(user.userInstitutionId),
25401
+ className: cn(
25402
+ "w-full flex items-center gap-3 p-3 rounded-lg transition-colors justify-start h-auto",
25403
+ selectedIds.has(user.userInstitutionId) ? "bg-primary-50 border border-primary-500" : "bg-background-50 hover:bg-background-100 border border-transparent"
25404
+ ),
25405
+ children: [
25406
+ /* @__PURE__ */ jsx104("div", { className: "w-10 h-10 rounded-full bg-gray-200 flex items-center justify-center", children: user.photo ? /* @__PURE__ */ jsx104(
25407
+ "img",
25408
+ {
25409
+ src: user.photo,
25410
+ alt: user.name,
25411
+ className: "w-10 h-10 rounded-full object-cover"
25412
+ }
25413
+ ) : /* @__PURE__ */ jsx104(Text_default, { size: "sm", weight: "bold", className: "text-gray-600", children: user.name.charAt(0).toUpperCase() }) }),
25414
+ /* @__PURE__ */ jsxs83("div", { className: "flex-1 text-left", children: [
25415
+ /* @__PURE__ */ jsx104(Text_default, { size: "sm", weight: "medium", className: "text-text-900", children: user.name }),
25416
+ /* @__PURE__ */ jsx104(Text_default, { size: "xs", className: "text-text-500", children: user.profileName })
25417
+ ] }),
25418
+ /* @__PURE__ */ jsx104(
25419
+ "div",
25420
+ {
25421
+ className: cn(
25422
+ "w-5 h-5 rounded-full border-2 flex items-center justify-center",
25423
+ selectedIds.has(user.userInstitutionId) ? "bg-primary-500 border-primary-500" : "border-gray-300"
25424
+ ),
25425
+ children: selectedIds.has(user.userInstitutionId) && /* @__PURE__ */ jsx104("div", { className: "w-2 h-2 bg-white rounded-full" })
25426
+ }
25427
+ )
25428
+ ]
25429
+ },
25430
+ user.userInstitutionId
25431
+ )) });
25432
+ function Chat({
25433
+ apiClient,
25434
+ wsUrl,
25435
+ token,
25436
+ userId,
25437
+ userName,
25438
+ userPhoto,
25439
+ userRole,
25440
+ className
25441
+ }) {
25442
+ const [view, setView] = useState52("list");
25443
+ const [selectedRoom, setSelectedRoom] = useState52(
25444
+ null
25445
+ );
25446
+ const [selectedUserIds, setSelectedUserIds] = useState52(
25447
+ /* @__PURE__ */ new Set()
25448
+ );
25449
+ const [messageInput, setMessageInput] = useState52("");
25450
+ const [showCreateModal, setShowCreateModal] = useState52(false);
25451
+ const {
25452
+ rooms,
25453
+ availableUsers,
25454
+ loading: roomsLoading,
25455
+ error: roomsError,
25456
+ fetchRooms,
25457
+ fetchAvailableUsers,
25458
+ createRoom
25459
+ } = useChatRooms({ apiClient });
25460
+ const {
25461
+ isConnected,
25462
+ messages,
25463
+ participants,
25464
+ sendMessage,
25465
+ error: chatError
25466
+ } = useChat({
25467
+ wsUrl,
25468
+ token,
25469
+ roomId: selectedRoom?.id || "",
25470
+ userId,
25471
+ onConnect: () => console.log("Connected to chat"),
25472
+ onDisconnect: () => console.log("Disconnected from chat"),
25473
+ onError: (err) => console.error("Chat error:", err)
25474
+ });
25475
+ const getRoleLabel = () => {
25476
+ return userRole === "TEACHER" /* TEACHER */ ? "Professor" : "Aluno";
25477
+ };
25478
+ useEffect47(() => {
25479
+ fetchRooms();
25480
+ }, [fetchRooms]);
25481
+ const handleSelectRoom = useCallback29((room) => {
25482
+ setSelectedRoom(room);
25483
+ setView("room");
25484
+ }, []);
25485
+ const handleOpenCreateModal = useCallback29(async () => {
25486
+ await fetchAvailableUsers();
25487
+ setSelectedUserIds(/* @__PURE__ */ new Set());
25488
+ setShowCreateModal(true);
25489
+ }, [fetchAvailableUsers]);
25490
+ const handleToggleUser = useCallback29((id) => {
25491
+ setSelectedUserIds((prev) => {
25492
+ const next = new Set(prev);
25493
+ if (next.has(id)) {
25494
+ next.delete(id);
25495
+ } else {
25496
+ next.add(id);
25497
+ }
25498
+ return next;
25499
+ });
25500
+ }, []);
25501
+ const handleCreateRoom = useCallback29(async () => {
25502
+ if (selectedUserIds.size === 0) return;
25503
+ const room = await createRoom(Array.from(selectedUserIds));
25504
+ if (room) {
25505
+ setShowCreateModal(false);
25506
+ setSelectedUserIds(/* @__PURE__ */ new Set());
25507
+ await fetchRooms();
25508
+ }
25509
+ }, [selectedUserIds, createRoom, fetchRooms]);
25510
+ const handleSendMessage = useCallback29(() => {
25511
+ if (!messageInput.trim()) return;
25512
+ sendMessage(messageInput);
25513
+ setMessageInput("");
25514
+ }, [messageInput, sendMessage]);
25515
+ const handleBackToList = useCallback29(() => {
25516
+ setSelectedRoom(null);
25517
+ setView("list");
25518
+ }, []);
25519
+ const renderMessagesContent = () => {
25520
+ if (chatError) {
25521
+ return /* @__PURE__ */ jsx104("div", { className: "flex items-center justify-center h-full", children: /* @__PURE__ */ jsxs83("div", { className: "text-center", children: [
25522
+ /* @__PURE__ */ jsx104(Text_default, { size: "sm", className: "text-red-500 mb-2", children: "Erro de conexao com o chat" }),
25523
+ /* @__PURE__ */ jsx104(Text_default, { size: "xs", className: "text-text-500", children: "Tentando reconectar..." })
25524
+ ] }) });
25525
+ }
25526
+ if (messages.length === 0) {
25527
+ return /* @__PURE__ */ jsx104("div", { className: "flex items-center justify-center h-full", children: /* @__PURE__ */ jsx104(Text_default, { size: "sm", className: "text-text-500", children: "Nenhuma mensagem ainda. Comece a conversa!" }) });
25528
+ }
25529
+ return messages.map((message) => /* @__PURE__ */ jsx104(
25530
+ MessageBubble,
25531
+ {
25532
+ message,
25533
+ isOwn: message.senderId === userId
25534
+ },
25535
+ message.id
25536
+ ));
25537
+ };
25538
+ const renderRoomList = () => /* @__PURE__ */ jsxs83("div", { className: "flex flex-col h-full", children: [
25539
+ /* @__PURE__ */ jsxs83("div", { className: "p-4 border-b border-background-200 flex items-center justify-between", children: [
25540
+ /* @__PURE__ */ jsxs83("div", { className: "flex items-center gap-3", children: [
25541
+ /* @__PURE__ */ jsx104("div", { className: "w-10 h-10 rounded-full bg-primary-100 flex items-center justify-center flex-shrink-0", children: userPhoto ? /* @__PURE__ */ jsx104(
25542
+ "img",
25543
+ {
25544
+ src: userPhoto,
25545
+ alt: userName,
25546
+ className: "w-10 h-10 rounded-full object-cover"
25547
+ }
25548
+ ) : /* @__PURE__ */ jsx104(Text_default, { size: "sm", weight: "bold", className: "text-primary-600", children: userName.charAt(0).toUpperCase() }) }),
25549
+ /* @__PURE__ */ jsxs83("div", { children: [
25550
+ /* @__PURE__ */ jsx104(Text_default, { size: "lg", weight: "bold", className: "text-text-900", children: "Conversas" }),
25551
+ /* @__PURE__ */ jsxs83(Text_default, { size: "xs", className: "text-text-500", children: [
25552
+ userName,
25553
+ " - ",
25554
+ getRoleLabel()
25555
+ ] })
25556
+ ] })
25557
+ ] }),
25558
+ /* @__PURE__ */ jsx104(
25559
+ Button_default,
25560
+ {
25561
+ variant: "solid",
25562
+ size: "small",
25563
+ onClick: handleOpenCreateModal,
25564
+ iconLeft: /* @__PURE__ */ jsx104(PlusIcon, { size: 16 }),
25565
+ children: "Nova conversa"
25566
+ }
25567
+ )
25568
+ ] }),
25569
+ /* @__PURE__ */ jsxs83("div", { className: "flex-1 overflow-y-auto p-2", children: [
25570
+ roomsError && /* @__PURE__ */ jsxs83("div", { className: "p-4 text-center", children: [
25571
+ /* @__PURE__ */ jsx104(Text_default, { size: "sm", className: "text-red-500 mb-2", children: "Erro ao carregar conversas" }),
25572
+ /* @__PURE__ */ jsx104(Button_default, { variant: "outline", size: "small", onClick: fetchRooms, children: "Tentar novamente" })
25573
+ ] }),
25574
+ !roomsError && roomsLoading && /* @__PURE__ */ jsx104("div", { className: "space-y-3 p-2", children: [1, 2, 3].map((i) => /* @__PURE__ */ jsxs83("div", { className: "flex items-center gap-3", children: [
25575
+ /* @__PURE__ */ jsx104(SkeletonRounded, { className: "w-10 h-10" }),
25576
+ /* @__PURE__ */ jsxs83("div", { className: "flex-1", children: [
25577
+ /* @__PURE__ */ jsx104(SkeletonText, { className: "w-3/4 h-4 mb-2" }),
25578
+ /* @__PURE__ */ jsx104(SkeletonText, { className: "w-1/2 h-3" })
25579
+ ] })
25580
+ ] }, i)) }),
25581
+ !roomsError && !roomsLoading && rooms.length === 0 && /* @__PURE__ */ jsx104(
25582
+ EmptyState_default,
25583
+ {
25584
+ title: "Nenhuma conversa",
25585
+ description: "Comece uma nova conversa clicando no botao acima"
25586
+ }
25587
+ ),
25588
+ !roomsError && !roomsLoading && rooms.length > 0 && /* @__PURE__ */ jsx104("div", { className: "space-y-1", children: rooms.map((room) => /* @__PURE__ */ jsx104(
25589
+ RoomItem,
25590
+ {
25591
+ room,
25592
+ onClick: () => handleSelectRoom(room),
25593
+ isActive: selectedRoom?.id === room.id
25594
+ },
25595
+ room.id
25596
+ )) })
25597
+ ] })
25598
+ ] });
25599
+ const renderChatRoom = () => {
25600
+ if (!selectedRoom) return null;
25601
+ return /* @__PURE__ */ jsxs83("div", { className: "flex h-full", children: [
25602
+ /* @__PURE__ */ jsxs83("div", { className: "flex-1 flex flex-col", children: [
25603
+ /* @__PURE__ */ jsxs83("div", { className: "p-4 border-b border-background-200 flex items-center gap-3", children: [
25604
+ /* @__PURE__ */ jsx104(Button_default, { variant: "link", size: "small", onClick: handleBackToList, children: /* @__PURE__ */ jsx104(XIcon, { size: 20 }) }),
25605
+ /* @__PURE__ */ jsxs83("div", { className: "flex-1", children: [
25606
+ /* @__PURE__ */ jsx104(Text_default, { size: "md", weight: "semibold", className: "text-text-900", children: selectedRoom.name }),
25607
+ /* @__PURE__ */ jsx104(Text_default, { size: "xs", className: "text-text-500", children: isConnected ? "Conectado" : "Conectando..." })
25608
+ ] })
25609
+ ] }),
25610
+ /* @__PURE__ */ jsx104("div", { className: "flex-1 overflow-y-auto p-4", children: renderMessagesContent() }),
25611
+ /* @__PURE__ */ jsx104("div", { className: "p-4 border-t border-background-200", children: /* @__PURE__ */ jsxs83("div", { className: "flex gap-2", children: [
25612
+ /* @__PURE__ */ jsx104(
25613
+ Input_default,
25614
+ {
25615
+ placeholder: "Digite sua mensagem...",
25616
+ value: messageInput,
25617
+ onChange: (e) => setMessageInput(e.target.value),
25618
+ onKeyDown: (e) => {
25619
+ if (e.key === "Enter" && !e.shiftKey) {
25620
+ e.preventDefault();
25621
+ handleSendMessage();
25622
+ }
25623
+ },
25624
+ className: "flex-1"
25625
+ }
25626
+ ),
25627
+ /* @__PURE__ */ jsx104(
25628
+ Button_default,
25629
+ {
25630
+ variant: "solid",
25631
+ onClick: handleSendMessage,
25632
+ disabled: !messageInput.trim() || !isConnected,
25633
+ children: /* @__PURE__ */ jsx104(PaperPlaneTiltIcon2, { size: 20 })
25634
+ }
25635
+ )
25636
+ ] }) })
25637
+ ] }),
25638
+ /* @__PURE__ */ jsxs83("div", { className: "w-64 border-l border-background-200 p-4 hidden lg:block", children: [
25639
+ /* @__PURE__ */ jsxs83(Text_default, { size: "sm", weight: "semibold", className: "text-text-900 mb-3", children: [
25640
+ "Participantes (",
25641
+ participants.length,
25642
+ ")"
25643
+ ] }),
25644
+ /* @__PURE__ */ jsx104("div", { className: "space-y-1", children: participants.map((participant) => /* @__PURE__ */ jsx104(
25645
+ ParticipantItem,
25646
+ {
25647
+ participant
25648
+ },
25649
+ participant.userInstitutionId
25650
+ )) })
25651
+ ] })
25652
+ ] });
25653
+ };
25654
+ return /* @__PURE__ */ jsxs83(
25655
+ "div",
25656
+ {
25657
+ className: cn(
25658
+ "bg-background rounded-xl border border-background-200 h-[600px]",
25659
+ className
25660
+ ),
25661
+ children: [
25662
+ view === "list" && renderRoomList(),
25663
+ view === "room" && renderChatRoom(),
25664
+ /* @__PURE__ */ jsx104(
25665
+ Modal_default,
25666
+ {
25667
+ isOpen: showCreateModal,
25668
+ onClose: () => setShowCreateModal(false),
25669
+ title: "Nova conversa",
25670
+ children: /* @__PURE__ */ jsxs83("div", { className: "p-4", children: [
25671
+ /* @__PURE__ */ jsx104(Text_default, { size: "sm", className: "text-text-600 mb-4", children: "Selecione os participantes para iniciar uma conversa" }),
25672
+ roomsLoading && /* @__PURE__ */ jsx104("div", { className: "space-y-3", children: [1, 2, 3].map((i) => /* @__PURE__ */ jsxs83("div", { className: "flex items-center gap-3", children: [
25673
+ /* @__PURE__ */ jsx104(SkeletonRounded, { className: "w-10 h-10" }),
25674
+ /* @__PURE__ */ jsx104(SkeletonText, { className: "flex-1 h-4" })
25675
+ ] }, i)) }),
25676
+ !roomsLoading && availableUsers.length === 0 && /* @__PURE__ */ jsx104(Text_default, { size: "sm", className: "text-text-500 text-center py-4", children: "Nenhum usuario disponivel para chat" }),
25677
+ !roomsLoading && availableUsers.length > 0 && /* @__PURE__ */ jsx104(
25678
+ UserSelector,
25679
+ {
25680
+ users: availableUsers,
25681
+ selectedIds: selectedUserIds,
25682
+ onToggle: handleToggleUser
25683
+ }
25684
+ ),
25685
+ /* @__PURE__ */ jsxs83("div", { className: "flex justify-end gap-2 mt-6", children: [
25686
+ /* @__PURE__ */ jsx104(Button_default, { variant: "outline", onClick: () => setShowCreateModal(false), children: "Cancelar" }),
25687
+ /* @__PURE__ */ jsx104(
25688
+ Button_default,
25689
+ {
25690
+ variant: "solid",
25691
+ onClick: handleCreateRoom,
25692
+ disabled: selectedUserIds.size === 0 || roomsLoading,
25693
+ children: "Criar conversa"
25694
+ }
25695
+ )
25696
+ ] })
25697
+ ] })
25698
+ }
25699
+ )
25700
+ ]
25701
+ }
25702
+ );
25703
+ }
25006
25704
  export {
25007
25705
  ACTIVITY_AVAILABILITY,
25008
25706
  ACTIVITY_FILTER_STATUS_OPTIONS,
@@ -25028,6 +25726,7 @@ export {
25028
25726
  Badge_default as Badge,
25029
25727
  BreadcrumbMenu,
25030
25728
  Button_default as Button,
25729
+ CHAT_MESSAGE_TYPES,
25031
25730
  QUESTION_STATUS2 as CORRECTION_QUESTION_STATUS,
25032
25731
  Calendar_default as Calendar,
25033
25732
  CardAccordation,
@@ -25042,6 +25741,7 @@ export {
25042
25741
  CardStatus,
25043
25742
  CardTest,
25044
25743
  CardTopic,
25744
+ Chat,
25045
25745
  CheckBox_default as CheckBox,
25046
25746
  CheckboxGroup,
25047
25747
  CheckboxList_default as CheckboxList,
@@ -25088,6 +25788,7 @@ export {
25088
25788
  NotFound_default as NotFound,
25089
25789
  NotificationCard_default as NotificationCard,
25090
25790
  NotificationEntityType,
25791
+ PROFILE_ROLES,
25091
25792
  ProfileMenuFooter,
25092
25793
  ProfileMenuHeader,
25093
25794
  ProfileMenuInfo,
@@ -25172,6 +25873,7 @@ export {
25172
25873
  Toast_default as Toast,
25173
25874
  Toaster_default as Toaster,
25174
25875
  VideoPlayer_default as VideoPlayer,
25876
+ WS_STATES,
25175
25877
  Whiteboard_default as Whiteboard,
25176
25878
  activitiesHistoryApiResponseSchema,
25177
25879
  activityModelsApiResponseSchema,
@@ -25188,6 +25890,8 @@ export {
25188
25890
  createUseActivitiesHistory,
25189
25891
  createUseActivityFiltersData,
25190
25892
  createUseActivityModels,
25893
+ createUseChat,
25894
+ createUseChatRooms,
25191
25895
  createUseNotificationStore,
25192
25896
  createUseNotifications,
25193
25897
  createUseQuestionsList,
@@ -25255,6 +25959,8 @@ export {
25255
25959
  useAuthStore,
25256
25960
  useBreadcrumb,
25257
25961
  useBreadcrumbBuilder,
25962
+ useChat,
25963
+ useChatRooms,
25258
25964
  useInstitutionId,
25259
25965
  useMobile,
25260
25966
  useQuestionFiltersStore,