organify-ui 0.3.28 → 0.3.29
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/{chunk-WYZBUQ5Y.js → chunk-7RCUPHNX.js} +17 -4
- package/dist/{chunk-WYZBUQ5Y.js.map → chunk-7RCUPHNX.js.map} +1 -1
- package/dist/{chunk-276ZWKXB.js → chunk-XXBUSG5Q.js} +7 -3
- package/dist/chunk-XXBUSG5Q.js.map +1 -0
- package/dist/{chunk-JIT64DWO.js → chunk-ZZRLEONE.js} +3 -3
- package/dist/{chunk-JIT64DWO.js.map → chunk-ZZRLEONE.js.map} +1 -1
- package/dist/components/chat/index.js +2 -2
- package/dist/components/notifications/index.js +2 -2
- package/dist/index.d.ts +1 -3
- package/dist/index.js +29 -29
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/dist/chunk-276ZWKXB.js.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { cn, useOrganifyApi, useOrganifyUser, useOrganifyWorkspace, useOrganifyGql, Drawer, DrawerContent, Skeleton, Badge, Avatar, AvatarFallback, TooltipProvider, Tooltip, TooltipTrigger, TooltipContent, ScrollArea } from './chunk-
|
|
1
|
+
import { cn, useOrganifyApi, useOrganifyUser, useOrganifyWorkspace, useOrganifyGql, useOrganifyLookupUser, Drawer, DrawerContent, Skeleton, Badge, Avatar, AvatarFallback, TooltipProvider, Tooltip, TooltipTrigger, TooltipContent, ScrollArea } from './chunk-XXBUSG5Q.js';
|
|
2
2
|
import { OrgBell, OrgDoor, OrgWave, OrgFolder, OrgCheckCircle, OrgSprint, OrgMail, OrgMention, OrgComment, OrgEdit, OrgBoard, OrgClose } from './chunk-MZKEDV5W.js';
|
|
3
3
|
import React, { useState, useRef, useCallback, useEffect } from 'react';
|
|
4
4
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
@@ -327,7 +327,20 @@ function useNotifications(options = {}) {
|
|
|
327
327
|
}`,
|
|
328
328
|
{ filter: { workspaceId, limit, offset } }
|
|
329
329
|
);
|
|
330
|
-
|
|
330
|
+
let items = data?.notifications?.items ?? [];
|
|
331
|
+
if (items.length > 0) {
|
|
332
|
+
const lookupUser = useOrganifyLookupUser();
|
|
333
|
+
items = items.map((n) => {
|
|
334
|
+
if (n.metadata?.actorId && !n.metadata.actorName) {
|
|
335
|
+
const cached = lookupUser(String(n.metadata.actorId));
|
|
336
|
+
if (cached) {
|
|
337
|
+
n.metadata.actorName = cached.name;
|
|
338
|
+
if (!n.metadata.avatarUrl) n.metadata.avatarUrl = cached.avatarUrl ?? "";
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
return n;
|
|
342
|
+
});
|
|
343
|
+
}
|
|
331
344
|
setNotifications(items);
|
|
332
345
|
setUnreadCount(data?.unreadNotificationCount?.count ?? 0);
|
|
333
346
|
if (items.length > 0) {
|
|
@@ -956,5 +969,5 @@ function usePresence(options) {
|
|
|
956
969
|
}
|
|
957
970
|
|
|
958
971
|
export { NotificationBell, NotificationItem, NotificationList, OrganifyNotifications, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, PresenceAvatarStack, PresenceIndicator, useNotifications, usePresence };
|
|
959
|
-
//# sourceMappingURL=chunk-
|
|
960
|
-
//# sourceMappingURL=chunk-
|
|
972
|
+
//# sourceMappingURL=chunk-7RCUPHNX.js.map
|
|
973
|
+
//# sourceMappingURL=chunk-7RCUPHNX.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/notifications/notification-bell.tsx","../src/components/notifications/notification-item.tsx","../src/components/notifications/notification-list.tsx","../src/components/notifications/use-notifications.ts","../src/components/notifications/organify-notifications.tsx","../src/components/notifications/presence-indicator.tsx","../src/components/primitives/popover.tsx","../src/components/notifications/presence-avatar-stack.tsx","../src/components/notifications/use-presence.ts"],"names":["jsxs","jsx","useState","useRef","useEffect","Fragment","useCallback"],"mappings":"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","file":"chunk-WYZBUQ5Y.js","sourcesContent":["'use client';\n\n// ─────────────────────────────────────────────\n// NotificationBell — Bell icon with unread badge\n// ─────────────────────────────────────────────\n\nimport React from 'react';\nimport { cn } from '../../lib/utils';\nimport type { NotificationBellProps } from './types';\nimport { OrgBell as BellIcon } from '../../icons/system'\n\nexport const NotificationBell: React.FC<NotificationBellProps> = ({\n count,\n isOpen,\n onToggle,\n className,\n}) => {\n return (\n <button\n type=\"button\"\n onClick={onToggle}\n className={cn(\n 'relative inline-flex items-center justify-center',\n 'w-10 h-10 rounded-xl',\n 'bg-surface-glass/50 backdrop-blur-sm',\n 'border border-border-subtle/30',\n 'text-text-secondary hover:text-text-primary',\n 'hover:bg-surface-glass/70 hover:border-brand-primary/30',\n 'transition-all duration-[400ms]',\n 'focus:outline-none focus:ring-2 focus:ring-brand-primary/40',\n isOpen && 'bg-surface-glass/70 border-brand-primary/40 text-text-primary',\n className,\n )}\n aria-label={`Notifications${count > 0 ? ` (${count} unread)` : ''}`}\n aria-expanded={isOpen}\n >\n <BellIcon className={cn('w-5 h-5', count > 0 && 'animate-[bell_0.5s_ease-in-out]')} />\n\n {count > 0 && (\n <span\n className={cn(\n 'absolute -top-1 -right-1',\n 'flex items-center justify-center',\n 'min-w-[18px] h-[18px] px-1',\n 'rounded-full',\n 'bg-status-error text-white',\n 'text-[10px] font-bold leading-none',\n 'border-2 border-surface-base',\n 'animate-in zoom-in-50 duration-[400ms]',\n )}\n >\n {count > 99 ? '99+' : count}\n </span>\n )}\n </button>\n );\n};\n","'use client';\n\n// ─────────────────────────────────────────────\n// NotificationItem — Single notification entry\n// ─────────────────────────────────────────────\n\nimport React from 'react';\nimport { cn } from '../../lib/utils';\nimport type { NotificationItemProps, NotificationType } from './types';\nimport {\n OrgBoard, OrgEdit, OrgComment, OrgMention,\n OrgMail, OrgSprint, OrgCheckCircle, OrgFolder,\n OrgWave, OrgDoor, OrgBell, OrgClose,\n} from '../../icons';\n\n// ─── Type → Icon mapping ───────────────────\n\nconst typeIcons: Record<NotificationType, React.FC<{ className?: string }>> = {\n TASK_ASSIGNED: OrgBoard,\n TASK_UPDATED: OrgEdit,\n COMMENT_ADDED: OrgComment,\n CHAT_MESSAGE: OrgComment,\n MENTION: OrgMention,\n INVITATION: OrgMail,\n SPRINT_STARTED: OrgSprint,\n SPRINT_COMPLETED: OrgCheckCircle,\n PROJECT_UPDATED: OrgFolder,\n MEMBER_JOINED: OrgWave,\n MEMBER_LEFT: OrgDoor,\n OTHER: OrgBell,\n};\n\nconst typeColors: Record<NotificationType, string> = {\n TASK_ASSIGNED: 'bg-brand-primary/10 text-brand-primary',\n TASK_UPDATED: 'bg-status-warning/10 text-status-warning',\n COMMENT_ADDED: 'bg-accent-secondary/10 text-accent-secondary',\n CHAT_MESSAGE: 'bg-accent-tertiary/10 text-accent-tertiary',\n MENTION: 'bg-brand-primary/10 text-brand-primary',\n INVITATION: 'bg-status-success/10 text-status-success',\n SPRINT_STARTED: 'bg-status-info/10 text-status-info',\n SPRINT_COMPLETED: 'bg-status-success/10 text-status-success',\n PROJECT_UPDATED: 'bg-accent-secondary/10 text-accent-secondary',\n MEMBER_JOINED: 'bg-status-success/10 text-status-success',\n MEMBER_LEFT: 'bg-status-error/10 text-status-error',\n OTHER: 'bg-surface-elevated text-text-secondary',\n};\n\nfunction formatTimeAgo(dateStr: string): string {\n const now = Date.now();\n const date = new Date(dateStr).getTime();\n const diffMs = now - date;\n const diffMin = Math.floor(diffMs / 60000);\n\n if (diffMin < 1) return 'agora';\n if (diffMin < 60) return `${diffMin}m`;\n const diffHour = Math.floor(diffMin / 60);\n if (diffHour < 24) return `${diffHour}h`;\n const diffDay = Math.floor(diffHour / 24);\n if (diffDay < 7) return `${diffDay}d`;\n return new Date(dateStr).toLocaleDateString('pt-BR', { day: '2-digit', month: 'short' });\n}\n\nexport const NotificationItem: React.FC<NotificationItemProps> = ({\n notification,\n onMarkRead,\n onDelete,\n onClick,\n}) => {\n const IconComponent = typeIcons[notification.type] || OrgBell;\n const colorClass = typeColors[notification.type] || typeColors.OTHER;\n\n const handleClick = () => {\n if (!notification.read) onMarkRead(notification.id);\n onClick?.(notification);\n };\n\n return (\n <div\n role=\"button\"\n tabIndex={0}\n onClick={handleClick}\n onKeyDown={(e) => e.key === 'Enter' && handleClick()}\n className={cn(\n 'flex items-start gap-3 p-3 rounded-xl cursor-pointer',\n 'transition-all duration-[400ms]',\n 'hover:bg-surface-glass/50',\n !notification.read && 'bg-brand-primary/5 border-l-2 border-brand-primary',\n notification.read && 'opacity-70',\n )}\n >\n {/* Icon */}\n <div\n className={cn(\n 'flex-shrink-0 w-9 h-9 rounded-xl',\n 'flex items-center justify-center',\n 'text-sm',\n colorClass,\n )}\n >\n {notification.metadata?.avatarUrl ? (\n <img\n src={notification.metadata.avatarUrl}\n alt=\"\"\n className=\"w-9 h-9 rounded-xl object-cover\"\n />\n ) : (\n <IconComponent className=\"w-4 h-4\" />\n )}\n </div>\n\n {/* Content */}\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-start justify-between gap-2\">\n <p\n className={cn(\n 'text-sm leading-snug truncate',\n !notification.read ? 'font-semibold text-text-primary' : 'text-text-secondary',\n )}\n >\n {notification.title}\n </p>\n <span className=\"text-[10px] text-text-muted flex-shrink-0 mt-0.5\">\n {formatTimeAgo(notification.createdAt)}\n </span>\n </div>\n\n <p className=\"text-xs text-text-muted mt-0.5 line-clamp-2\">\n {notification.message}\n </p>\n\n {notification.metadata?.actorName && (\n <p className=\"text-[10px] text-text-muted mt-1\">\n por {notification.metadata.actorName}\n </p>\n )}\n </div>\n\n {/* Actions */}\n <div className=\"flex flex-col gap-1 flex-shrink-0 opacity-0 group-hover:opacity-100 transition-opacity\">\n {!notification.read && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n onMarkRead(notification.id);\n }}\n className=\"w-2 h-2 rounded-full bg-brand-primary flex-shrink-0 mt-1.5\"\n aria-label=\"Mark as read\"\n />\n )}\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n onDelete(notification.id);\n }}\n className={cn(\n 'text-[10px] text-text-muted hover:text-status-error',\n 'transition-colors',\n )}\n aria-label=\"Delete notification\"\n >\n <OrgClose className=\"w-3 h-3\" />\n </button>\n </div>\n </div>\n );\n};\n","'use client';\n\n// ─────────────────────────────────────────────\n// NotificationList — Scrollable notification panel\n// ─────────────────────────────────────────────\n\nimport React from 'react';\nimport { cn } from '../../lib/utils';\nimport { NotificationItem } from './notification-item';\nimport { OrgBell } from '../../icons';\nimport type { NotificationListProps } from './types';\n\nexport const NotificationList: React.FC<NotificationListProps> = ({\n notifications,\n loading,\n onMarkRead,\n onMarkAllRead,\n onDelete,\n onNotificationClick,\n className,\n}) => {\n const unreadCount = notifications.filter((n) => !n.read).length;\n\n return (\n <div\n className={cn(\n 'flex flex-col',\n 'w-[380px] max-h-[520px]',\n 'rounded-xl',\n 'bg-surface-base/95 backdrop-blur-xl',\n 'border border-border-subtle/40',\n 'shadow-2xl shadow-black/20',\n 'overflow-hidden',\n className,\n )}\n >\n {/* Header */}\n <div className=\"flex items-center justify-between px-4 py-3 border-b border-border-subtle/30\">\n <div className=\"flex items-center gap-2\">\n <h3 className=\"text-sm font-semibold text-text-primary\">Notificações</h3>\n {unreadCount > 0 && (\n <span\n className={cn(\n 'inline-flex items-center justify-center',\n 'min-w-[20px] h-5 px-1.5',\n 'rounded-full',\n 'bg-brand-primary/10 text-brand-primary',\n 'text-[10px] font-bold',\n )}\n >\n {unreadCount}\n </span>\n )}\n </div>\n\n {unreadCount > 0 && (\n <button\n type=\"button\"\n onClick={onMarkAllRead}\n className={cn(\n 'text-xs text-brand-primary hover:text-brand-primary/80',\n 'transition-colors',\n )}\n >\n Marcar todas como lidas\n </button>\n )}\n </div>\n\n {/* Content */}\n <div className=\"flex-1 overflow-y-auto overscroll-contain\">\n {loading && notifications.length === 0 ? (\n <div className=\"flex flex-col gap-3 p-4\">\n {[1, 2, 3].map((i) => (\n <div key={i} className=\"flex items-start gap-3 animate-pulse\">\n <div className=\"w-9 h-9 rounded-xl bg-surface-elevated\" />\n <div className=\"flex-1 space-y-2\">\n <div className=\"h-3 bg-surface-elevated rounded w-3/4\" />\n <div className=\"h-2 bg-surface-elevated rounded w-1/2\" />\n </div>\n </div>\n ))}\n </div>\n ) : notifications.length === 0 ? (\n <div className=\"flex flex-col items-center justify-center py-12 px-4\">\n <OrgBell className=\"w-8 h-8 text-text-muted mb-3\" />\n <p className=\"text-sm text-text-secondary font-medium\">Tudo em dia!</p>\n <p className=\"text-xs text-text-muted mt-1\">Nenhuma notificação por enquanto.</p>\n </div>\n ) : (\n <div className=\"p-2 space-y-0.5 group\">\n {notifications.map((notification) => (\n <NotificationItem\n key={notification.id}\n notification={notification}\n onMarkRead={onMarkRead}\n onDelete={onDelete}\n onClick={onNotificationClick}\n />\n ))}\n </div>\n )}\n </div>\n\n {/* Footer */}\n {notifications.length > 0 && (\n <div className=\"px-4 py-2.5 border-t border-border-subtle/30 text-center\">\n <button\n type=\"button\"\n className={cn(\n 'text-xs text-text-muted hover:text-text-secondary',\n 'transition-colors',\n )}\n >\n Ver todas as notificações\n </button>\n </div>\n )}\n </div>\n );\n};\n","// ─────────────────────────────────────────────\n// useNotifications — React hook for notification state\n// ─────────────────────────────────────────────\n// Pulls gatewayUrl, authToken, userId, workspaceId\n// from OrganifyProvider — no props needed.\n//\n// Uses graphql-ws subscription for real-time updates\n// instead of polling. Falls back to polling if\n// subscription fails or service URL not configured.\n// ─────────────────────────────────────────────\n\nimport { useState, useEffect, useCallback, useRef } from 'react';\nimport { useOrganifyApi, useOrganifyUser, useOrganifyWorkspace, useOrganifyGql } from '../../providers/organify-provider';\nimport type { Notification } from './types';\n\ninterface UseNotificationsOptions {\n /** Auto-fetch on mount (default true) */\n autoFetch?: boolean;\n /** Polling interval in ms as fallback (0 = no polling, default 0 since we use subscriptions) */\n pollingInterval?: number;\n}\n\ninterface UseNotificationsReturn {\n notifications: Notification[];\n unreadCount: number;\n loading: boolean;\n error: string | null;\n connected: boolean;\n fetchNotifications: (limit?: number, offset?: number) => Promise<void>;\n markAsRead: (id: string) => Promise<void>;\n markAllAsRead: () => Promise<void>;\n deleteNotification: (id: string) => Promise<void>;\n refetch: () => Promise<void>;\n}\n\nexport function useNotifications(options: UseNotificationsOptions = {}): UseNotificationsReturn {\n const { autoFetch = true, pollingInterval = 0 } = options;\n\n // ─── Pull from OrganifyProvider ───────\n const api = useOrganifyApi();\n const { gatewayUrl, authToken } = api;\n const notificationsServiceUrl = api.services?.notifications;\n const user = useOrganifyUser();\n const { workspace } = useOrganifyWorkspace();\n const userId = user?.id ?? '';\n const workspaceId = workspace?.id ?? '';\n\n const [notifications, setNotifications] = useState<Notification[]>([]);\n const [unreadCount, setUnreadCount] = useState(0);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [connected, setConnected] = useState(false);\n\n const pollingRef = useRef<ReturnType<typeof setInterval> | null>(null);\n const wsRef = useRef<WebSocket | null>(null);\n const reconnectCountRef = useRef(0);\n const reconnectTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const lastSeenRef = useRef<string | null>(null);\n\n // Notifications GraphQL uses centralized useOrganifyGql with 'notifications' endpoint.\n // Routes through gateway proxy (/api/graphql/notifications) which injects x-user-id from JWT cookie.\n const centralGql = useOrganifyGql();\n\n const gqlFetch = useCallback(\n async (query: string, variables?: Record<string, any>) => {\n return centralGql('notifications', query, variables);\n },\n [centralGql],\n );\n\n const fetchNotifications = useCallback(\n async (limit = 20, offset = 0) => {\n if (!workspaceId) return;\n setLoading(true);\n setError(null);\n try {\n const data = await gqlFetch(\n `query GetNotifications($filter: NotificationFilterInput) {\n notifications(filter: $filter) {\n items {\n id userId workspaceId type priority title message\n read readAt archived createdAt updatedAt\n metadata { actionUrl avatarUrl actorId actorName }\n }\n total hasMore\n }\n unreadNotificationCount(workspaceId: \"${workspaceId}\") { count }\n }`,\n { filter: { workspaceId, limit, offset } },\n );\n\n const items = data?.notifications?.items ?? [];\n setNotifications(items);\n setUnreadCount(data?.unreadNotificationCount?.count ?? 0);\n\n // Track last seen for subscription replay on reconnect\n if (items.length > 0) {\n lastSeenRef.current = items[0].createdAt;\n }\n } catch (err: any) {\n setError(err.message || 'Failed to fetch notifications');\n } finally {\n setLoading(false);\n }\n },\n [gqlFetch, workspaceId],\n );\n\n const markAsRead = useCallback(\n async (id: string) => {\n try {\n await gqlFetch(\n `mutation MarkRead($id: ID!) {\n markNotificationAsRead(id: $id) { id read readAt }\n }`,\n { id },\n );\n\n setNotifications((prev) =>\n prev.map((n) => (n.id === id ? { ...n, read: true, readAt: new Date().toISOString() } : n)),\n );\n setUnreadCount((prev) => Math.max(0, prev - 1));\n } catch (err: any) {\n setError(err.message);\n }\n },\n [gqlFetch],\n );\n\n const markAllAsRead = useCallback(async () => {\n try {\n await gqlFetch(\n `mutation MarkAllRead($workspaceId: String) {\n markAllNotificationsAsRead(workspaceId: $workspaceId)\n }`,\n { workspaceId },\n );\n\n setNotifications((prev) =>\n prev.map((n) => ({ ...n, read: true, readAt: new Date().toISOString() })),\n );\n setUnreadCount(0);\n } catch (err: any) {\n setError(err.message);\n }\n }, [gqlFetch, workspaceId]);\n\n const deleteNotification = useCallback(\n async (id: string) => {\n try {\n await gqlFetch(\n `mutation DeleteNotification($id: ID!) {\n deleteNotification(id: $id)\n }`,\n { id },\n );\n\n setNotifications((prev) => {\n const removed = prev.find((n) => n.id === id);\n if (removed && !removed.read) {\n setUnreadCount((c) => Math.max(0, c - 1));\n }\n return prev.filter((n) => n.id !== id);\n });\n } catch (err: any) {\n setError(err.message);\n }\n },\n [gqlFetch],\n );\n\n const refetch = useCallback(() => fetchNotifications(), [fetchNotifications]);\n\n // Auto-fetch on mount\n useEffect(() => {\n if (autoFetch && userId?.trim() && workspaceId) {\n fetchNotifications();\n }\n }, [autoFetch, userId, workspaceId, fetchNotifications]);\n\n // ─── GraphQL-WS Subscription ──────────\n useEffect(() => {\n // Skip if user is not authenticated or service URL not configured\n if (!userId?.trim() || !notificationsServiceUrl) return;\n\n const MAX_RECONNECTS = 5;\n\n function connectSubscription() {\n // Build WebSocket URL from service URL\n // NestJS notifications service exposes subscriptions at /graphql/notifications\n const wsUrl = notificationsServiceUrl!\n .replace(/^http/, 'ws')\n .replace(/\\/$/, '') + '/graphql/notifications';\n\n const ws = new WebSocket(wsUrl, 'graphql-transport-ws');\n wsRef.current = ws;\n\n ws.onopen = () => {\n // graphql-ws connection_init\n ws.send(JSON.stringify({\n type: 'connection_init',\n payload: authToken ? { Authorization: `Bearer ${authToken}` } : {},\n }));\n };\n\n ws.onmessage = (event) => {\n let msg: any;\n try { msg = JSON.parse(event.data); } catch { return; }\n\n switch (msg.type) {\n case 'connection_ack':\n setConnected(true);\n reconnectCountRef.current = 0;\n\n // Subscribe to notificationCreated\n ws.send(JSON.stringify({\n id: 'notif-created',\n type: 'subscribe',\n payload: {\n query: `subscription NotificationCreated {\n notificationCreated {\n id userId workspaceId type title message data read readAt archived metadata { actionUrl avatarUrl actorId actorName } createdAt updatedAt\n }\n }`,\n variables: {},\n },\n }));\n\n break;\n\n case 'next':\n if (msg.id === 'notif-created' && msg.payload?.data?.notificationCreated) {\n const notif = msg.payload.data.notificationCreated;\n // Deduplicate\n setNotifications((prev) => {\n if (prev.some((n) => n.id === notif.id)) return prev;\n return [notif, ...prev];\n });\n setUnreadCount((c) => c + 1);\n lastSeenRef.current = notif.createdAt;\n }\n break;\n\n case 'error':\n console.error('[useNotifications] Subscription error:', msg.payload);\n break;\n\n case 'ping':\n ws.send(JSON.stringify({ type: 'pong' }));\n break;\n }\n };\n\n ws.onclose = () => {\n setConnected(false);\n wsRef.current = null;\n\n // Reconnect with exponential backoff, capped\n if (reconnectCountRef.current < MAX_RECONNECTS) {\n const delay = Math.min(1000 * 2 ** reconnectCountRef.current, 30000);\n reconnectCountRef.current++;\n reconnectTimerRef.current = setTimeout(connectSubscription, delay);\n }\n };\n\n ws.onerror = () => {\n // onclose will fire after onerror\n };\n }\n\n connectSubscription();\n\n return () => {\n if (reconnectTimerRef.current) clearTimeout(reconnectTimerRef.current);\n if (wsRef.current) {\n wsRef.current.close();\n wsRef.current = null;\n }\n setConnected(false);\n };\n }, [userId, notificationsServiceUrl, authToken]);\n\n // ─── Fallback Polling (only if no subscription service configured) ──\n useEffect(() => {\n if (notificationsServiceUrl) return; // subscriptions active, no polling\n if (pollingInterval > 0 && userId?.trim() && workspaceId) {\n pollingRef.current = setInterval(() => fetchNotifications(), pollingInterval);\n return () => {\n if (pollingRef.current) clearInterval(pollingRef.current);\n };\n }\n }, [pollingInterval, userId, workspaceId, fetchNotifications, notificationsServiceUrl]);\n\n return {\n notifications,\n unreadCount,\n loading,\n error,\n connected,\n fetchNotifications,\n markAsRead,\n markAllAsRead,\n deleteNotification,\n refetch,\n };\n}","'use client';\n\n// ─────────────────────────────────────────────\n// OrganifyNotifications — Composed notification widget\n// ─────────────────────────────────────────────\n// Desktop: dropdown panel\n// Mobile: bottom Drawer\n// Pulls all data from OrganifyProvider — no props needed.\n// ─────────────────────────────────────────────\n\nimport React, { useState, useRef, useEffect } from 'react';\nimport { cn } from '../../lib/utils';\nimport { NotificationBell } from './notification-bell';\nimport { NotificationList } from './notification-list';\nimport { useNotifications } from './use-notifications';\nimport {\n Drawer,\n DrawerContent,\n} from '../primitives/drawer';\nimport type { OrganifyNotificationsProps } from './types';\n\nfunction useMediaQuery(query: string): boolean {\n const [matches, setMatches] = React.useState(false);\n React.useEffect(() => {\n const mql = window.matchMedia(query);\n setMatches(mql.matches);\n const handler = (e: MediaQueryListEvent) => setMatches(e.matches);\n mql.addEventListener('change', handler);\n return () => mql.removeEventListener('change', handler);\n }, [query]);\n return matches;\n}\n\nexport const OrganifyNotifications: React.FC<OrganifyNotificationsProps> = ({\n onNotificationClick,\n className,\n}) => {\n const [isOpen, setIsOpen] = useState(false);\n const containerRef = useRef<HTMLDivElement>(null);\n const isDesktop = useMediaQuery('(min-width: 768px)');\n\n const {\n notifications,\n unreadCount,\n loading,\n markAsRead,\n markAllAsRead,\n deleteNotification,\n } = useNotifications();\n\n // Close dropdown when clicking outside (desktop only)\n useEffect(() => {\n if (!isDesktop) return;\n const handleClickOutside = (event: MouseEvent) => {\n if (\n containerRef.current &&\n !containerRef.current.contains(event.target as Node)\n ) {\n setIsOpen(false);\n }\n };\n if (isOpen) {\n document.addEventListener('mousedown', handleClickOutside);\n return () => document.removeEventListener('mousedown', handleClickOutside);\n }\n }, [isOpen, isDesktop]);\n\n // Close dropdown on Escape (desktop only)\n useEffect(() => {\n if (!isDesktop) return;\n const handleEscape = (event: KeyboardEvent) => {\n if (event.key === 'Escape') setIsOpen(false);\n };\n if (isOpen) {\n document.addEventListener('keydown', handleEscape);\n return () => document.removeEventListener('keydown', handleEscape);\n }\n }, [isOpen, isDesktop]);\n\n const list = (\n <NotificationList\n notifications={notifications}\n loading={loading}\n onMarkRead={markAsRead}\n onMarkAllRead={markAllAsRead}\n onDelete={deleteNotification}\n onNotificationClick={(n) => {\n onNotificationClick?.(n);\n setIsOpen(false);\n }}\n />\n );\n\n return (\n <>\n {/* ── Desktop: dropdown ── */}\n <div ref={containerRef} data-tour=\"notifications\" className={cn('relative hidden sm:block', className)}>\n <NotificationBell\n count={unreadCount}\n isOpen={isOpen}\n onToggle={() => setIsOpen((prev) => !prev)}\n />\n\n {isOpen && (\n <div\n className={cn(\n 'absolute right-0 top-full mt-2 z-50',\n 'animate-in slide-in-from-top-2 fade-in-0 duration-[400ms]',\n )}\n >\n {list}\n </div>\n )}\n </div>\n\n {/* ── Mobile: drawer ── */}\n <div className={cn('sm:hidden', className)}>\n <NotificationBell\n count={unreadCount}\n isOpen={isOpen}\n onToggle={() => setIsOpen((prev) => !prev)}\n />\n </div>\n\n <Drawer open={!isDesktop && isOpen} onOpenChange={setIsOpen}>\n <DrawerContent className=\"max-h-[85vh]\">\n <div className=\"overflow-y-auto overscroll-contain flex-1\">\n <NotificationList\n notifications={notifications}\n loading={loading}\n onMarkRead={markAsRead}\n onMarkAllRead={markAllAsRead}\n onDelete={deleteNotification}\n onNotificationClick={(n) => {\n onNotificationClick?.(n);\n setIsOpen(false);\n }}\n className=\"w-full max-h-none border-0 shadow-none rounded-none bg-transparent\"\n />\n </div>\n </DrawerContent>\n </Drawer>\n </>\n );\n};\n","'use client';\n\n// ─────────────────────────────────────────────\n// PresenceIndicator — User online status dot\n// ─────────────────────────────────────────────\n\nimport React from 'react';\nimport { cn } from '../../lib/utils';\nimport type { PresenceIndicatorProps, PresenceStatus } from './types';\n\nconst statusColors: Record<PresenceStatus, string> = {\n ONLINE: 'bg-status-success',\n AWAY: 'bg-status-warning',\n BUSY: 'bg-status-error',\n OFFLINE: 'bg-text-muted/40',\n};\n\nconst statusLabels: Record<PresenceStatus, string> = {\n ONLINE: 'Online',\n AWAY: 'Ausente',\n BUSY: 'Ocupado',\n OFFLINE: 'Offline',\n};\n\nconst sizeClasses = {\n sm: 'w-2 h-2',\n md: 'w-2.5 h-2.5',\n lg: 'w-3 h-3',\n};\n\nexport const PresenceIndicator: React.FC<PresenceIndicatorProps> = ({\n status,\n size = 'md',\n showLabel = false,\n className,\n}) => {\n return (\n <span\n className={cn('inline-flex items-center gap-1.5', className)}\n title={statusLabels[status]}\n >\n <span\n className={cn(\n 'rounded-full flex-shrink-0',\n 'border-2 border-surface-base',\n sizeClasses[size],\n statusColors[status],\n status === 'ONLINE' && 'animate-pulse',\n )}\n aria-label={statusLabels[status]}\n />\n {showLabel && (\n <span className=\"text-xs text-text-muted\">{statusLabels[status]}</span>\n )}\n </span>\n );\n};\n","'use client';\n\nimport * as React from 'react';\nimport * as PopoverPrimitive from '@radix-ui/react-popover';\nimport { cn } from '../../lib/utils';\n\nconst Popover = PopoverPrimitive.Root;\nconst PopoverTrigger = PopoverPrimitive.Trigger;\nconst PopoverAnchor = PopoverPrimitive.Anchor;\n\nfunction PopoverContent({\n className,\n align = 'center',\n sideOffset = 4,\n ...props\n}: React.ComponentProps<typeof PopoverPrimitive.Content>) {\n return (\n <PopoverPrimitive.Portal>\n <PopoverPrimitive.Content\n data-slot=\"popover-content\"\n align={align}\n sideOffset={sideOffset}\n style={{\n background: 'var(--org-glass-bg-heavy, rgba(17,14,34,0.92))',\n borderColor: 'var(--org-glass-border, rgba(167,139,250,0.15))',\n color: 'var(--org-text, #F0ECF9)',\n }}\n className={cn(\n 'z-50 w-72 rounded-xl border backdrop-blur-[40px] p-4 shadow-[0_24px_80px_-15px_rgba(0,0,0,0.5)] outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',\n className,\n )}\n {...props}\n />\n </PopoverPrimitive.Portal>\n );\n}\n\nexport { Popover, PopoverTrigger, PopoverContent, PopoverAnchor };\n","// ─────────────────────────────────────────────\n// PresenceAvatarStack — Shows online users\n// in a context (workspace, project, board)\n// Compact stacked avatars + expandable list\n// ─────────────────────────────────────────────\n\n'use client';\n\nimport * as React from 'react';\nimport { cn } from '../../lib/utils';\nimport { Avatar, AvatarFallback } from '../primitives/avatar';\nimport { Badge } from '../primitives/badge';\nimport { ScrollArea } from '../primitives/scroll-area';\nimport { Skeleton } from '../primitives/skeleton';\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n TooltipProvider,\n} from '../primitives/tooltip';\nimport { Popover, PopoverContent, PopoverTrigger } from '../primitives/popover';\nimport { PresenceIndicator } from './presence-indicator';\nimport type { PresenceStatus } from './types';\n\n// ─── Types ──────────────────────────────────\n\nexport interface PresenceUser {\n id: string;\n displayName: string;\n avatarUrl: string | null;\n status: PresenceStatus;\n lastSeen?: string;\n}\n\nexport interface PresenceAvatarStackProps {\n /** List of users with presence status */\n users: PresenceUser[];\n /** Max avatars to show before \"+N\" */\n maxVisible?: number;\n /** Size of avatars */\n size?: 'sm' | 'md' | 'lg';\n /** Show only online users in the stack */\n onlineOnly?: boolean;\n /** Loading state */\n loading?: boolean;\n /** Show the expandable popover list */\n expandable?: boolean;\n /** CSS class */\n className?: string;\n}\n\n// ─── Helpers ────────────────────────────────\n\nfunction getInitials(name: string): string {\n return name\n .split(' ')\n .map((w) => w[0])\n .slice(0, 2)\n .join('')\n .toUpperCase();\n}\n\nconst sizeConfig = {\n sm: { avatar: 'h-6 w-6', text: 'text-[9px]', stack: '-space-x-1.5', dot: 'sm' as const },\n md: { avatar: 'h-8 w-8', text: 'text-[10px]', stack: '-space-x-2', dot: 'md' as const },\n lg: { avatar: 'h-10 w-10', text: 'text-xs', stack: '-space-x-2.5', dot: 'lg' as const },\n};\n\nconst statusOrder: Record<PresenceStatus, number> = {\n ONLINE: 0,\n BUSY: 1,\n AWAY: 2,\n OFFLINE: 3,\n};\n\nfunction formatLastSeen(iso?: string): string {\n if (!iso) return '';\n const diff = Date.now() - new Date(iso).getTime();\n const mins = Math.floor(diff / 60000);\n if (mins < 1) return 'agora';\n if (mins < 60) return `${mins}m atrás`;\n const hours = Math.floor(mins / 60);\n if (hours < 24) return `${hours}h atrás`;\n return `${Math.floor(hours / 24)}d atrás`;\n}\n\n// ─── Single Avatar with Status ──────────────\n\nfunction PresenceAvatar({\n user,\n size = 'md',\n showTooltip = true,\n}: {\n user: PresenceUser;\n size?: 'sm' | 'md' | 'lg';\n showTooltip?: boolean;\n}) {\n const cfg = sizeConfig[size];\n\n const avatar = (\n <div className=\"relative\">\n <Avatar shape=\"circle\" size=\"sm\" className={cn(cfg.avatar, 'border-2 border-surface')}>\n <AvatarFallback className=\"bg-primary/20 text-primary-light font-semibold\" style={{ fontSize: 'inherit' }}>\n <span className={cfg.text}>{getInitials(user.displayName)}</span>\n </AvatarFallback>\n </Avatar>\n <span className=\"absolute -bottom-0.5 -right-0.5\">\n <PresenceIndicator status={user.status} size={cfg.dot} />\n </span>\n </div>\n );\n\n if (!showTooltip) return avatar;\n\n return (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>{avatar}</TooltipTrigger>\n <TooltipContent className=\"text-xs\">\n <p className=\"font-medium\">{user.displayName}</p>\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n );\n}\n\n// ─── Presence List (Expandable) ─────────────\n\nfunction PresenceList({\n users,\n size = 'md',\n}: {\n users: PresenceUser[];\n size?: 'sm' | 'md' | 'lg';\n}) {\n const sorted = [...users].sort((a, b) => statusOrder[a.status] - statusOrder[b.status]);\n const online = sorted.filter((u) => u.status !== 'OFFLINE');\n const offline = sorted.filter((u) => u.status === 'OFFLINE');\n\n const renderUser = (user: PresenceUser) => (\n <div\n key={user.id}\n className=\"flex items-center gap-2.5 px-3 py-1.5 rounded-xl hover:bg-theme-subtle transition-colors\"\n >\n <PresenceAvatar user={user} size=\"sm\" showTooltip={false} />\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-xs font-medium text-theme truncate\">{user.displayName}</p>\n {user.status === 'OFFLINE' && user.lastSeen && (\n <p className=\"text-[10px] text-theme-muted\">{formatLastSeen(user.lastSeen)}</p>\n )}\n </div>\n <PresenceIndicator status={user.status} size=\"sm\" showLabel />\n </div>\n );\n\n return (\n <div className=\"w-[240px]\">\n <div className=\"px-3 py-2 border-b border-theme-subtle\">\n <h4 className=\"text-xs font-semibold text-theme\">\n Membros\n <span className=\"text-theme-muted font-normal ml-1\">({users.length})</span>\n </h4>\n </div>\n <ScrollArea className=\"max-h-[300px]\">\n <div className=\"py-1\">\n {online.length > 0 && (\n <>\n <p className=\"px-3 py-1 text-[10px] text-emerald-400/70 uppercase tracking-wider font-semibold\">\n Online — {online.length}\n </p>\n {online.map(renderUser)}\n </>\n )}\n {offline.length > 0 && (\n <>\n <p className=\"px-3 py-1 mt-1 text-[10px] text-theme-muted uppercase tracking-wider font-semibold\">\n Offline — {offline.length}\n </p>\n {offline.map(renderUser)}\n </>\n )}\n {users.length === 0 && (\n <p className=\"px-3 py-4 text-xs text-theme-muted text-center\">Sem membros</p>\n )}\n </div>\n </ScrollArea>\n </div>\n );\n}\n\n// ─── Main Component ─────────────────────────\n\nexport function PresenceAvatarStack({\n users,\n maxVisible = 4,\n size = 'md',\n onlineOnly = false,\n loading = false,\n expandable = true,\n className,\n}: PresenceAvatarStackProps) {\n const cfg = sizeConfig[size];\n\n const displayUsers = onlineOnly\n ? users.filter((u) => u.status !== 'OFFLINE')\n : [...users].sort((a, b) => statusOrder[a.status] - statusOrder[b.status]);\n\n const visible = displayUsers.slice(0, maxVisible);\n const overflow = displayUsers.length - maxVisible;\n const onlineCount = users.filter((u) => u.status === 'ONLINE').length;\n\n if (loading) {\n return (\n <div className={cn('flex items-center', cfg.stack, className)}>\n {Array.from({ length: Math.min(3, maxVisible) }).map((_, i) => (\n <Skeleton\n key={i}\n variant=\"circular\"\n className={cn(cfg.avatar, 'border-2 border-surface')}\n />\n ))}\n </div>\n );\n }\n\n if (displayUsers.length === 0) {\n return null;\n }\n\n const stack = (\n <div className={cn('flex items-center', className)}>\n <div className={cn('flex items-center', cfg.stack)}>\n {visible.map((user) => (\n <PresenceAvatar\n key={user.id}\n user={user}\n size={size}\n showTooltip={!expandable}\n />\n ))}\n\n {overflow > 0 && (\n <div\n className={cn(\n cfg.avatar,\n 'flex items-center justify-center rounded-full border-2 border-surface bg-theme-subtle',\n cfg.text,\n 'font-medium text-theme-muted',\n )}\n >\n +{overflow}\n </div>\n )}\n </div>\n\n {/* Online count badge */}\n <Badge\n variant=\"default\"\n className=\"ml-2 text-[10px] px-1.5 py-0 h-4 border-emerald-500/20 text-emerald-400/70 bg-emerald-500/5\"\n >\n <span className=\"w-1.5 h-1.5 rounded-full bg-emerald-400 mr-1 animate-pulse\" />\n {onlineCount}\n </Badge>\n </div>\n );\n\n if (!expandable) return stack;\n\n return (\n <Popover>\n <PopoverTrigger asChild>\n <button className=\"cursor-pointer hover:opacity-80 transition-opacity\">\n {stack}\n </button>\n </PopoverTrigger>\n <PopoverContent\n className=\"p-0 bg-white/[0.03] backdrop-blur-[40px] border-primary/25 shadow-[0_24px_80px_-15px_rgba(0,0,0,0.5)]\"\n align=\"end\"\n >\n <PresenceList users={users} size={size} />\n </PopoverContent>\n </Popover>\n );\n}\n","// ─────────────────────────────────────────────\n// usePresence — React hook for presence tracking\n// ─────────────────────────────────────────────\n\nimport { useState, useEffect, useCallback, useRef } from 'react';\nimport type { UserPresence, PresenceStatus } from './types';\n\ninterface UsePresenceOptions {\n gatewayUrl: string;\n userId: string;\n authToken?: string;\n /** Direct service URLs (bypasses gateway) */\n services?: { notifications?: string };\n /** Heartbeat interval in ms (default: 30s) */\n heartbeatInterval?: number;\n /** Auto-connect on mount */\n autoConnect?: boolean;\n}\n\ninterface UsePresenceReturn {\n onlineUsers: UserPresence[];\n myStatus: PresenceStatus;\n isConnected: boolean;\n setStatus: (status: PresenceStatus) => void;\n getUserStatus: (userId: string) => PresenceStatus;\n fetchOnlineUsers: () => Promise<void>;\n}\n\nexport function usePresence(options: UsePresenceOptions): UsePresenceReturn {\n const {\n gatewayUrl,\n userId,\n authToken,\n heartbeatInterval = 30000,\n autoConnect = true,\n } = options;\n\n const [onlineUsers, setOnlineUsers] = useState<UserPresence[]>([]);\n const [myStatus, setMyStatus] = useState<PresenceStatus>('ONLINE');\n const [isConnected, setIsConnected] = useState(false);\n const heartbeatRef = useRef<ReturnType<typeof setInterval> | null>(null);\n\n // Presence GraphQL goes through gateway proxy (/api/graphql/notifications)\n // which injects x-user-id from the JWT cookie.\n const graphqlUrl = `${gatewayUrl}/api/graphql/notifications`;\n\n const gqlFetch = useCallback(\n async (query: string, variables?: Record<string, any>) => {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n if (authToken) headers['Authorization'] = `Bearer ${authToken}`;\n\n const res = await fetch(graphqlUrl, {\n method: 'POST',\n headers,\n credentials: 'include',\n body: JSON.stringify({ query, variables }),\n });\n\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const json = await res.json();\n if (json.errors?.length) throw new Error(json.errors[0].message);\n return json.data;\n },\n [graphqlUrl, userId, authToken],\n );\n\n const fetchOnlineUsers = useCallback(async () => {\n try {\n const data = await gqlFetch(`\n query GetOnlineUsers {\n onlineUsers {\n users { userId status connectedAt lastActivityAt sessionCount }\n count\n }\n }\n `);\n setOnlineUsers(data.onlineUsers.users);\n setIsConnected(true);\n } catch {\n setIsConnected(false);\n }\n }, [gqlFetch]);\n\n const setStatus = useCallback(\n (status: PresenceStatus) => {\n setMyStatus(status);\n // Fire-and-forget status update\n gqlFetch('').catch(() => {});\n },\n [gqlFetch],\n );\n\n const getUserStatus = useCallback(\n (targetUserId: string): PresenceStatus => {\n const user = onlineUsers.find((u) => u.userId === targetUserId);\n return user?.status || 'OFFLINE';\n },\n [onlineUsers],\n );\n\n // Auto-connect: fetch online users on mount\n useEffect(() => {\n if (autoConnect && userId) {\n fetchOnlineUsers();\n }\n }, [autoConnect, userId, fetchOnlineUsers]);\n\n // Heartbeat polling\n useEffect(() => {\n if (heartbeatInterval > 0 && userId) {\n heartbeatRef.current = setInterval(() => {\n fetchOnlineUsers();\n }, heartbeatInterval);\n\n return () => {\n if (heartbeatRef.current) clearInterval(heartbeatRef.current);\n };\n }\n }, [heartbeatInterval, userId, fetchOnlineUsers]);\n\n // Visibility change → away/online\n useEffect(() => {\n const handleVisibility = () => {\n if (document.hidden) {\n setMyStatus('AWAY');\n } else {\n setMyStatus('ONLINE');\n }\n };\n\n document.addEventListener('visibilitychange', handleVisibility);\n return () => document.removeEventListener('visibilitychange', handleVisibility);\n }, []);\n\n return {\n onlineUsers,\n myStatus,\n isConnected,\n setStatus,\n getUserStatus,\n fetchOnlineUsers,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/components/notifications/notification-bell.tsx","../src/components/notifications/notification-item.tsx","../src/components/notifications/notification-list.tsx","../src/components/notifications/use-notifications.ts","../src/components/notifications/organify-notifications.tsx","../src/components/notifications/presence-indicator.tsx","../src/components/primitives/popover.tsx","../src/components/notifications/presence-avatar-stack.tsx","../src/components/notifications/use-presence.ts"],"names":["jsxs","jsx","useState","useRef","useEffect","Fragment","useCallback"],"mappings":"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","file":"chunk-7RCUPHNX.js","sourcesContent":["'use client';\n\n// ─────────────────────────────────────────────\n// NotificationBell — Bell icon with unread badge\n// ─────────────────────────────────────────────\n\nimport React from 'react';\nimport { cn } from '../../lib/utils';\nimport type { NotificationBellProps } from './types';\nimport { OrgBell as BellIcon } from '../../icons/system'\n\nexport const NotificationBell: React.FC<NotificationBellProps> = ({\n count,\n isOpen,\n onToggle,\n className,\n}) => {\n return (\n <button\n type=\"button\"\n onClick={onToggle}\n className={cn(\n 'relative inline-flex items-center justify-center',\n 'w-10 h-10 rounded-xl',\n 'bg-surface-glass/50 backdrop-blur-sm',\n 'border border-border-subtle/30',\n 'text-text-secondary hover:text-text-primary',\n 'hover:bg-surface-glass/70 hover:border-brand-primary/30',\n 'transition-all duration-[400ms]',\n 'focus:outline-none focus:ring-2 focus:ring-brand-primary/40',\n isOpen && 'bg-surface-glass/70 border-brand-primary/40 text-text-primary',\n className,\n )}\n aria-label={`Notifications${count > 0 ? ` (${count} unread)` : ''}`}\n aria-expanded={isOpen}\n >\n <BellIcon className={cn('w-5 h-5', count > 0 && 'animate-[bell_0.5s_ease-in-out]')} />\n\n {count > 0 && (\n <span\n className={cn(\n 'absolute -top-1 -right-1',\n 'flex items-center justify-center',\n 'min-w-[18px] h-[18px] px-1',\n 'rounded-full',\n 'bg-status-error text-white',\n 'text-[10px] font-bold leading-none',\n 'border-2 border-surface-base',\n 'animate-in zoom-in-50 duration-[400ms]',\n )}\n >\n {count > 99 ? '99+' : count}\n </span>\n )}\n </button>\n );\n};\n","'use client';\n\n// ─────────────────────────────────────────────\n// NotificationItem — Single notification entry\n// ─────────────────────────────────────────────\n\nimport React from 'react';\nimport { cn } from '../../lib/utils';\nimport type { NotificationItemProps, NotificationType } from './types';\nimport {\n OrgBoard, OrgEdit, OrgComment, OrgMention,\n OrgMail, OrgSprint, OrgCheckCircle, OrgFolder,\n OrgWave, OrgDoor, OrgBell, OrgClose,\n} from '../../icons';\n\n// ─── Type → Icon mapping ───────────────────\n\nconst typeIcons: Record<NotificationType, React.FC<{ className?: string }>> = {\n TASK_ASSIGNED: OrgBoard,\n TASK_UPDATED: OrgEdit,\n COMMENT_ADDED: OrgComment,\n CHAT_MESSAGE: OrgComment,\n MENTION: OrgMention,\n INVITATION: OrgMail,\n SPRINT_STARTED: OrgSprint,\n SPRINT_COMPLETED: OrgCheckCircle,\n PROJECT_UPDATED: OrgFolder,\n MEMBER_JOINED: OrgWave,\n MEMBER_LEFT: OrgDoor,\n OTHER: OrgBell,\n};\n\nconst typeColors: Record<NotificationType, string> = {\n TASK_ASSIGNED: 'bg-brand-primary/10 text-brand-primary',\n TASK_UPDATED: 'bg-status-warning/10 text-status-warning',\n COMMENT_ADDED: 'bg-accent-secondary/10 text-accent-secondary',\n CHAT_MESSAGE: 'bg-accent-tertiary/10 text-accent-tertiary',\n MENTION: 'bg-brand-primary/10 text-brand-primary',\n INVITATION: 'bg-status-success/10 text-status-success',\n SPRINT_STARTED: 'bg-status-info/10 text-status-info',\n SPRINT_COMPLETED: 'bg-status-success/10 text-status-success',\n PROJECT_UPDATED: 'bg-accent-secondary/10 text-accent-secondary',\n MEMBER_JOINED: 'bg-status-success/10 text-status-success',\n MEMBER_LEFT: 'bg-status-error/10 text-status-error',\n OTHER: 'bg-surface-elevated text-text-secondary',\n};\n\nfunction formatTimeAgo(dateStr: string): string {\n const now = Date.now();\n const date = new Date(dateStr).getTime();\n const diffMs = now - date;\n const diffMin = Math.floor(diffMs / 60000);\n\n if (diffMin < 1) return 'agora';\n if (diffMin < 60) return `${diffMin}m`;\n const diffHour = Math.floor(diffMin / 60);\n if (diffHour < 24) return `${diffHour}h`;\n const diffDay = Math.floor(diffHour / 24);\n if (diffDay < 7) return `${diffDay}d`;\n return new Date(dateStr).toLocaleDateString('pt-BR', { day: '2-digit', month: 'short' });\n}\n\nexport const NotificationItem: React.FC<NotificationItemProps> = ({\n notification,\n onMarkRead,\n onDelete,\n onClick,\n}) => {\n const IconComponent = typeIcons[notification.type] || OrgBell;\n const colorClass = typeColors[notification.type] || typeColors.OTHER;\n\n const handleClick = () => {\n if (!notification.read) onMarkRead(notification.id);\n onClick?.(notification);\n };\n\n return (\n <div\n role=\"button\"\n tabIndex={0}\n onClick={handleClick}\n onKeyDown={(e) => e.key === 'Enter' && handleClick()}\n className={cn(\n 'flex items-start gap-3 p-3 rounded-xl cursor-pointer',\n 'transition-all duration-[400ms]',\n 'hover:bg-surface-glass/50',\n !notification.read && 'bg-brand-primary/5 border-l-2 border-brand-primary',\n notification.read && 'opacity-70',\n )}\n >\n {/* Icon */}\n <div\n className={cn(\n 'flex-shrink-0 w-9 h-9 rounded-xl',\n 'flex items-center justify-center',\n 'text-sm',\n colorClass,\n )}\n >\n {notification.metadata?.avatarUrl ? (\n <img\n src={notification.metadata.avatarUrl}\n alt=\"\"\n className=\"w-9 h-9 rounded-xl object-cover\"\n />\n ) : (\n <IconComponent className=\"w-4 h-4\" />\n )}\n </div>\n\n {/* Content */}\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-start justify-between gap-2\">\n <p\n className={cn(\n 'text-sm leading-snug truncate',\n !notification.read ? 'font-semibold text-text-primary' : 'text-text-secondary',\n )}\n >\n {notification.title}\n </p>\n <span className=\"text-[10px] text-text-muted flex-shrink-0 mt-0.5\">\n {formatTimeAgo(notification.createdAt)}\n </span>\n </div>\n\n <p className=\"text-xs text-text-muted mt-0.5 line-clamp-2\">\n {notification.message}\n </p>\n\n {notification.metadata?.actorName && (\n <p className=\"text-[10px] text-text-muted mt-1\">\n por {notification.metadata.actorName}\n </p>\n )}\n </div>\n\n {/* Actions */}\n <div className=\"flex flex-col gap-1 flex-shrink-0 opacity-0 group-hover:opacity-100 transition-opacity\">\n {!notification.read && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n onMarkRead(notification.id);\n }}\n className=\"w-2 h-2 rounded-full bg-brand-primary flex-shrink-0 mt-1.5\"\n aria-label=\"Mark as read\"\n />\n )}\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n onDelete(notification.id);\n }}\n className={cn(\n 'text-[10px] text-text-muted hover:text-status-error',\n 'transition-colors',\n )}\n aria-label=\"Delete notification\"\n >\n <OrgClose className=\"w-3 h-3\" />\n </button>\n </div>\n </div>\n );\n};\n","'use client';\n\n// ─────────────────────────────────────────────\n// NotificationList — Scrollable notification panel\n// ─────────────────────────────────────────────\n\nimport React from 'react';\nimport { cn } from '../../lib/utils';\nimport { NotificationItem } from './notification-item';\nimport { OrgBell } from '../../icons';\nimport type { NotificationListProps } from './types';\n\nexport const NotificationList: React.FC<NotificationListProps> = ({\n notifications,\n loading,\n onMarkRead,\n onMarkAllRead,\n onDelete,\n onNotificationClick,\n className,\n}) => {\n const unreadCount = notifications.filter((n) => !n.read).length;\n\n return (\n <div\n className={cn(\n 'flex flex-col',\n 'w-[380px] max-h-[520px]',\n 'rounded-xl',\n 'bg-surface-base/95 backdrop-blur-xl',\n 'border border-border-subtle/40',\n 'shadow-2xl shadow-black/20',\n 'overflow-hidden',\n className,\n )}\n >\n {/* Header */}\n <div className=\"flex items-center justify-between px-4 py-3 border-b border-border-subtle/30\">\n <div className=\"flex items-center gap-2\">\n <h3 className=\"text-sm font-semibold text-text-primary\">Notificações</h3>\n {unreadCount > 0 && (\n <span\n className={cn(\n 'inline-flex items-center justify-center',\n 'min-w-[20px] h-5 px-1.5',\n 'rounded-full',\n 'bg-brand-primary/10 text-brand-primary',\n 'text-[10px] font-bold',\n )}\n >\n {unreadCount}\n </span>\n )}\n </div>\n\n {unreadCount > 0 && (\n <button\n type=\"button\"\n onClick={onMarkAllRead}\n className={cn(\n 'text-xs text-brand-primary hover:text-brand-primary/80',\n 'transition-colors',\n )}\n >\n Marcar todas como lidas\n </button>\n )}\n </div>\n\n {/* Content */}\n <div className=\"flex-1 overflow-y-auto overscroll-contain\">\n {loading && notifications.length === 0 ? (\n <div className=\"flex flex-col gap-3 p-4\">\n {[1, 2, 3].map((i) => (\n <div key={i} className=\"flex items-start gap-3 animate-pulse\">\n <div className=\"w-9 h-9 rounded-xl bg-surface-elevated\" />\n <div className=\"flex-1 space-y-2\">\n <div className=\"h-3 bg-surface-elevated rounded w-3/4\" />\n <div className=\"h-2 bg-surface-elevated rounded w-1/2\" />\n </div>\n </div>\n ))}\n </div>\n ) : notifications.length === 0 ? (\n <div className=\"flex flex-col items-center justify-center py-12 px-4\">\n <OrgBell className=\"w-8 h-8 text-text-muted mb-3\" />\n <p className=\"text-sm text-text-secondary font-medium\">Tudo em dia!</p>\n <p className=\"text-xs text-text-muted mt-1\">Nenhuma notificação por enquanto.</p>\n </div>\n ) : (\n <div className=\"p-2 space-y-0.5 group\">\n {notifications.map((notification) => (\n <NotificationItem\n key={notification.id}\n notification={notification}\n onMarkRead={onMarkRead}\n onDelete={onDelete}\n onClick={onNotificationClick}\n />\n ))}\n </div>\n )}\n </div>\n\n {/* Footer */}\n {notifications.length > 0 && (\n <div className=\"px-4 py-2.5 border-t border-border-subtle/30 text-center\">\n <button\n type=\"button\"\n className={cn(\n 'text-xs text-text-muted hover:text-text-secondary',\n 'transition-colors',\n )}\n >\n Ver todas as notificações\n </button>\n </div>\n )}\n </div>\n );\n};\n","// ─────────────────────────────────────────────\n// useNotifications — React hook for notification state\n// ─────────────────────────────────────────────\n// Pulls gatewayUrl, authToken, userId, workspaceId\n// from OrganifyProvider — no props needed.\n//\n// Uses graphql-ws subscription for real-time updates\n// instead of polling. Falls back to polling if\n// subscription fails or service URL not configured.\n// ─────────────────────────────────────────────\n\nimport { useState, useEffect, useCallback, useRef } from 'react';\nimport { useOrganifyApi, useOrganifyUser, useOrganifyWorkspace, useOrganifyGql, useOrganifyLookupUser } from '../../providers/organify-provider';\nimport type { Notification } from './types';\n\ninterface UseNotificationsOptions {\n /** Auto-fetch on mount (default true) */\n autoFetch?: boolean;\n /** Polling interval in ms as fallback (0 = no polling, default 0 since we use subscriptions) */\n pollingInterval?: number;\n}\n\ninterface UseNotificationsReturn {\n notifications: Notification[];\n unreadCount: number;\n loading: boolean;\n error: string | null;\n connected: boolean;\n fetchNotifications: (limit?: number, offset?: number) => Promise<void>;\n markAsRead: (id: string) => Promise<void>;\n markAllAsRead: () => Promise<void>;\n deleteNotification: (id: string) => Promise<void>;\n refetch: () => Promise<void>;\n}\n\nexport function useNotifications(options: UseNotificationsOptions = {}): UseNotificationsReturn {\n const { autoFetch = true, pollingInterval = 0 } = options;\n\n // ─── Pull from OrganifyProvider ───────\n const api = useOrganifyApi();\n const { gatewayUrl, authToken } = api;\n const notificationsServiceUrl = api.services?.notifications;\n const user = useOrganifyUser();\n const { workspace } = useOrganifyWorkspace();\n const userId = user?.id ?? '';\n const workspaceId = workspace?.id ?? '';\n\n const [notifications, setNotifications] = useState<Notification[]>([]);\n const [unreadCount, setUnreadCount] = useState(0);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [connected, setConnected] = useState(false);\n\n const pollingRef = useRef<ReturnType<typeof setInterval> | null>(null);\n const wsRef = useRef<WebSocket | null>(null);\n const reconnectCountRef = useRef(0);\n const reconnectTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const lastSeenRef = useRef<string | null>(null);\n\n // Notifications GraphQL uses centralized useOrganifyGql with 'notifications' endpoint.\n // Routes through gateway proxy (/api/graphql/notifications) which injects x-user-id from JWT cookie.\n const centralGql = useOrganifyGql();\n\n const gqlFetch = useCallback(\n async (query: string, variables?: Record<string, any>) => {\n return centralGql('notifications', query, variables);\n },\n [centralGql],\n );\n\n const fetchNotifications = useCallback(\n async (limit = 20, offset = 0) => {\n if (!workspaceId) return;\n setLoading(true);\n setError(null);\n try {\n const data = await gqlFetch(\n `query GetNotifications($filter: NotificationFilterInput) {\n notifications(filter: $filter) {\n items {\n id userId workspaceId type priority title message\n read readAt archived createdAt updatedAt\n metadata { actionUrl avatarUrl actorId actorName }\n }\n total hasMore\n }\n unreadNotificationCount(workspaceId: \"${workspaceId}\") { count }\n }`,\n { filter: { workspaceId, limit, offset } },\n );\n\n let items: Notification[] = data?.notifications?.items ?? [];\n\n // ─── patch actor info from cache if missing ──────────\n // The backend may only provide actorId in metadata; we resolve\n // name/avatar via a lookup provided by the host app (typically the\n // IndexedDB cache we built earlier). This keeps the UI package\n // agnostic of where the cache lives while still enabling the same\n // replacement behaviour used in chat/board components.\n if (items.length > 0) {\n const lookupUser = useOrganifyLookupUser();\n items = items.map((n) => {\n if (n.metadata?.actorId && !n.metadata.actorName) {\n const cached = lookupUser(String(n.metadata.actorId));\n if (cached) {\n n.metadata.actorName = cached.name;\n if (!n.metadata.avatarUrl) n.metadata.avatarUrl = cached.avatarUrl ?? '';\n }\n }\n return n;\n });\n }\n\n setNotifications(items);\n setUnreadCount(data?.unreadNotificationCount?.count ?? 0);\n\n // Track last seen for subscription replay on reconnect\n if (items.length > 0) {\n lastSeenRef.current = items[0].createdAt;\n }\n } catch (err: any) {\n setError(err.message || 'Failed to fetch notifications');\n } finally {\n setLoading(false);\n }\n },\n [gqlFetch, workspaceId],\n );\n\n const markAsRead = useCallback(\n async (id: string) => {\n try {\n await gqlFetch(\n `mutation MarkRead($id: ID!) {\n markNotificationAsRead(id: $id) { id read readAt }\n }`,\n { id },\n );\n\n setNotifications((prev) =>\n prev.map((n) => (n.id === id ? { ...n, read: true, readAt: new Date().toISOString() } : n)),\n );\n setUnreadCount((prev) => Math.max(0, prev - 1));\n } catch (err: any) {\n setError(err.message);\n }\n },\n [gqlFetch],\n );\n\n const markAllAsRead = useCallback(async () => {\n try {\n await gqlFetch(\n `mutation MarkAllRead($workspaceId: String) {\n markAllNotificationsAsRead(workspaceId: $workspaceId)\n }`,\n { workspaceId },\n );\n\n setNotifications((prev) =>\n prev.map((n) => ({ ...n, read: true, readAt: new Date().toISOString() })),\n );\n setUnreadCount(0);\n } catch (err: any) {\n setError(err.message);\n }\n }, [gqlFetch, workspaceId]);\n\n const deleteNotification = useCallback(\n async (id: string) => {\n try {\n await gqlFetch(\n `mutation DeleteNotification($id: ID!) {\n deleteNotification(id: $id)\n }`,\n { id },\n );\n\n setNotifications((prev) => {\n const removed = prev.find((n) => n.id === id);\n if (removed && !removed.read) {\n setUnreadCount((c) => Math.max(0, c - 1));\n }\n return prev.filter((n) => n.id !== id);\n });\n } catch (err: any) {\n setError(err.message);\n }\n },\n [gqlFetch],\n );\n\n const refetch = useCallback(() => fetchNotifications(), [fetchNotifications]);\n\n // Auto-fetch on mount\n useEffect(() => {\n if (autoFetch && userId?.trim() && workspaceId) {\n fetchNotifications();\n }\n }, [autoFetch, userId, workspaceId, fetchNotifications]);\n\n // ─── GraphQL-WS Subscription ──────────\n useEffect(() => {\n // Skip if user is not authenticated or service URL not configured\n if (!userId?.trim() || !notificationsServiceUrl) return;\n\n const MAX_RECONNECTS = 5;\n\n function connectSubscription() {\n // Build WebSocket URL from service URL\n // NestJS notifications service exposes subscriptions at /graphql/notifications\n const wsUrl = notificationsServiceUrl!\n .replace(/^http/, 'ws')\n .replace(/\\/$/, '') + '/graphql/notifications';\n\n const ws = new WebSocket(wsUrl, 'graphql-transport-ws');\n wsRef.current = ws;\n\n ws.onopen = () => {\n // graphql-ws connection_init\n ws.send(JSON.stringify({\n type: 'connection_init',\n payload: authToken ? { Authorization: `Bearer ${authToken}` } : {},\n }));\n };\n\n ws.onmessage = (event) => {\n let msg: any;\n try { msg = JSON.parse(event.data); } catch { return; }\n\n switch (msg.type) {\n case 'connection_ack':\n setConnected(true);\n reconnectCountRef.current = 0;\n\n // Subscribe to notificationCreated\n ws.send(JSON.stringify({\n id: 'notif-created',\n type: 'subscribe',\n payload: {\n query: `subscription NotificationCreated {\n notificationCreated {\n id userId workspaceId type title message data read readAt archived metadata { actionUrl avatarUrl actorId actorName } createdAt updatedAt\n }\n }`,\n variables: {},\n },\n }));\n\n break;\n\n case 'next':\n if (msg.id === 'notif-created' && msg.payload?.data?.notificationCreated) {\n const notif = msg.payload.data.notificationCreated;\n // Deduplicate\n setNotifications((prev) => {\n if (prev.some((n) => n.id === notif.id)) return prev;\n return [notif, ...prev];\n });\n setUnreadCount((c) => c + 1);\n lastSeenRef.current = notif.createdAt;\n }\n break;\n\n case 'error':\n console.error('[useNotifications] Subscription error:', msg.payload);\n break;\n\n case 'ping':\n ws.send(JSON.stringify({ type: 'pong' }));\n break;\n }\n };\n\n ws.onclose = () => {\n setConnected(false);\n wsRef.current = null;\n\n // Reconnect with exponential backoff, capped\n if (reconnectCountRef.current < MAX_RECONNECTS) {\n const delay = Math.min(1000 * 2 ** reconnectCountRef.current, 30000);\n reconnectCountRef.current++;\n reconnectTimerRef.current = setTimeout(connectSubscription, delay);\n }\n };\n\n ws.onerror = () => {\n // onclose will fire after onerror\n };\n }\n\n connectSubscription();\n\n return () => {\n if (reconnectTimerRef.current) clearTimeout(reconnectTimerRef.current);\n if (wsRef.current) {\n wsRef.current.close();\n wsRef.current = null;\n }\n setConnected(false);\n };\n }, [userId, notificationsServiceUrl, authToken]);\n\n // ─── Fallback Polling (only if no subscription service configured) ──\n useEffect(() => {\n if (notificationsServiceUrl) return; // subscriptions active, no polling\n if (pollingInterval > 0 && userId?.trim() && workspaceId) {\n pollingRef.current = setInterval(() => fetchNotifications(), pollingInterval);\n return () => {\n if (pollingRef.current) clearInterval(pollingRef.current);\n };\n }\n }, [pollingInterval, userId, workspaceId, fetchNotifications, notificationsServiceUrl]);\n\n return {\n notifications,\n unreadCount,\n loading,\n error,\n connected,\n fetchNotifications,\n markAsRead,\n markAllAsRead,\n deleteNotification,\n refetch,\n };\n}","'use client';\n\n// ─────────────────────────────────────────────\n// OrganifyNotifications — Composed notification widget\n// ─────────────────────────────────────────────\n// Desktop: dropdown panel\n// Mobile: bottom Drawer\n// Pulls all data from OrganifyProvider — no props needed.\n// ─────────────────────────────────────────────\n\nimport React, { useState, useRef, useEffect } from 'react';\nimport { cn } from '../../lib/utils';\nimport { NotificationBell } from './notification-bell';\nimport { NotificationList } from './notification-list';\nimport { useNotifications } from './use-notifications';\nimport {\n Drawer,\n DrawerContent,\n} from '../primitives/drawer';\nimport type { OrganifyNotificationsProps } from './types';\n\nfunction useMediaQuery(query: string): boolean {\n const [matches, setMatches] = React.useState(false);\n React.useEffect(() => {\n const mql = window.matchMedia(query);\n setMatches(mql.matches);\n const handler = (e: MediaQueryListEvent) => setMatches(e.matches);\n mql.addEventListener('change', handler);\n return () => mql.removeEventListener('change', handler);\n }, [query]);\n return matches;\n}\n\nexport const OrganifyNotifications: React.FC<OrganifyNotificationsProps> = ({\n onNotificationClick,\n className,\n}) => {\n const [isOpen, setIsOpen] = useState(false);\n const containerRef = useRef<HTMLDivElement>(null);\n const isDesktop = useMediaQuery('(min-width: 768px)');\n\n const {\n notifications,\n unreadCount,\n loading,\n markAsRead,\n markAllAsRead,\n deleteNotification,\n } = useNotifications();\n\n // Close dropdown when clicking outside (desktop only)\n useEffect(() => {\n if (!isDesktop) return;\n const handleClickOutside = (event: MouseEvent) => {\n if (\n containerRef.current &&\n !containerRef.current.contains(event.target as Node)\n ) {\n setIsOpen(false);\n }\n };\n if (isOpen) {\n document.addEventListener('mousedown', handleClickOutside);\n return () => document.removeEventListener('mousedown', handleClickOutside);\n }\n }, [isOpen, isDesktop]);\n\n // Close dropdown on Escape (desktop only)\n useEffect(() => {\n if (!isDesktop) return;\n const handleEscape = (event: KeyboardEvent) => {\n if (event.key === 'Escape') setIsOpen(false);\n };\n if (isOpen) {\n document.addEventListener('keydown', handleEscape);\n return () => document.removeEventListener('keydown', handleEscape);\n }\n }, [isOpen, isDesktop]);\n\n const list = (\n <NotificationList\n notifications={notifications}\n loading={loading}\n onMarkRead={markAsRead}\n onMarkAllRead={markAllAsRead}\n onDelete={deleteNotification}\n onNotificationClick={(n) => {\n onNotificationClick?.(n);\n setIsOpen(false);\n }}\n />\n );\n\n return (\n <>\n {/* ── Desktop: dropdown ── */}\n <div ref={containerRef} data-tour=\"notifications\" className={cn('relative hidden sm:block', className)}>\n <NotificationBell\n count={unreadCount}\n isOpen={isOpen}\n onToggle={() => setIsOpen((prev) => !prev)}\n />\n\n {isOpen && (\n <div\n className={cn(\n 'absolute right-0 top-full mt-2 z-50',\n 'animate-in slide-in-from-top-2 fade-in-0 duration-[400ms]',\n )}\n >\n {list}\n </div>\n )}\n </div>\n\n {/* ── Mobile: drawer ── */}\n <div className={cn('sm:hidden', className)}>\n <NotificationBell\n count={unreadCount}\n isOpen={isOpen}\n onToggle={() => setIsOpen((prev) => !prev)}\n />\n </div>\n\n <Drawer open={!isDesktop && isOpen} onOpenChange={setIsOpen}>\n <DrawerContent className=\"max-h-[85vh]\">\n <div className=\"overflow-y-auto overscroll-contain flex-1\">\n <NotificationList\n notifications={notifications}\n loading={loading}\n onMarkRead={markAsRead}\n onMarkAllRead={markAllAsRead}\n onDelete={deleteNotification}\n onNotificationClick={(n) => {\n onNotificationClick?.(n);\n setIsOpen(false);\n }}\n className=\"w-full max-h-none border-0 shadow-none rounded-none bg-transparent\"\n />\n </div>\n </DrawerContent>\n </Drawer>\n </>\n );\n};\n","'use client';\n\n// ─────────────────────────────────────────────\n// PresenceIndicator — User online status dot\n// ─────────────────────────────────────────────\n\nimport React from 'react';\nimport { cn } from '../../lib/utils';\nimport type { PresenceIndicatorProps, PresenceStatus } from './types';\n\nconst statusColors: Record<PresenceStatus, string> = {\n ONLINE: 'bg-status-success',\n AWAY: 'bg-status-warning',\n BUSY: 'bg-status-error',\n OFFLINE: 'bg-text-muted/40',\n};\n\nconst statusLabels: Record<PresenceStatus, string> = {\n ONLINE: 'Online',\n AWAY: 'Ausente',\n BUSY: 'Ocupado',\n OFFLINE: 'Offline',\n};\n\nconst sizeClasses = {\n sm: 'w-2 h-2',\n md: 'w-2.5 h-2.5',\n lg: 'w-3 h-3',\n};\n\nexport const PresenceIndicator: React.FC<PresenceIndicatorProps> = ({\n status,\n size = 'md',\n showLabel = false,\n className,\n}) => {\n return (\n <span\n className={cn('inline-flex items-center gap-1.5', className)}\n title={statusLabels[status]}\n >\n <span\n className={cn(\n 'rounded-full flex-shrink-0',\n 'border-2 border-surface-base',\n sizeClasses[size],\n statusColors[status],\n status === 'ONLINE' && 'animate-pulse',\n )}\n aria-label={statusLabels[status]}\n />\n {showLabel && (\n <span className=\"text-xs text-text-muted\">{statusLabels[status]}</span>\n )}\n </span>\n );\n};\n","'use client';\n\nimport * as React from 'react';\nimport * as PopoverPrimitive from '@radix-ui/react-popover';\nimport { cn } from '../../lib/utils';\n\nconst Popover = PopoverPrimitive.Root;\nconst PopoverTrigger = PopoverPrimitive.Trigger;\nconst PopoverAnchor = PopoverPrimitive.Anchor;\n\nfunction PopoverContent({\n className,\n align = 'center',\n sideOffset = 4,\n ...props\n}: React.ComponentProps<typeof PopoverPrimitive.Content>) {\n return (\n <PopoverPrimitive.Portal>\n <PopoverPrimitive.Content\n data-slot=\"popover-content\"\n align={align}\n sideOffset={sideOffset}\n style={{\n background: 'var(--org-glass-bg-heavy, rgba(17,14,34,0.92))',\n borderColor: 'var(--org-glass-border, rgba(167,139,250,0.15))',\n color: 'var(--org-text, #F0ECF9)',\n }}\n className={cn(\n 'z-50 w-72 rounded-xl border backdrop-blur-[40px] p-4 shadow-[0_24px_80px_-15px_rgba(0,0,0,0.5)] outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',\n className,\n )}\n {...props}\n />\n </PopoverPrimitive.Portal>\n );\n}\n\nexport { Popover, PopoverTrigger, PopoverContent, PopoverAnchor };\n","// ─────────────────────────────────────────────\n// PresenceAvatarStack — Shows online users\n// in a context (workspace, project, board)\n// Compact stacked avatars + expandable list\n// ─────────────────────────────────────────────\n\n'use client';\n\nimport * as React from 'react';\nimport { cn } from '../../lib/utils';\nimport { Avatar, AvatarFallback } from '../primitives/avatar';\nimport { Badge } from '../primitives/badge';\nimport { ScrollArea } from '../primitives/scroll-area';\nimport { Skeleton } from '../primitives/skeleton';\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n TooltipProvider,\n} from '../primitives/tooltip';\nimport { Popover, PopoverContent, PopoverTrigger } from '../primitives/popover';\nimport { PresenceIndicator } from './presence-indicator';\nimport type { PresenceStatus } from './types';\n\n// ─── Types ──────────────────────────────────\n\nexport interface PresenceUser {\n id: string;\n displayName: string;\n avatarUrl: string | null;\n status: PresenceStatus;\n lastSeen?: string;\n}\n\nexport interface PresenceAvatarStackProps {\n /** List of users with presence status */\n users: PresenceUser[];\n /** Max avatars to show before \"+N\" */\n maxVisible?: number;\n /** Size of avatars */\n size?: 'sm' | 'md' | 'lg';\n /** Show only online users in the stack */\n onlineOnly?: boolean;\n /** Loading state */\n loading?: boolean;\n /** Show the expandable popover list */\n expandable?: boolean;\n /** CSS class */\n className?: string;\n}\n\n// ─── Helpers ────────────────────────────────\n\nfunction getInitials(name: string): string {\n return name\n .split(' ')\n .map((w) => w[0])\n .slice(0, 2)\n .join('')\n .toUpperCase();\n}\n\nconst sizeConfig = {\n sm: { avatar: 'h-6 w-6', text: 'text-[9px]', stack: '-space-x-1.5', dot: 'sm' as const },\n md: { avatar: 'h-8 w-8', text: 'text-[10px]', stack: '-space-x-2', dot: 'md' as const },\n lg: { avatar: 'h-10 w-10', text: 'text-xs', stack: '-space-x-2.5', dot: 'lg' as const },\n};\n\nconst statusOrder: Record<PresenceStatus, number> = {\n ONLINE: 0,\n BUSY: 1,\n AWAY: 2,\n OFFLINE: 3,\n};\n\nfunction formatLastSeen(iso?: string): string {\n if (!iso) return '';\n const diff = Date.now() - new Date(iso).getTime();\n const mins = Math.floor(diff / 60000);\n if (mins < 1) return 'agora';\n if (mins < 60) return `${mins}m atrás`;\n const hours = Math.floor(mins / 60);\n if (hours < 24) return `${hours}h atrás`;\n return `${Math.floor(hours / 24)}d atrás`;\n}\n\n// ─── Single Avatar with Status ──────────────\n\nfunction PresenceAvatar({\n user,\n size = 'md',\n showTooltip = true,\n}: {\n user: PresenceUser;\n size?: 'sm' | 'md' | 'lg';\n showTooltip?: boolean;\n}) {\n const cfg = sizeConfig[size];\n\n const avatar = (\n <div className=\"relative\">\n <Avatar shape=\"circle\" size=\"sm\" className={cn(cfg.avatar, 'border-2 border-surface')}>\n <AvatarFallback className=\"bg-primary/20 text-primary-light font-semibold\" style={{ fontSize: 'inherit' }}>\n <span className={cfg.text}>{getInitials(user.displayName)}</span>\n </AvatarFallback>\n </Avatar>\n <span className=\"absolute -bottom-0.5 -right-0.5\">\n <PresenceIndicator status={user.status} size={cfg.dot} />\n </span>\n </div>\n );\n\n if (!showTooltip) return avatar;\n\n return (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>{avatar}</TooltipTrigger>\n <TooltipContent className=\"text-xs\">\n <p className=\"font-medium\">{user.displayName}</p>\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n );\n}\n\n// ─── Presence List (Expandable) ─────────────\n\nfunction PresenceList({\n users,\n size = 'md',\n}: {\n users: PresenceUser[];\n size?: 'sm' | 'md' | 'lg';\n}) {\n const sorted = [...users].sort((a, b) => statusOrder[a.status] - statusOrder[b.status]);\n const online = sorted.filter((u) => u.status !== 'OFFLINE');\n const offline = sorted.filter((u) => u.status === 'OFFLINE');\n\n const renderUser = (user: PresenceUser) => (\n <div\n key={user.id}\n className=\"flex items-center gap-2.5 px-3 py-1.5 rounded-xl hover:bg-theme-subtle transition-colors\"\n >\n <PresenceAvatar user={user} size=\"sm\" showTooltip={false} />\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-xs font-medium text-theme truncate\">{user.displayName}</p>\n {user.status === 'OFFLINE' && user.lastSeen && (\n <p className=\"text-[10px] text-theme-muted\">{formatLastSeen(user.lastSeen)}</p>\n )}\n </div>\n <PresenceIndicator status={user.status} size=\"sm\" showLabel />\n </div>\n );\n\n return (\n <div className=\"w-[240px]\">\n <div className=\"px-3 py-2 border-b border-theme-subtle\">\n <h4 className=\"text-xs font-semibold text-theme\">\n Membros\n <span className=\"text-theme-muted font-normal ml-1\">({users.length})</span>\n </h4>\n </div>\n <ScrollArea className=\"max-h-[300px]\">\n <div className=\"py-1\">\n {online.length > 0 && (\n <>\n <p className=\"px-3 py-1 text-[10px] text-emerald-400/70 uppercase tracking-wider font-semibold\">\n Online — {online.length}\n </p>\n {online.map(renderUser)}\n </>\n )}\n {offline.length > 0 && (\n <>\n <p className=\"px-3 py-1 mt-1 text-[10px] text-theme-muted uppercase tracking-wider font-semibold\">\n Offline — {offline.length}\n </p>\n {offline.map(renderUser)}\n </>\n )}\n {users.length === 0 && (\n <p className=\"px-3 py-4 text-xs text-theme-muted text-center\">Sem membros</p>\n )}\n </div>\n </ScrollArea>\n </div>\n );\n}\n\n// ─── Main Component ─────────────────────────\n\nexport function PresenceAvatarStack({\n users,\n maxVisible = 4,\n size = 'md',\n onlineOnly = false,\n loading = false,\n expandable = true,\n className,\n}: PresenceAvatarStackProps) {\n const cfg = sizeConfig[size];\n\n const displayUsers = onlineOnly\n ? users.filter((u) => u.status !== 'OFFLINE')\n : [...users].sort((a, b) => statusOrder[a.status] - statusOrder[b.status]);\n\n const visible = displayUsers.slice(0, maxVisible);\n const overflow = displayUsers.length - maxVisible;\n const onlineCount = users.filter((u) => u.status === 'ONLINE').length;\n\n if (loading) {\n return (\n <div className={cn('flex items-center', cfg.stack, className)}>\n {Array.from({ length: Math.min(3, maxVisible) }).map((_, i) => (\n <Skeleton\n key={i}\n variant=\"circular\"\n className={cn(cfg.avatar, 'border-2 border-surface')}\n />\n ))}\n </div>\n );\n }\n\n if (displayUsers.length === 0) {\n return null;\n }\n\n const stack = (\n <div className={cn('flex items-center', className)}>\n <div className={cn('flex items-center', cfg.stack)}>\n {visible.map((user) => (\n <PresenceAvatar\n key={user.id}\n user={user}\n size={size}\n showTooltip={!expandable}\n />\n ))}\n\n {overflow > 0 && (\n <div\n className={cn(\n cfg.avatar,\n 'flex items-center justify-center rounded-full border-2 border-surface bg-theme-subtle',\n cfg.text,\n 'font-medium text-theme-muted',\n )}\n >\n +{overflow}\n </div>\n )}\n </div>\n\n {/* Online count badge */}\n <Badge\n variant=\"default\"\n className=\"ml-2 text-[10px] px-1.5 py-0 h-4 border-emerald-500/20 text-emerald-400/70 bg-emerald-500/5\"\n >\n <span className=\"w-1.5 h-1.5 rounded-full bg-emerald-400 mr-1 animate-pulse\" />\n {onlineCount}\n </Badge>\n </div>\n );\n\n if (!expandable) return stack;\n\n return (\n <Popover>\n <PopoverTrigger asChild>\n <button className=\"cursor-pointer hover:opacity-80 transition-opacity\">\n {stack}\n </button>\n </PopoverTrigger>\n <PopoverContent\n className=\"p-0 bg-white/[0.03] backdrop-blur-[40px] border-primary/25 shadow-[0_24px_80px_-15px_rgba(0,0,0,0.5)]\"\n align=\"end\"\n >\n <PresenceList users={users} size={size} />\n </PopoverContent>\n </Popover>\n );\n}\n","// ─────────────────────────────────────────────\n// usePresence — React hook for presence tracking\n// ─────────────────────────────────────────────\n\nimport { useState, useEffect, useCallback, useRef } from 'react';\nimport type { UserPresence, PresenceStatus } from './types';\n\ninterface UsePresenceOptions {\n gatewayUrl: string;\n userId: string;\n authToken?: string;\n /** Direct service URLs (bypasses gateway) */\n services?: { notifications?: string };\n /** Heartbeat interval in ms (default: 30s) */\n heartbeatInterval?: number;\n /** Auto-connect on mount */\n autoConnect?: boolean;\n}\n\ninterface UsePresenceReturn {\n onlineUsers: UserPresence[];\n myStatus: PresenceStatus;\n isConnected: boolean;\n setStatus: (status: PresenceStatus) => void;\n getUserStatus: (userId: string) => PresenceStatus;\n fetchOnlineUsers: () => Promise<void>;\n}\n\nexport function usePresence(options: UsePresenceOptions): UsePresenceReturn {\n const {\n gatewayUrl,\n userId,\n authToken,\n heartbeatInterval = 30000,\n autoConnect = true,\n } = options;\n\n const [onlineUsers, setOnlineUsers] = useState<UserPresence[]>([]);\n const [myStatus, setMyStatus] = useState<PresenceStatus>('ONLINE');\n const [isConnected, setIsConnected] = useState(false);\n const heartbeatRef = useRef<ReturnType<typeof setInterval> | null>(null);\n\n // Presence GraphQL goes through gateway proxy (/api/graphql/notifications)\n // which injects x-user-id from the JWT cookie.\n const graphqlUrl = `${gatewayUrl}/api/graphql/notifications`;\n\n const gqlFetch = useCallback(\n async (query: string, variables?: Record<string, any>) => {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n if (authToken) headers['Authorization'] = `Bearer ${authToken}`;\n\n const res = await fetch(graphqlUrl, {\n method: 'POST',\n headers,\n credentials: 'include',\n body: JSON.stringify({ query, variables }),\n });\n\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const json = await res.json();\n if (json.errors?.length) throw new Error(json.errors[0].message);\n return json.data;\n },\n [graphqlUrl, userId, authToken],\n );\n\n const fetchOnlineUsers = useCallback(async () => {\n try {\n const data = await gqlFetch(`\n query GetOnlineUsers {\n onlineUsers {\n users { userId status connectedAt lastActivityAt sessionCount }\n count\n }\n }\n `);\n setOnlineUsers(data.onlineUsers.users);\n setIsConnected(true);\n } catch {\n setIsConnected(false);\n }\n }, [gqlFetch]);\n\n const setStatus = useCallback(\n (status: PresenceStatus) => {\n setMyStatus(status);\n // Fire-and-forget status update\n gqlFetch('').catch(() => {});\n },\n [gqlFetch],\n );\n\n const getUserStatus = useCallback(\n (targetUserId: string): PresenceStatus => {\n const user = onlineUsers.find((u) => u.userId === targetUserId);\n return user?.status || 'OFFLINE';\n },\n [onlineUsers],\n );\n\n // Auto-connect: fetch online users on mount\n useEffect(() => {\n if (autoConnect && userId) {\n fetchOnlineUsers();\n }\n }, [autoConnect, userId, fetchOnlineUsers]);\n\n // Heartbeat polling\n useEffect(() => {\n if (heartbeatInterval > 0 && userId) {\n heartbeatRef.current = setInterval(() => {\n fetchOnlineUsers();\n }, heartbeatInterval);\n\n return () => {\n if (heartbeatRef.current) clearInterval(heartbeatRef.current);\n };\n }\n }, [heartbeatInterval, userId, fetchOnlineUsers]);\n\n // Visibility change → away/online\n useEffect(() => {\n const handleVisibility = () => {\n if (document.hidden) {\n setMyStatus('AWAY');\n } else {\n setMyStatus('ONLINE');\n }\n };\n\n document.addEventListener('visibilitychange', handleVisibility);\n return () => document.removeEventListener('visibilitychange', handleVisibility);\n }, []);\n\n return {\n onlineUsers,\n myStatus,\n isConnected,\n setStatus,\n getUserStatus,\n fetchOnlineUsers,\n };\n}\n"]}
|
|
@@ -158,6 +158,10 @@ var OrganifyContext = React3.createContext({
|
|
|
158
158
|
function useOrganify() {
|
|
159
159
|
return React3.useContext(OrganifyContext);
|
|
160
160
|
}
|
|
161
|
+
function useOrganifyLookupUser() {
|
|
162
|
+
const { lookupUser } = React3.useContext(OrganifyContext);
|
|
163
|
+
return lookupUser ?? (() => null);
|
|
164
|
+
}
|
|
161
165
|
function useOrganifyApi() {
|
|
162
166
|
const ctx = React3.useContext(OrganifyContext);
|
|
163
167
|
return ctx.api ?? { gatewayUrl: "" };
|
|
@@ -562,6 +566,6 @@ function ScrollBar({
|
|
|
562
566
|
);
|
|
563
567
|
}
|
|
564
568
|
|
|
565
|
-
export { Avatar, AvatarFallback, AvatarImage, Badge, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, OrganifyContext, OrganifyProvider, ScrollArea, ScrollBar, Skeleton, SkeletonCard, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, avatarVariants, badgeVariants, cn, useOrganify, useOrganifyApi, useOrganifyGql, useOrganifyNavigation, useOrganifyProject, useOrganifyRest, useOrganifyUser, useOrganifyWorkspace };
|
|
566
|
-
//# sourceMappingURL=chunk-
|
|
567
|
-
//# sourceMappingURL=chunk-
|
|
569
|
+
export { Avatar, AvatarFallback, AvatarImage, Badge, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, OrganifyContext, OrganifyProvider, ScrollArea, ScrollBar, Skeleton, SkeletonCard, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, avatarVariants, badgeVariants, cn, useOrganify, useOrganifyApi, useOrganifyGql, useOrganifyLookupUser, useOrganifyNavigation, useOrganifyProject, useOrganifyRest, useOrganifyUser, useOrganifyWorkspace };
|
|
570
|
+
//# sourceMappingURL=chunk-XXBUSG5Q.js.map
|
|
571
|
+
//# sourceMappingURL=chunk-XXBUSG5Q.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/utils.ts","../src/components/primitives/badge.tsx","../src/components/primitives/avatar.tsx","../src/components/primitives/tooltip.tsx","../src/providers/organify-provider.tsx","../src/components/primitives/skeleton.tsx","../src/components/primitives/drawer.tsx","../src/components/primitives/scroll-area.tsx"],"names":["cva","React","jsxs","jsx","React2","json","DrawerPrimitive"],"mappings":"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","file":"chunk-XXBUSG5Q.js","sourcesContent":["import { type ClassValue, clsx } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\n/**\n * Merge Tailwind CSS classes with clsx — the standard shadcn pattern.\n */\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","import * as React from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { cn } from '../../lib/utils';\n\n/**\n * Badge — Status badges & context indicators\n *\n * Organic Design System — smooth pill shapes.\n * Theme-aware: uses CSS variables for theme switching.\n */\nconst badgeVariants = cva(\n 'inline-flex items-center gap-2 text-caption font-bold uppercase tracking-wider transition-all duration-[400ms] ease-[cubic-bezier(0.25,1,0.5,1)]',\n {\n variants: {\n variant: {\n default:\n 'rounded-full border border-primary/15 bg-white/[0.05] px-3 py-1.5 text-org-text-secondary',\n primary:\n 'rounded-full border border-indigo-400/30 bg-indigo-500/20 px-3 py-1.5 text-indigo-300',\n success:\n 'rounded-full border border-success/30 bg-success/10 px-3 py-1.5 text-success-light',\n warning:\n 'rounded-full border border-warning/30 bg-warning/10 px-3 py-1.5 text-warning-light',\n error:\n 'rounded-full border border-error/30 bg-error/10 px-3 py-1.5 text-error-light',\n info:\n 'rounded-full border border-info/30 bg-info/10 px-3 py-1.5 text-info-light',\n\n // ─── Flow status (from Brand Assets HTML) ──\n 'in-flow':\n 'rounded-full border border-indigo-500/30 bg-indigo-500/20 px-3 py-1.5 text-indigo-200 shadow-[0_0_15px_rgba(99,102,241,0.15)]',\n 'deep-work':\n 'rounded-full border border-fuchsia-500/20 bg-fuchsia-500/10 px-3 py-1.5 text-fuchsia-200',\n 'high-energy':\n 'rounded-full border border-emerald-500/20 bg-emerald-500/10 px-3 py-1.5 text-emerald-200',\n\n // ─── Cream Light theme ─────────────────────\n 'cream-default':\n 'rounded-full border border-neutral-200 bg-white/50 px-3 py-1 text-neutral-600 backdrop-blur-sm',\n 'cream-primary':\n 'rounded-full border border-primary/20 bg-primary/5 px-3 py-1 text-primary',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n },\n);\n\nexport interface BadgeProps\n extends React.HTMLAttributes<HTMLDivElement>,\n VariantProps<typeof badgeVariants> {\n /** Animated pulse dot */\n dot?: boolean;\n /** Dot color class (e.g. 'bg-indigo-400') */\n dotColor?: string;\n}\n\nfunction Badge({ className, variant, dot, dotColor, children, ...props }: BadgeProps) {\n return (\n <div className={cn(badgeVariants({ variant }), className)} {...props}>\n {dot && (\n <span\n className={cn(\n 'h-1.5 w-1.5 rounded-full animate-pulse',\n dotColor || 'bg-current',\n variant === 'in-flow' && 'shadow-[0_0_8px_rgba(129,140,248,0.8)]',\n )}\n />\n )}\n {children}\n </div>\n );\n}\n\nexport { Badge, badgeVariants };\n","'use client';\n\nimport * as React from 'react';\nimport * as AvatarPrimitive from '@radix-ui/react-avatar';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { cn } from '../../lib/utils';\n\n/**\n * Avatar — Geometric asymmetric avatars\n *\n * From the Brand Assets HTML: asymmetric shapes with gradient backgrounds,\n * geometric corner accents, status dot indicators.\n * Theme-aware: uses CSS variables for theme switching.\n */\nconst avatarVariants = cva(\n 'relative overflow-hidden border border-primary/15 flex items-center justify-center',\n {\n variants: {\n shape: {\n circle: 'rounded-full',\n 'asym-1': 'rounded-asym-1',\n 'asym-2': 'rounded-asym-2',\n geo: 'rounded-geo',\n 'geo-inv': 'rounded-geo-inv',\n square: 'rounded-xl',\n },\n size: {\n sm: 'h-8 w-8',\n default: 'h-10 w-10',\n lg: 'h-16 w-16',\n xl: 'h-20 w-20',\n },\n },\n defaultVariants: {\n shape: 'circle',\n size: 'default',\n },\n },\n);\n\nexport interface AvatarProps\n extends React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root>,\n VariantProps<typeof avatarVariants> {\n /** Online status indicator */\n status?: 'online' | 'offline' | 'away' | 'busy';\n /** Status dot color class override */\n statusColor?: string;\n /** Gradient background for fallback */\n gradient?: string;\n}\n\nconst Avatar = React.forwardRef<\n React.ComponentRef<typeof AvatarPrimitive.Root>,\n AvatarProps\n>(({ className, shape, size, status, statusColor, gradient, ...props }, ref) => (\n <div className=\"relative inline-flex\">\n <AvatarPrimitive.Root\n ref={ref}\n className={cn(\n avatarVariants({ shape, size }),\n gradient && `bg-gradient-to-br ${gradient}`,\n className,\n )}\n {...props}\n />\n {status && (\n <span\n className={cn(\n 'absolute -bottom-0.5 -right-0.5 rounded-full border-2 border-surface',\n size === 'sm' && 'h-2.5 w-2.5',\n size === 'default' && 'h-3 w-3',\n (size === 'lg' || size === 'xl') && 'h-3.5 w-3.5',\n statusColor ||\n (status === 'online' && 'bg-green-500'),\n status === 'offline' && 'bg-neutral-500',\n status === 'away' && 'bg-amber-500',\n status === 'busy' && 'bg-red-500',\n )}\n />\n )}\n {/* Geometric corner accent for lg/xl */}\n {(size === 'lg' || size === 'xl') && shape !== 'circle' && (\n <div className=\"absolute bottom-0 right-0 h-3 w-3 rotate-45 translate-x-1/2 translate-y-1/2 bg-primary-light\" />\n )}\n </div>\n));\nAvatar.displayName = 'Avatar';\n\nconst AvatarImage = React.forwardRef<\n React.ComponentRef<typeof AvatarPrimitive.Image>,\n React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Image>\n>(({ className, ...props }, ref) => (\n <AvatarPrimitive.Image\n ref={ref}\n className={cn('aspect-square h-full w-full object-cover', className)}\n {...props}\n />\n));\nAvatarImage.displayName = 'AvatarImage';\n\nconst AvatarFallback = React.forwardRef<\n React.ComponentRef<typeof AvatarPrimitive.Fallback>,\n React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback>\n>(({ className, ...props }, ref) => (\n <AvatarPrimitive.Fallback\n ref={ref}\n className={cn(\n 'flex h-full w-full items-center justify-center text-sm font-medium text-white/90',\n className,\n )}\n {...props}\n />\n));\nAvatarFallback.displayName = 'AvatarFallback';\n\nexport { Avatar, AvatarImage, AvatarFallback, avatarVariants };\n","'use client';\n\nimport * as React from 'react';\nimport * as TooltipPrimitive from '@radix-ui/react-tooltip';\nimport { cn } from '../../lib/utils';\n\n/**\n * Tooltip — Organic glass tooltip\n *\n * Theme-aware: uses CSS variables for theme switching.\n * Squircle shape with glass backdrop.\n */\n\nconst TooltipProvider = TooltipPrimitive.Provider;\nconst Tooltip = TooltipPrimitive.Root;\nconst TooltipTrigger = TooltipPrimitive.Trigger;\n\nconst TooltipContent = React.forwardRef<\n React.ComponentRef<typeof TooltipPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>\n>(({ className, sideOffset = 6, ...props }, ref) => (\n <TooltipPrimitive.Portal>\n <TooltipPrimitive.Content\n ref={ref}\n sideOffset={sideOffset}\n className={cn(\n 'z-50 max-w-[12rem] bg-white/[0.05] backdrop-blur-[40px] border border-primary/15 rounded-xl px-2.5 py-1.5 text-[11px] leading-snug text-white/90 shadow-[0_24px_80px_-15px_rgba(0,0,0,0.5)] animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-1 data-[side=left]:slide-in-from-right-1 data-[side=right]:slide-in-from-left-1 data-[side=top]:slide-in-from-bottom-1',\n className,\n )}\n {...props}\n />\n </TooltipPrimitive.Portal>\n));\nTooltipContent.displayName = TooltipPrimitive.Content.displayName;\n\nexport { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };\n","// ─────────────────────────────────────────────\n// OrganifyProvider — Shared data context\n// ─────────────────────────────────────────────\n// Holds workspace, user, project data + API config\n// so that organify-ui components (WorkspaceSwitcher,\n// OrganifyNotifications, OrganifyChat, TaskDetailDialog,\n// CommentThread, etc.) can do internal API fetches\n// instead of receiving data via props.\n//\n// ALL API requests must go through:\n// useOrganifyGql(endpoint, query, vars) — for GraphQL\n// useOrganifyRest(endpoint, options) — for REST\n//\n// Never use raw fetch() directly.\n// ─────────────────────────────────────────────\n\n'use client';\n\nimport * as React from 'react';\n\n// ─── Types ──────────────────────────────────\n\nexport interface OrganifyWorkspace {\n id: string;\n name: string;\n slug: string;\n description?: string | null;\n avatarUrl?: string | null;\n plan?: { name: string } | null;\n _count?: {\n members?: number;\n teams?: number;\n invites?: number;\n };\n}\n\nexport interface OrganifyUser {\n id: string;\n name: string;\n email: string;\n avatarUrl?: string | null;\n role?: string;\n}\n\nexport interface OrganifyProject {\n id: string;\n name: string;\n slug: string;\n description?: string | null;\n type?: string;\n status?: string;\n}\n\nexport interface OrganifyApiConfig {\n /** Gateway base URL (e.g. http://localhost:4000) */\n gatewayUrl: string;\n /** JWT auth token (from cookie or auth state) */\n authToken?: string;\n /** Direct service URLs for WebSocket/subscription connections (bypass gateway) */\n services?: {\n /** Chat service (e.g. https://organify-chat-service.onrender.com) */\n chat?: string;\n /** Notifications service (e.g. https://organify-notifications-service.onrender.com) */\n notifications?: string;\n /** Projects service (e.g. https://organify-projects-service.onrender.com) */\n projects?: string;\n /** Workspaces service (e.g. https://modern-nikki-organify-studio-787ea453.koyeb.app) */\n workspaces?: string;\n };\n}\n\n// ─── Endpoint Types ─────────────────────────\n// Pre-configured endpoint keys for useOrganifyGql\n\nexport type GqlEndpoint = 'projects' | 'chat' | 'notifications' | 'workspaces';\nexport type RestEndpoint = 'auth' | 'users' | 'onboarding' | 'workspaces' | 'projects';\n\nexport interface OrganifyContextValue {\n // ─── API Configuration ────────────────\n api: OrganifyApiConfig;\n\n // Current workspace\n workspace: OrganifyWorkspace | null;\n workspaceLoading: boolean;\n\n // All available workspaces (for switcher)\n workspaces: OrganifyWorkspace[];\n workspacesLoading: boolean;\n\n // Current user\n user: OrganifyUser | null;\n\n // Optional helper used by components/hooks to resolve a user id into a\n // proper OrganifyUser object. Host apps may provide this using their own\n // cache (e.g. IndexedDB + Zustand). If not provided, components must rely\n // on whatever minimal actorName/avatarUrl the API returns.\n lookupUser?: (id: string) => OrganifyUser | null;\n\n // Current project (optional, set inside project routes)\n project: OrganifyProject | null;\n projectLoading: boolean;\n\n // Navigation\n navigate?: (path: string) => void;\n\n // Render helpers\n renderLink?: (props: {\n href: string;\n children: React.ReactNode;\n className?: string;\n onClick?: () => void;\n }) => React.ReactNode;\n\n // ─── Workspace Mutation Callbacks ─────\n // Called by internal components (WorkspaceSwitcher) to update parent state.\n // The host app provides these to keep its workspace state in sync.\n\n /** Called when workspaces list changes (create, update, delete) */\n onWorkspacesChange?: (workspaces: OrganifyWorkspace[]) => void;\n\n /** Called when active workspace should change (e.g. after create, switch) */\n onWorkspaceChange?: (workspace: OrganifyWorkspace | null) => void;\n}\n\n// ─── Context ────────────────────────────────\n\nconst OrganifyContext = React.createContext<OrganifyContextValue>({\n api: { gatewayUrl: '' },\n workspace: null,\n workspaceLoading: false,\n workspaces: [],\n workspacesLoading: false,\n user: null,\n project: null,\n projectLoading: false,\n});\n\n// ─── Hooks ──────────────────────────────────\n\nexport function useOrganify(): OrganifyContextValue {\n return React.useContext(OrganifyContext);\n}\n\n/**\n * Lookup a user by ID using the provider-supplied helper. Falls back to null.\n */\nexport function useOrganifyLookupUser(): ((id: string) => OrganifyUser | null) {\n const { lookupUser } = React.useContext(OrganifyContext);\n return lookupUser ?? (() => null);\n}\n\n/** Access the API config (gatewayUrl, authToken, services) for internal fetches */\nexport function useOrganifyApi(): OrganifyApiConfig {\n const ctx = React.useContext(OrganifyContext);\n return ctx.api ?? { gatewayUrl: '' };\n}\n\n// ─── URL Resolution ─────────────────────────\n\n/**\n * Resolves the full URL for a GraphQL endpoint.\n *\n * Routing logic:\n * - 'projects' → gatewayUrl/api/graphql (via gateway proxy)\n * - 'chat' → gatewayUrl/api/graphql (via gateway proxy)\n * - 'notifications' → gatewayUrl/api/graphql (via gateway proxy)\n * - 'workspaces' → gatewayUrl/api/graphql (via gateway proxy)\n *\n * The gateway at port 4000 has a global `/api` prefix and proxies all\n * GraphQL endpoints through `/api/graphql/[subgraph]`:\n * - POST /api/graphql/workspaces → workspaces subgraph\n * - POST /api/graphql/projects → projects subgraph\n * - POST /api/graphql/chat → chat subgraph\n * - POST /api/graphql/notifications → notifications subgraph\n *\n * Also accepts legacy full paths like '/graphql/projects' or '/api/graphql'.\n */\nfunction resolveGqlUrl(\n endpoint: string,\n gatewayUrl: string,\n services?: OrganifyApiConfig['services'],\n): string {\n // Normalise: strip leading slash if present\n const ep = endpoint.replace(/^\\//, '');\n\n // Named endpoint keys → gateway proxy with /api prefix\n switch (ep) {\n case 'projects':\n return `${gatewayUrl}/api/graphql/projects`;\n case 'chat':\n return `${gatewayUrl}/api/graphql/chat`;\n case 'notifications':\n return `${gatewayUrl}/api/graphql/notifications`;\n case 'workspaces': {\n // Gateway proxy (primary) or direct service fallback\n return `${gatewayUrl}/api/graphql/workspaces`;\n }\n default:\n break;\n }\n\n // Legacy full paths — support both /graphql/* and /api/graphql/*\n if (ep.startsWith('graphql/')) {\n return `${gatewayUrl}/api/${ep}`;\n }\n if (ep.startsWith('api/graphql')) {\n return `${gatewayUrl}/${ep}`;\n }\n\n // Absolute URL passthrough (for services that need direct connection)\n if (ep.startsWith('http://') || ep.startsWith('https://')) {\n return ep;\n }\n\n // Fallback: attach to gateway with /api prefix\n return `${gatewayUrl}/api/${ep}`;\n}\n\n/**\n * Resolves the full URL for a REST endpoint.\n *\n * Routing logic:\n * - 'auth' → gatewayUrl/api/auth\n * - 'users' → gatewayUrl/api/users\n * - 'onboarding' → gatewayUrl/api/onboarding\n * - 'workspaces' → gatewayUrl/api/internal/workspaces\n * - 'projects' → gatewayUrl/api/internal/projects\n *\n * Also accepts full paths like '/api/auth/me'.\n */\nfunction resolveRestUrl(\n endpoint: string,\n path: string,\n gatewayUrl: string,\n): string {\n const p = path.replace(/^\\//, '');\n\n switch (endpoint) {\n case 'auth':\n return `${gatewayUrl}/api/auth/${p}`;\n case 'users':\n return `${gatewayUrl}/api/users/${p}`;\n case 'onboarding':\n return `${gatewayUrl}/api/onboarding/${p}`;\n case 'workspaces':\n return `${gatewayUrl}/api/internal/workspaces/${p}`;\n case 'projects':\n return `${gatewayUrl}/api/internal/projects/${p}`;\n default:\n break;\n }\n\n // Full path passthrough (e.g. '/api/auth/me')\n if (endpoint.startsWith('/')) {\n return `${gatewayUrl}${endpoint}`;\n }\n\n return `${gatewayUrl}/${endpoint}`;\n}\n\n// ─── Client-side Query Rate Limiter ─────────\n// Prevents runaway re-fetches from overwhelming the backend.\n// Deduplicates identical queries within a sliding window.\n\nconst GQL_RATE_LIMIT_WINDOW = 2000; // 2 seconds\nconst GQL_RATE_LIMIT_MAX = 5; // max 5 identical queries per window\n\n/** Global map: \"endpoint|queryHash|varsHash\" → timestamp[] */\nconst _gqlQueryLog = new Map<string, number[]>();\n\nfunction _gqlRateLimitKey(endpoint: string, query: string, variables?: Record<string, any>): string {\n // Fast hash: first 80 chars of the query + stringified vars (or empty)\n const qKey = query.replace(/\\s+/g, ' ').slice(0, 80);\n const vKey = variables ? JSON.stringify(variables) : '';\n return `${endpoint}|${qKey}|${vKey}`;\n}\n\nfunction _gqlCheckRateLimit(key: string): boolean {\n const now = Date.now();\n const times = _gqlQueryLog.get(key) ?? [];\n // Evict old entries\n const recent = times.filter((t) => now - t < GQL_RATE_LIMIT_WINDOW);\n if (recent.length >= GQL_RATE_LIMIT_MAX) {\n _gqlQueryLog.set(key, recent);\n return false; // blocked\n }\n recent.push(now);\n _gqlQueryLog.set(key, recent);\n return true; // allowed\n}\n\nfunction readAuthTokenCookie(cookieName = 'auth_token'): string | null {\n if (typeof document === 'undefined') return null;\n const match = document.cookie\n .split(';')\n .map((s) => s.trim())\n .find((s) => s.startsWith(`${cookieName}=`));\n if (!match) return null;\n return decodeURIComponent(match.split('=')[1]);\n}\n\n// ─── Centralized GraphQL Client ─────────────\n\n/**\n * Universal GraphQL fetch helper — ALL GraphQL requests go through this.\n *\n * Includes client-side rate limiting: identical queries are capped at\n * 5 per 2-second window. If exceeded, the call throws to prevent\n * runaway loops from overwhelming the backend.\n *\n * Usage:\n * const gql = useOrganifyGql();\n * const data = await gql('projects', CREATE_TASK_MUTATION, { input });\n * const data = await gql('chat', GET_ROOMS_QUERY, { workspaceId });\n * const data = await gql('workspaces', GET_WORKSPACES_QUERY);\n * const data = await gql('notifications', GET_NOTIFICATIONS_QUERY, { filter });\n */\nexport function useOrganifyGql() {\n const api = useOrganifyApi();\n const gatewayUrl = api?.gatewayUrl ?? '';\n const authToken = api?.authToken;\n const services = api?.services;\n\n return React.useCallback(\n async <T = any>(\n endpoint: GqlEndpoint | string,\n query: string,\n variables?: Record<string, any>,\n ): Promise<T> => {\n // ─── Rate limit check ──\n const rlKey = _gqlRateLimitKey(endpoint, query, variables);\n if (!_gqlCheckRateLimit(rlKey)) {\n console.warn(\n `[useOrganifyGql] Rate limited — ${GQL_RATE_LIMIT_MAX} identical requests in ${GQL_RATE_LIMIT_WINDOW}ms window`,\n { endpoint, variables },\n );\n throw new Error('Rate limited: too many identical requests');\n }\n\n const url = resolveGqlUrl(endpoint, gatewayUrl, services);\n const token = authToken || readAuthTokenCookie();\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n if (token) headers['Authorization'] = `Bearer ${token}`;\n\n console.log(\n `[useOrganifyGql] ${endpoint} ${token ? '✓ token' : '⚠ no token'}`,\n Object.keys(variables || {}).length > 0 ? `vars: ${JSON.stringify(variables)}` : '',\n );\n\n const res = await fetch(url, {\n method: 'POST',\n headers,\n credentials: 'include',\n body: JSON.stringify({ query, variables }),\n });\n\n if (!res.ok) {\n const json = await res.json();\n const errorMsg = json.errors?.[0]?.message || json.error || `HTTP ${res.status}`;\n const originalError = json.errors?.[0]?.extensions?.originalError?.message;\n console.error(`[useOrganifyGql] ${res.status} error on ${endpoint}:`, {\n message: errorMsg,\n originalError,\n errors: json.errors,\n });\n throw new Error(`HTTP ${res.status}: ${errorMsg}${originalError ? ` (${originalError})` : ''}`);\n }\n const json = await res.json();\n if (json.errors?.length) {\n const errorMsg = json.errors[0].message;\n const originalError = json.errors[0]?.extensions?.originalError?.message;\n console.error(`[useOrganifyGql] GraphQL error on ${endpoint}:`, {\n message: errorMsg,\n originalError,\n errors: json.errors,\n });\n throw new Error(`${errorMsg}${originalError ? ` (${originalError})` : ''}`);\n }\n return json.data;\n },\n [gatewayUrl, authToken, services],\n );\n}\n\n// ─── Centralized REST Client ────────────────\n\n/**\n * Universal REST fetch helper — ALL REST requests go through this.\n *\n * Usage:\n * const rest = useOrganifyRest();\n * const user = await rest('auth', 'me');\n * const data = await rest('auth', 'login', { method: 'POST', body: { email, password } });\n * const ws = await rest('workspaces', '');\n */\nexport function useOrganifyRest() {\n const api = useOrganifyApi();\n const gatewayUrl = api?.gatewayUrl ?? '';\n const authToken = api?.authToken;\n\n return React.useCallback(\n async <T = any>(\n endpoint: RestEndpoint | string,\n path: string = '',\n options?: {\n method?: string;\n body?: any;\n headers?: Record<string, string>;\n },\n ): Promise<T> => {\n const url = resolveRestUrl(endpoint, path, gatewayUrl);\n const method = options?.method ?? 'GET';\n const token = authToken || readAuthTokenCookie();\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...(options?.headers ?? {}),\n };\n if (token) headers['Authorization'] = `Bearer ${token}`;\n\n const fetchOpts: RequestInit = {\n method,\n headers,\n credentials: 'include',\n };\n if (options?.body && method !== 'GET') {\n fetchOpts.body = JSON.stringify(options.body);\n }\n\n const res = await fetch(url, fetchOpts);\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const json = await res.json();\n return json.data ?? json;\n },\n [gatewayUrl, authToken],\n );\n}\n\n// ─── Data Hooks ─────────────────────────────\n\nexport function useOrganifyWorkspace() {\n const ctx = React.useContext(OrganifyContext);\n return {\n workspace: ctx.workspace,\n loading: ctx.workspaceLoading,\n workspaces: ctx.workspaces,\n workspacesLoading: ctx.workspacesLoading,\n onWorkspacesChange: ctx.onWorkspacesChange,\n onWorkspaceChange: ctx.onWorkspaceChange,\n };\n}\n\nexport function useOrganifyUser() {\n const ctx = React.useContext(OrganifyContext);\n return ctx.user;\n}\n\nexport function useOrganifyProject() {\n const ctx = React.useContext(OrganifyContext);\n return {\n project: ctx.project,\n loading: ctx.projectLoading,\n };\n}\n\nexport function useOrganifyNavigation() {\n const ctx = React.useContext(OrganifyContext);\n return {\n navigate: ctx.navigate,\n renderLink: ctx.renderLink,\n };\n}\n\n// ─── Provider ───────────────────────────────\n\nexport interface OrganifyProviderProps {\n children: React.ReactNode;\n value: Partial<OrganifyContextValue> & { api: OrganifyApiConfig };\n}\n\nfunction OrganifyProvider({ children, value }: OrganifyProviderProps) {\n const merged = React.useMemo<OrganifyContextValue>(\n () => ({\n api: value.api,\n workspace: value.workspace ?? null,\n workspaceLoading: value.workspaceLoading ?? false,\n workspaces: value.workspaces ?? [],\n workspacesLoading: value.workspacesLoading ?? false,\n user: value.user ?? null,\n project: value.project ?? null,\n projectLoading: value.projectLoading ?? false,\n navigate: value.navigate,\n renderLink: value.renderLink,\n onWorkspacesChange: value.onWorkspacesChange,\n onWorkspaceChange: value.onWorkspaceChange,\n }),\n [\n value.api,\n value.workspace,\n value.workspaceLoading,\n value.workspaces,\n value.workspacesLoading,\n value.user,\n value.project,\n value.projectLoading,\n value.navigate,\n value.renderLink,\n value.onWorkspacesChange,\n value.onWorkspaceChange,\n ],\n );\n\n return (\n <OrganifyContext.Provider value={merged}>\n {children}\n </OrganifyContext.Provider>\n );\n}\n\nOrganifyProvider.displayName = 'OrganifyProvider';\n\nexport { OrganifyProvider, OrganifyContext };\n","import * as React from 'react';\nimport { cn } from '../../lib/utils';\n\n/**\n * Skeleton — Shimmer loading placeholder\n *\n * From the design system: bg-white/10 with a sliding gradient shimmer animation.\n */\n\nexport interface SkeletonProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Shape variant */\n variant?: 'rectangular' | 'circular' | 'rounded';\n}\n\nfunction Skeleton({ className, variant = 'rounded', ...props }: SkeletonProps) {\n return (\n <div\n className={cn(\n 'skeleton-shimmer',\n variant === 'circular' && 'rounded-full',\n variant === 'rounded' && 'rounded-xl',\n variant === 'rectangular' && 'rounded-none',\n className,\n )}\n {...props}\n />\n );\n}\n\n/**\n * SkeletonCard — Pre-built skeleton card from the design system\n */\nfunction SkeletonCard({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {\n return (\n <div className={cn('glass-panel space-y-6 p-6', className)} {...props}>\n <div className=\"flex items-center gap-5\">\n <Skeleton className=\"h-14 w-14 shrink-0\" variant=\"rounded\" />\n <div className=\"flex-1 space-y-2.5\">\n <Skeleton className=\"h-4 w-2/3\" />\n <Skeleton className=\"h-3 w-1/2 opacity-60\" />\n </div>\n </div>\n <div className=\"space-y-3 pt-2\">\n <Skeleton className=\"h-24 w-full rounded-xl\" />\n <div className=\"flex justify-between pt-1\">\n <Skeleton className=\"h-3 w-20 opacity-40\" />\n <Skeleton className=\"h-3 w-20 opacity-40\" />\n </div>\n </div>\n </div>\n );\n}\n\nexport { Skeleton, SkeletonCard };\n","'use client';\n\nimport * as React from 'react';\nimport { motion } from 'framer-motion';\nimport { Drawer as DrawerPrimitive } from 'vaul';\nimport { cn } from '../../lib/utils';\n\nfunction Drawer({\n shouldScaleBackground = true,\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Root>) {\n return <DrawerPrimitive.Root shouldScaleBackground={shouldScaleBackground} {...props} />;\n}\n\nconst DrawerTrigger = DrawerPrimitive.Trigger;\nconst DrawerPortal = DrawerPrimitive.Portal;\nconst DrawerClose = DrawerPrimitive.Close;\n\nfunction DrawerOverlay({\n className,\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Overlay>) {\n return (\n <DrawerPrimitive.Overlay\n data-slot=\"drawer-overlay\"\n className={cn('fixed inset-0 z-[200] bg-theme-subtle-20', className)}\n {...props}\n />\n );\n}\n\nfunction DrawerContent({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Content>) {\n return (\n <DrawerPortal>\n <DrawerOverlay />\n <DrawerPrimitive.Content\n asChild\n data-slot=\"drawer-content\"\n {...props}\n >\n <motion.div\n initial={{ y: '100%', opacity: 0 }}\n animate={{ y: 0, opacity: 1 }}\n exit={{ y: '100%', opacity: 0 }}\n transition={{\n type: 'spring',\n stiffness: 400,\n damping: 40,\n }}\n className={cn(\n 'fixed inset-x-0 bottom-0 z-[200] mt-24 flex h-auto flex-col rounded-t-[10px] border-t border-x border-gray-200 dark:!border-gray-800 !bg-white dark:!bg-[#0D0A1A] !text-gray-900 dark:!text-gray-100 shadow-2xl dark:shadow-[0_-10px_40px_rgba(124,58,237,0.15)]',\n className,\n )}\n >\n <div className=\"mx-auto mt-4 h-2 w-[100px] rounded-full bg-theme-subtle\" />\n {children}\n </motion.div>\n </DrawerPrimitive.Content>\n </DrawerPortal>\n );\n}\n\nfunction DrawerHeader({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"drawer-header\"\n className={cn('grid gap-1.5 p-4 text-center sm:text-left', className)}\n {...props}\n />\n );\n}\n\nfunction DrawerFooter({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"drawer-footer\"\n className={cn('mt-auto flex flex-col gap-2 p-4', className)}\n {...props}\n />\n );\n}\n\nfunction DrawerTitle({\n className,\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Title>) {\n return (\n <DrawerPrimitive.Title\n data-slot=\"drawer-title\"\n className={cn('text-lg font-semibold leading-none tracking-tight', className)}\n {...props}\n />\n );\n}\n\nfunction DrawerDescription({\n className,\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Description>) {\n return (\n <DrawerPrimitive.Description\n data-slot=\"drawer-description\"\n className={cn('text-sm text-theme-secondary', className)}\n {...props}\n />\n );\n}\n\nexport {\n Drawer,\n DrawerPortal,\n DrawerOverlay,\n DrawerTrigger,\n DrawerClose,\n DrawerContent,\n DrawerHeader,\n DrawerFooter,\n DrawerTitle,\n DrawerDescription,\n};\n","'use client';\n\nimport * as React from 'react';\nimport * as ScrollAreaPrimitive from '@radix-ui/react-scroll-area';\nimport { cn } from '../../lib/utils';\n\nfunction ScrollArea({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof ScrollAreaPrimitive.Root>) {\n return (\n <ScrollAreaPrimitive.Root\n data-slot=\"scroll-area\"\n className={cn('relative overflow-hidden', className)}\n {...props}\n >\n <ScrollAreaPrimitive.Viewport className=\"h-full w-full rounded-[inherit]\">\n {children}\n </ScrollAreaPrimitive.Viewport>\n <ScrollBar />\n <ScrollAreaPrimitive.Corner />\n </ScrollAreaPrimitive.Root>\n );\n}\n\nfunction ScrollBar({\n className,\n orientation = 'vertical',\n ...props\n}: React.ComponentProps<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>) {\n return (\n <ScrollAreaPrimitive.ScrollAreaScrollbar\n data-slot=\"scroll-bar\"\n orientation={orientation}\n className={cn(\n 'flex touch-none select-none transition-colors',\n orientation === 'vertical' && 'h-full w-2.5 border-l border-l-transparent p-[1px]',\n orientation === 'horizontal' && 'h-2.5 flex-col border-t border-t-transparent p-[1px]',\n className,\n )}\n {...props}\n >\n <ScrollAreaPrimitive.ScrollAreaThumb className=\"relative flex-1 rounded-full bg-border\" />\n </ScrollAreaPrimitive.ScrollAreaScrollbar>\n );\n}\n\nexport { ScrollArea, ScrollBar };\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { cn, TooltipProvider, Tooltip, TooltipTrigger, TooltipContent, ScrollArea, Skeleton, useOrganifyApi, useOrganify, Avatar, AvatarImage, AvatarFallback, Drawer, DrawerContent, DrawerHeader, DrawerTitle, DrawerDescription, DrawerFooter, Badge, useOrganifyUser, useOrganifyWorkspace, useOrganifyGql } from './chunk-
|
|
1
|
+
import { cn, TooltipProvider, Tooltip, TooltipTrigger, TooltipContent, ScrollArea, Skeleton, useOrganifyApi, useOrganify, Avatar, AvatarImage, AvatarFallback, Drawer, DrawerContent, DrawerHeader, DrawerTitle, DrawerDescription, DrawerFooter, Badge, useOrganifyUser, useOrganifyWorkspace, useOrganifyGql } from './chunk-XXBUSG5Q.js';
|
|
2
2
|
import { OrgPlus, OrgSearch, OrgComment, OrgClose, OrgEdit, OrgTeam, OrgGlobe, OrgLock, OrgCheckCircle, OrgError, OrgWarning, OrgInfo, OrgChevronDown, OrgChevronRight, OrgDoor, OrgTrash, OrgCheck, OrgFolder, OrgChevronLeft } from './chunk-MZKEDV5W.js';
|
|
3
3
|
import * as React6 from 'react';
|
|
4
4
|
import React6__default, { useState, useEffect, useCallback } from 'react';
|
|
@@ -4708,5 +4708,5 @@ function useAiInline({ gatewayUrl, workspaceId, projectId }) {
|
|
|
4708
4708
|
}
|
|
4709
4709
|
|
|
4710
4710
|
export { AiChatSidebar, Alert, Button, ChatMessages, ChatSidebar, CommandBar, CreateRoomDialog, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, InlineAiButton, Input, Label, MOCK_PROJECTS, MOCK_USERS, MentionPopover, MessageBubble, MessageInput, OrgLoader, OrgLoaderInline, OrganifyChat, ResponsiveDialog, RoomManagementPanel, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, TypingIndicatorMock, UserAvatar, UserDisplayName, alertVariants, buttonVariants, generateAutoReplies, getMockMentionOptions, getRoomPermissions, inputVariants, invalidateUserCache, orgLoaderVariants, resolveUser, seedUserCache, typingIndicator, useAiInline, useChat, useResolvedUser };
|
|
4711
|
-
//# sourceMappingURL=chunk-
|
|
4712
|
-
//# sourceMappingURL=chunk-
|
|
4711
|
+
//# sourceMappingURL=chunk-ZZRLEONE.js.map
|
|
4712
|
+
//# sourceMappingURL=chunk-ZZRLEONE.js.map
|