18 Commits

Author SHA1 Message Date
Ruslan Bakiev
12af9979ab feat(crm): add deal create/update controls with status and payment 2026-02-27 09:44:15 +07:00
Ruslan Bakiev
bf7f4ae933 feat: broadcast pilot agent traces via WebSocket for live status on reconnect
Agent trace logs are now stored in-memory (pilotRunStore) and broadcast
through the existing /ws/crm-updates WebSocket channel. When a client
reconnects, it receives a pilot.catchup with all accumulated logs so the
user sees agent progress even after page reload. Three new WS event
types: pilot.trace, pilot.finished, pilot.catchup.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 08:45:32 +07:00
Ruslan Bakiev
7d647bef25 fix: disable context picker mode after selecting a scope
When a context scope is picked via the pipette, the picker mode now
turns off automatically since the selection is done and shows as a chip.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 08:18:45 +07:00
Ruslan Bakiev
6e3763a5fd fix: refetch contacts after hiding inbox, redirect to most recent chat
After hiding a contact inbox, the contacts list now refetches immediately
so the hidden contact disappears reactively. When the current contact is
removed from the list, the selection jumps to the most recently active
contact (by lastContactAt) instead of the first item in the current sort.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 07:56:10 +07:00
Ruslan Bakiev
292d587fe1 debug(calendar): add console.warn to GSAP zoom animation functions
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 07:32:33 +07:00
Ruslan Bakiev
cb685446a5 fix: show loading spinner when switching between contact threads
Clear old timeline items immediately on thread switch and display a centered
loader until the new conversation loads, instead of showing stale messages.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 21:45:01 +07:00
Ruslan Bakiev
3ff9120070 fix: export isCommCallPlaying from useCallAudio composable
Same issue as isCommCallPlayable — used in template but not exported/destructured.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 21:09:39 +07:00
Ruslan Bakiev
c07ef2026d fix: export isCommCallPlayable from useCallAudio composable
Function was used in CrmWorkspaceApp template but not exported/destructured,
causing TypeError at runtime.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 21:00:10 +07:00
Ruslan Bakiev
5492e0d05c feat: unread message tracking with blue dot indicator
Add ContactThreadRead model to track when users last viewed each contact thread.
Contacts with messages newer than the last read time show a blue dot in the sidebar.
Opening a thread automatically marks it as read via markThreadRead mutation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 20:25:32 +07:00
Ruslan Bakiev
643d8d02ba feat: granular WebSocket message.new events
- WebSocket now detects new ContactMessages and broadcasts
  message.new events with contactId, text, channel, direction
- Frontend handles message.new: refreshes timeline for open chat,
  refreshes contacts for sidebar preview update
- dashboard.changed still fires for non-message changes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 20:04:55 +07:00
Ruslan Bakiev
ac9c50b47d feat: remove CommunicationsQuery, load messages on-demand only
- Remove bulk CommunicationsQuery from useContacts (was loading ALL
  messages for ALL contacts on init)
- Rebuild commThreads from contacts + contactInboxes using the new
  lastMessageText field from Phase 1
- Per-contact messages now load on-demand via getClientTimeline
- Remove commItems from useWorkspaceRouting, use clientTimelineItems

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 20:02:58 +07:00
Ruslan Bakiev
c229bdee23 fix(calendar): restore GSAP fly-rect + fly-label animation in useCalendar composable
The refactoring in a4d8d81 moved calendar logic into useCalendar.ts but
used the old CSS-transform animation code instead of the GSAP-based
flying rect + flying label implementation. This restores:

- GSAP-based animateCalendarZoomIntoSource and animateCalendarFlipTransition
- Flying label that animates from card title → toolbar on zoom-in and back
- Clone-and-swap pattern with skeleton content in fly-rect (no text)
- Fly-rect/fly-label refs and setters now live in the composable
- isoWeekNumber() and weekNumber field on monthRows
- Sibling card titles and week numbers faded during zoom
- Removed old CSS-transform camera state and calendarSceneTransformStyle

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 15:50:35 +07:00
Ruslan Bakiev
195df8e16a fix: stop aggressive 2s chat polling, use WebSocket instead
- Add refetchChatMessages + refetchChatConversations to
  refetchAllCrmQueries so WebSocket dashboard.changed events
  cover pilot chat updates
- Reduce background polling from 2s to 30s (fallback only)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 15:41:58 +07:00
Ruslan Bakiev
19d001815c fix: add missing ClientTimelineItem import in useDocuments
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 15:33:22 +07:00
Ruslan Bakiev
d892d0c604 refactor: distribute types from crm-types.ts to owning composables
Each composable now owns its types and exports them. Other composables
import types from the owning composable. Deleted centralized crm-types.ts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 15:21:30 +07:00
Ruslan Bakiev
a4d8d81de9 refactor: decompose CrmWorkspaceApp.vue into 15 composables
Split the 6000+ line monolithic component into modular composables:
- crm-types.ts: shared types and utility functions
- useAuth, useContacts, useContactInboxes, useCalendar, useDeals,
  useDocuments, useFeed, useTimeline, usePilotChat, useCallAudio,
  usePins, useChangeReview, useCrmRealtime, useWorkspaceRouting
CrmWorkspaceApp.vue is now a thin orchestrator (~2500 lines) that
wires composables together with glue code, keeping template and
styles intact.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 15:05:01 +07:00
Ruslan Bakiev
c5d3a90413 refactor(voice): extract chat dictation into reusable component 2026-02-23 19:43:00 +07:00
Ruslan Bakiev
d4af315e2e chore(frontend): move nuxt ui source into app directory 2026-02-23 10:03:24 +07:00