Commit Graph

9 Commits

Author SHA1 Message Date
cf552d4b40 feat: chat — role on hover, role in direct header, @mention dropdown
- MessageBubble: role hidden by default, appears on hover of sender name (group/name CSS)
- Direct chat header: shows other user's role (from otherUserRole field added to backend)
- @mention: typing @ triggers filtered user dropdown, click inserts @Name into message
- Hint text updated: '@ — упомянуть'
- Backend: other_user_role added to rooms query

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 16:42:32 +03:00
e7ad9862ba feat: chat pagination — infinite scroll / load older messages
- Backend: cursor-based pagination via ?before=<ISO timestamp>
- Frontend: auto-load when scrolling to top (<60px), spinner + manual 'Загрузить ещё' button
- Poll merge: preserves older history when new messages arrive from polling
- hasMoreMsgs flag: shown only when exactly 50 msgs returned (more may exist)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 16:35:38 +03:00
abf1920e6f feat: chat — ⋮ room menu, typing indicator, online presence, read receipts
- RoomRow: ⋮ button (hover) for pin/unpin context menu
- MessageBubble: right-click context menu with emoji reactions + edit/delete
- Typing indicator: debounced setTyping, animated TypingDots, polling getTyping every 2s
- Online presence: heartbeat setPresence every 30s, green dot on avatars/header
- Read receipts: ✓/✓✓ for own messages in direct rooms via otherUserLastRead
- Migration 075: chat_presence + chat_typing tables
- Context menus clamped to viewport bounds

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 13:16:35 +03:00
a29f58282f feat: chat — edit/delete messages + emoji reactions
- Migration 074: edited_at, deleted_at columns + chat_reactions table
- Backend: PATCH edit (own only), DELETE soft-delete (own/admin), POST toggle reaction
  fetchMessage helper returns full message with aggregated reactions in one query
- API types: ChatReaction interface, editedAt/deletedAt/reactions in ChatMessage
- ChatWidget: hover toolbar (😊 react · ✏️ edit · 🗑️ delete), inline edit with
  save/cancel (Enter/Esc), reaction emoji picker (8 emojis), reaction pills below
  messages (click to toggle), '· изм.' label on edited messages, soft-deleted
  messages show 'Сообщение удалено' placeholder

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 12:31:17 +03:00
7ccf752429 feat: chat — photo attachments
- Migration 073: attachment_url column in chat_messages
- upload.ts: add 'chat' folder to ALLOWED_FOLDERS
- chat.ts: accept attachment_url in send message, return it in GET messages
- api.ts: attachmentUrl in ChatMessage type, uploadImage() with raw FormData fetch
- ChatWidget: paperclip button, file preview thumbnail with remove, image display
  inline in message bubbles (clickable, opens original), send enabled with image only

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 12:13:07 +03:00
d0dbf33701 fix: chat — VARCHAR(10) overflow for notifications type, skeleton loading
- Migration 072: widen type column to VARCHAR(20), add partial unique index for general rooms
- Backend: replace brittle ON CONFLICT with explicit SELECT-then-INSERT ensureRoom helper
- Frontend: show room skeletons (Общий чат + Уведомления) during load instead of spinner,
  hide '0 чатов' subtitle when list is empty

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 12:03:35 +03:00
3c4c40da44 feat: chat — search, notifications room, settings
- Migration 071: nullable sender_id, is_system flag, notifications room type
- Backend: notifications room auto-created per hotel, search messages endpoint,
  notify endpoint (manager/admin posts system messages), read-only enforcement
- API: ChatSearchResult type, chat.search(), chat.notify(), updated ChatMessage type
- Frontend ChatWidget: search view (people + messages tabs), settings panel
  (notifications visibility toggle, sound toggle), notifications room (bell icon,
  read-only banner, amber styling for system messages), new-chat button

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 11:25:40 +03:00
5128957d7c fix: loyalty tier crash, chat duplicate rooms, sidebar defaults
- LoyaltyPage: levelBadge() now falls back to bronze for unknown tiers
  (DB had loyalty_tier='standard' from old seed data)
- migration 040: deduplicate general chat rooms + add unique index,
  normalize loyalty_tier to bronze for non-standard values
- chat.ts: ON CONFLICT clause now targets the new partial unique index
- Sidebar: DEFAULT_GROUPS only opens 'basics' by default; bump
  localStorage key to sidebarGroups_v2 to clear stale stored state

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-26 10:58:47 +03:00
113971f854 feat: wire up loyalty + chat — register routes, API types, connect LoyaltyPage, add ChatWidget to layout 2026-03-26 10:15:29 +03:00