@anymux/ui-kit 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/dist/{calendar-DSlrbHoj.js → calendar-DQKfYSQS.js} +48 -45
  2. package/dist/calendar-DQKfYSQS.js.map +1 -0
  3. package/dist/calendar.d.ts +1 -1
  4. package/dist/calendar.js +1 -1
  5. package/dist/{contacts-DQXTZzHc.js → contacts-By9Wg3kn.js} +35 -33
  6. package/dist/contacts-By9Wg3kn.js.map +1 -0
  7. package/dist/contacts.d.ts +1 -1
  8. package/dist/contacts.js +1 -1
  9. package/dist/{file-browser-m5atC3kF.js → file-browser-CkhNwADU.js} +61 -133
  10. package/dist/file-browser-CkhNwADU.js.map +1 -0
  11. package/dist/file-browser.d.ts +6 -6
  12. package/dist/file-browser.js +4 -4
  13. package/dist/{git-B55e6LL-.js → git-m4lboTfx.js} +29 -29
  14. package/dist/git-m4lboTfx.js.map +1 -0
  15. package/dist/git.js +1 -1
  16. package/dist/{iconMap-V4B8P-Uh.js → iconMap-DDpe35ek.js} +5 -5
  17. package/dist/iconMap-DDpe35ek.js.map +1 -0
  18. package/dist/icons.js +1 -1
  19. package/dist/{index-Bryv_GCG.d.ts → index-BP4IYXiF.d.ts} +46 -53
  20. package/dist/index-BP4IYXiF.d.ts.map +1 -0
  21. package/dist/{index-kHr9udZD.d.ts → index-BkIh8oov.d.ts} +17 -17
  22. package/dist/{index-kHr9udZD.d.ts.map → index-BkIh8oov.d.ts.map} +1 -1
  23. package/dist/{index-DSu19mq0.d.ts → index-D3Ob3aXg.d.ts} +9 -9
  24. package/dist/{index-DSu19mq0.d.ts.map → index-D3Ob3aXg.d.ts.map} +1 -1
  25. package/dist/{index-Ml_SgiKa.d.ts → index-DGoLQBX6.d.ts} +18 -42
  26. package/dist/index-DGoLQBX6.d.ts.map +1 -0
  27. package/dist/index-DnJaZr08.d.ts +67 -0
  28. package/dist/index-DnJaZr08.d.ts.map +1 -0
  29. package/dist/{index-DmsyeHFr.d.ts → index-Pty-N7-g.d.ts} +5 -5
  30. package/dist/{index-DmsyeHFr.d.ts.map → index-Pty-N7-g.d.ts.map} +1 -1
  31. package/dist/index.d.ts +7 -7
  32. package/dist/index.js +10 -10
  33. package/dist/layout-BYsc16hD.js +183 -0
  34. package/dist/layout-BYsc16hD.js.map +1 -0
  35. package/dist/layout.d.ts +2 -2
  36. package/dist/layout.js +2 -2
  37. package/dist/{list-CxfT6hix.js → list-DAq-b6RR.js} +49 -63
  38. package/dist/list-DAq-b6RR.js.map +1 -0
  39. package/dist/list.d.ts +2 -2
  40. package/dist/list.js +4 -3
  41. package/dist/{media-DZ292aKK.js → media-DuczOGsk.js} +32 -31
  42. package/dist/media-DuczOGsk.js.map +1 -0
  43. package/dist/media.js +1 -1
  44. package/dist/{tree-Dd9Z0Aso.js → tree-B9VQcKBp.js} +2 -2
  45. package/dist/{tree-Dd9Z0Aso.js.map → tree-B9VQcKBp.js.map} +1 -1
  46. package/dist/tree.d.ts +1 -1
  47. package/dist/tree.js +2 -2
  48. package/package.json +2 -2
  49. package/src/calendar/AgendaView.tsx +2 -2
  50. package/src/calendar/CalendarBrowser.tsx +11 -11
  51. package/src/calendar/CalendarSidebar.tsx +10 -10
  52. package/src/calendar/DayView.tsx +5 -5
  53. package/src/calendar/EventCard.tsx +3 -3
  54. package/src/calendar/MonthView.tsx +6 -6
  55. package/src/calendar/WeekView.tsx +10 -10
  56. package/src/contacts/ContactBrowser.tsx +8 -8
  57. package/src/contacts/ContactCard.tsx +4 -4
  58. package/src/contacts/ContactDetail.tsx +10 -10
  59. package/src/contacts/ContactGroupSidebar.tsx +6 -6
  60. package/src/contacts/ContactList.tsx +3 -3
  61. package/src/file-browser/components/FileBrowser.tsx +3 -2
  62. package/src/file-browser/components/FileBrowserContent.tsx +1 -1
  63. package/src/file-browser/examples/BasicUsage.tsx +2 -2
  64. package/src/file-browser/index.ts +1 -1
  65. package/src/file-browser/providers/FileSystemProvider.ts +1 -1
  66. package/src/git/BranchList.tsx +12 -12
  67. package/src/git/CommitList.tsx +11 -11
  68. package/src/git/DiffViewer.tsx +11 -11
  69. package/src/icons/iconMap.ts +4 -4
  70. package/src/layout/index.ts +6 -2
  71. package/src/layout/models/ResponsiveLayoutModel.ts +116 -0
  72. package/src/list/components/ListItem.tsx +1 -1
  73. package/src/list/index.ts +1 -1
  74. package/src/media/AlbumSidebar.tsx +4 -4
  75. package/src/media/MediaBrowser.tsx +11 -11
  76. package/src/media/MediaGrid.tsx +3 -3
  77. package/src/media/MediaList.tsx +6 -6
  78. package/src/media/MediaPreview.tsx +2 -2
  79. package/src/media/MediaTimeline.tsx +3 -3
  80. package/src/{file-browser/components/shared → shared}/ErrorBoundary.tsx +3 -3
  81. package/dist/calendar-DSlrbHoj.js.map +0 -1
  82. package/dist/contacts-DQXTZzHc.js.map +0 -1
  83. package/dist/file-browser-m5atC3kF.js.map +0 -1
  84. package/dist/git-B55e6LL-.js.map +0 -1
  85. package/dist/iconMap-V4B8P-Uh.js.map +0 -1
  86. package/dist/index-Bryv_GCG.d.ts.map +0 -1
  87. package/dist/index-DzfY1Tok.d.ts +0 -32
  88. package/dist/index-DzfY1Tok.d.ts.map +0 -1
  89. package/dist/index-Ml_SgiKa.d.ts.map +0 -1
  90. package/dist/layout-Ca_4r8ka.js +0 -89
  91. package/dist/layout-Ca_4r8ka.js.map +0 -1
  92. package/dist/list-CxfT6hix.js.map +0 -1
  93. package/dist/media-DZ292aKK.js.map +0 -1
  94. package/src/list/components/shared/ErrorBoundary.tsx +0 -123
@@ -1 +0,0 @@
1
- {"version":3,"file":"calendar-DSlrbHoj.js","names":["provider: ICalendarProvider","err: any","event: Omit<CalendarEvent, 'id' | 'createdAt' | 'updatedAt'>","id: string","event: CalendarEvent | null","date: Date","mode: CalendarViewMode","d: Date","weeks: (number | null)[][]","week: (number | null)[]","day: number","d: Date","cells: (number | null)[]","day: number","VIEW_LABELS: Record<CalendarViewMode, string>","CALENDARS: CalendarInfo[]","events: CalendarEvent[]","id: string","item: Omit<CalendarEvent, 'id' | 'createdAt' | 'updatedAt'>","created: CalendarEvent","updates: Partial<CalendarEvent>","query: string","start: Date","end: Date","calendarId: string"],"sources":["../src/calendar/CalendarModel.ts","../src/calendar/EventCard.tsx","../src/calendar/MonthView.tsx","../src/calendar/WeekView.tsx","../src/calendar/DayView.tsx","../src/calendar/AgendaView.tsx","../src/calendar/CalendarSidebar.tsx","../src/calendar/CalendarBrowser.tsx","../src/calendar/MockCalendarProvider.ts"],"sourcesContent":["import { makeAutoObservable, flow } from 'mobx';\nimport type { ICalendarProvider, CalendarEvent, CalendarInfo } from './types';\n\nexport type CalendarViewMode = 'month' | 'week' | 'day' | 'agenda';\n\nexport class CalendarModel {\n events: CalendarEvent[] = [];\n calendars: CalendarInfo[] = [];\n currentDate: Date = new Date();\n viewMode: CalendarViewMode = 'month';\n selectedEvent: CalendarEvent | null = null;\n loading = false;\n error: string | null = null;\n\n constructor(private provider: ICalendarProvider) {\n makeAutoObservable(this);\n }\n\n get visibleDateRange(): { start: Date; end: Date } {\n const d = this.currentDate;\n switch (this.viewMode) {\n case 'month': {\n const start = new Date(d.getFullYear(), d.getMonth(), 1);\n start.setDate(start.getDate() - start.getDay());\n const end = new Date(d.getFullYear(), d.getMonth() + 1, 0);\n end.setDate(end.getDate() + (6 - end.getDay()));\n return { start, end };\n }\n case 'week': {\n const start = new Date(d);\n start.setDate(d.getDate() - d.getDay());\n start.setHours(0, 0, 0, 0);\n const end = new Date(start);\n end.setDate(start.getDate() + 6);\n end.setHours(23, 59, 59, 999);\n return { start, end };\n }\n case 'day': {\n const start = new Date(d);\n start.setHours(0, 0, 0, 0);\n const end = new Date(d);\n end.setHours(23, 59, 59, 999);\n return { start, end };\n }\n case 'agenda': {\n const start = new Date(d);\n start.setHours(0, 0, 0, 0);\n const end = new Date(d);\n end.setDate(end.getDate() + 30);\n return { start, end };\n }\n }\n }\n\n get eventsForCurrentView(): CalendarEvent[] {\n const { start, end } = this.visibleDateRange;\n return this.events.filter(e =>\n e.endDate >= start && e.startDate <= end\n );\n }\n\n get eventsByDay(): Map<string, CalendarEvent[]> {\n const map = new Map<string, CalendarEvent[]>();\n for (const event of this.eventsForCurrentView) {\n const key = event.startDate.toISOString().slice(0, 10);\n const list = map.get(key) ?? [];\n list.push(event);\n map.set(key, list);\n }\n return map;\n }\n\n loadEvents = flow(function* (this: CalendarModel) {\n this.loading = true;\n this.error = null;\n try {\n const { start, end } = this.visibleDateRange;\n const [events, calendars] = yield Promise.all([\n this.provider.getEventsByRange(start, end),\n this.provider.getCalendars()\n ]);\n this.events = events;\n this.calendars = calendars;\n } catch (err: any) {\n this.error = err?.message || 'Failed to load calendar events';\n } finally {\n this.loading = false;\n }\n });\n\n selectEvent(event: CalendarEvent | null) {\n this.selectedEvent = event;\n }\n\n setDate(date: Date) {\n this.currentDate = date;\n this.loadEvents();\n }\n\n setViewMode(mode: CalendarViewMode) {\n this.viewMode = mode;\n this.loadEvents();\n }\n\n navigateForward() {\n const d = new Date(this.currentDate);\n switch (this.viewMode) {\n case 'month': d.setMonth(d.getMonth() + 1); break;\n case 'week': d.setDate(d.getDate() + 7); break;\n case 'day': d.setDate(d.getDate() + 1); break;\n case 'agenda': d.setDate(d.getDate() + 30); break;\n }\n this.setDate(d);\n }\n\n navigateBack() {\n const d = new Date(this.currentDate);\n switch (this.viewMode) {\n case 'month': d.setMonth(d.getMonth() - 1); break;\n case 'week': d.setDate(d.getDate() - 7); break;\n case 'day': d.setDate(d.getDate() - 1); break;\n case 'agenda': d.setDate(d.getDate() - 30); break;\n }\n this.setDate(d);\n }\n\n today() {\n this.setDate(new Date());\n }\n\n createEvent = flow(function* (this: CalendarModel, event: Omit<CalendarEvent, 'id' | 'createdAt' | 'updatedAt'>) {\n const created = yield this.provider.createItem(event);\n this.events.push(created);\n return created;\n });\n\n deleteEvent = flow(function* (this: CalendarModel, id: string) {\n yield this.provider.deleteItem(id);\n this.events = this.events.filter(e => e.id !== id);\n if (this.selectedEvent?.id === id) this.selectedEvent = null;\n });\n}\n","import React from 'react';\nimport { Clock, MapPin } from 'lucide-react';\nimport type { CalendarEvent } from './types';\n\nexport interface EventCardProps {\n event: CalendarEvent;\n compact?: boolean;\n onClick?: () => void;\n className?: string;\n}\n\nconst formatTime = (d: Date) => d.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });\n\nexport const EventCard = ({ event, compact = false, onClick, className = '' }: EventCardProps) => {\n const color = event.color ?? '#3b82f6';\n\n if (compact) {\n return (\n <button\n onClick={onClick}\n className={`text-left text-xs px-1.5 py-0.5 rounded truncate w-full hover:opacity-80 transition-opacity ${className}`}\n style={{ backgroundColor: `${color}20`, color, borderLeft: `2px solid ${color}` }}\n title={event.title}\n >\n {event.title}\n </button>\n );\n }\n\n return (\n <button\n onClick={onClick}\n className={`text-left w-full p-3 rounded-lg border border-gray-200 hover:shadow-sm transition-shadow ${className}`}\n style={{ borderLeftWidth: '3px', borderLeftColor: color }}\n >\n <p className=\"text-sm font-medium text-gray-900 truncate\" title={event.title}>{event.title}</p>\n <div className=\"mt-1 flex items-center gap-3 text-xs text-gray-500\">\n <span className=\"flex items-center gap-1\">\n <Clock size={12} />\n {event.allDay ? 'All day' : `${formatTime(event.startDate)} - ${formatTime(event.endDate)}`}\n </span>\n {event.location && (\n <span className=\"flex items-center gap-1\">\n <MapPin size={12} />\n {event.location}\n </span>\n )}\n </div>\n </button>\n );\n};\n","import React from 'react';\nimport { observer } from 'mobx-react-lite';\nimport type { CalendarModel } from './CalendarModel';\nimport { EventCard } from './EventCard';\n\nexport interface MonthViewProps {\n model: CalendarModel;\n className?: string;\n}\n\nconst DAYS = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];\n\nexport const MonthView = observer<MonthViewProps>(({ model, className = '' }) => {\n const d = model.currentDate;\n const year = d.getFullYear();\n const month = d.getMonth();\n const today = new Date();\n\n const firstDay = new Date(year, month, 1).getDay();\n const daysInMonth = new Date(year, month + 1, 0).getDate();\n\n const weeks: (number | null)[][] = [];\n let week: (number | null)[] = [];\n for (let i = 0; i < firstDay; i++) week.push(null);\n for (let day = 1; day <= daysInMonth; day++) {\n week.push(day);\n if (week.length === 7) { weeks.push(week); week = []; }\n }\n if (week.length > 0) {\n while (week.length < 7) week.push(null);\n weeks.push(week);\n }\n\n const isToday = (day: number) =>\n day === today.getDate() && month === today.getMonth() && year === today.getFullYear();\n\n return (\n <div className={`flex flex-col h-full ${className}`}>\n <div className=\"grid grid-cols-7 border-b border-gray-200\">\n {DAYS.map(day => (\n <div key={day} className=\"px-2 py-2 text-xs font-medium text-gray-500 text-center\">{day.slice(0, 3)}</div>\n ))}\n </div>\n <div className=\"flex-1 grid grid-rows-[repeat(auto-fill,1fr)]\">\n {weeks.map((week, wi) => (\n <div key={wi} className=\"grid grid-cols-7 border-b border-gray-100 min-h-[80px]\">\n {week.map((day, di) => {\n const dateKey = day ? `${year}-${String(month + 1).padStart(2, '0')}-${String(day).padStart(2, '0')}` : null;\n const events = dateKey ? (model.eventsByDay.get(dateKey) ?? []) : [];\n return (\n <div key={di} className={`border-r border-gray-100 p-1 ${day === null ? 'bg-gray-50' : ''}`}>\n {day !== null && (\n <>\n <div className={`text-xs mb-0.5 w-6 h-6 flex items-center justify-center rounded-full ${\n isToday(day) ? 'bg-blue-500 text-white font-bold' : 'text-gray-700'\n }`}>\n {day}\n </div>\n <div className=\"space-y-0.5\">\n {events.slice(0, 3).map(ev => (\n <EventCard key={ev.id} event={ev} compact onClick={() => model.selectEvent(ev)} />\n ))}\n {events.length > 3 && (\n <p className=\"text-[10px] text-gray-400 pl-1\">+{events.length - 3} more</p>\n )}\n </div>\n </>\n )}\n </div>\n );\n })}\n </div>\n ))}\n </div>\n </div>\n );\n});\n","import React from 'react';\nimport { observer } from 'mobx-react-lite';\nimport type { CalendarModel } from './CalendarModel';\n\nexport interface WeekViewProps {\n model: CalendarModel;\n className?: string;\n}\n\nconst HOURS = Array.from({ length: 24 }, (_, i) => i);\n\nexport const WeekView = observer<WeekViewProps>(({ model, className = '' }) => {\n const { start } = model.visibleDateRange;\n const days = Array.from({ length: 7 }, (_, i) => {\n const d = new Date(start);\n d.setDate(start.getDate() + i);\n return d;\n });\n\n const now = new Date();\n const isToday = (d: Date) => d.toDateString() === now.toDateString();\n const currentHour = now.getHours();\n const currentMinute = now.getMinutes();\n\n // Collect all-day events for the visible week\n const allDayEventsByDay = days.map(d => {\n const dateKey = d.toISOString().slice(0, 10);\n return (model.eventsByDay.get(dateKey) ?? []).filter(e => e.allDay);\n });\n const hasAllDay = allDayEventsByDay.some(events => events.length > 0);\n\n return (\n <div className={`flex flex-col h-full overflow-auto ${className}`}>\n {/* Day headers */}\n <div className=\"sticky top-0 bg-white z-10 border-b border-gray-200\">\n <div className=\"grid\" style={{ gridTemplateColumns: '60px repeat(7, 1fr)' }}>\n <div />\n {days.map((d, i) => (\n <div key={i} className={`text-center py-2 border-l border-gray-100 ${isToday(d) ? 'bg-blue-50' : ''}`}>\n <div className=\"text-xs text-gray-500\">{d.toLocaleDateString(undefined, { weekday: 'short' })}</div>\n <div className={`text-lg font-medium ${isToday(d) ? 'text-blue-600' : 'text-gray-900'}`}>{d.getDate()}</div>\n </div>\n ))}\n </div>\n\n {/* All-day events row */}\n {hasAllDay && (\n <div className=\"grid border-t border-gray-100\" style={{ gridTemplateColumns: '60px repeat(7, 1fr)' }}>\n <div className=\"text-[10px] text-gray-400 text-right pr-2 py-1\">all-day</div>\n {allDayEventsByDay.map((events, i) => (\n <div key={i} className=\"border-l border-gray-100 px-0.5 py-0.5 space-y-0.5\">\n {events.map(ev => (\n <button\n key={ev.id}\n onClick={() => model.selectEvent(ev)}\n className=\"w-full text-left text-[10px] px-1 py-0.5 rounded truncate\"\n style={{\n backgroundColor: `${ev.color ?? '#3b82f6'}20`,\n color: ev.color ?? '#3b82f6',\n borderLeft: `2px solid ${ev.color ?? '#3b82f6'}`,\n }}\n title={ev.title}\n >\n {ev.title}\n </button>\n ))}\n </div>\n ))}\n </div>\n )}\n </div>\n\n {/* Time grid */}\n <div className=\"flex-1 relative\">\n {HOURS.map(hour => (\n <div key={hour} className=\"grid border-b border-gray-50\" style={{ gridTemplateColumns: '60px repeat(7, 1fr)', height: '48px' }}>\n <div className=\"text-[10px] text-gray-400 text-right pr-2 -mt-2\">\n {hour === 0 ? '' : `${hour % 12 || 12} ${hour < 12 ? 'AM' : 'PM'}`}\n </div>\n {days.map((d, i) => {\n const dateKey = d.toISOString().slice(0, 10);\n const events = (model.eventsByDay.get(dateKey) ?? []).filter(e =>\n !e.allDay && e.startDate.getHours() === hour\n );\n const showTimeLine = isToday(d) && hour === currentHour;\n return (\n <div key={i} className=\"border-l border-gray-100 relative\">\n {/* Current time indicator */}\n {showTimeLine && (\n <div\n className=\"absolute left-0 right-0 z-10 pointer-events-none\"\n style={{ top: `${(currentMinute / 60) * 48}px` }}\n >\n <div className=\"w-2 h-2 bg-red-500 rounded-full absolute -left-1 -top-1\" />\n <div className=\"h-px bg-red-500 w-full\" />\n </div>\n )}\n {events.map((ev, ei) => {\n const durationHours = Math.max(0.5, (ev.endDate.getTime() - ev.startDate.getTime()) / 3600000);\n const topOffset = (ev.startDate.getMinutes() / 60) * 48;\n return (\n <button\n key={ev.id}\n onClick={() => model.selectEvent(ev)}\n className=\"absolute text-xs px-1 py-0.5 rounded truncate z-[1]\"\n title={ev.title}\n style={{\n backgroundColor: `${ev.color ?? '#3b82f6'}20`,\n color: ev.color ?? '#3b82f6',\n borderLeft: `2px solid ${ev.color ?? '#3b82f6'}`,\n height: `${durationHours * 48}px`,\n top: `${topOffset}px`,\n left: `${ei * 4 + 2}px`,\n right: '2px',\n }}\n >\n {ev.title}\n </button>\n );\n })}\n </div>\n );\n })}\n </div>\n ))}\n </div>\n </div>\n );\n});\n","import React from 'react';\nimport { observer } from 'mobx-react-lite';\nimport type { CalendarModel } from './CalendarModel';\n\nexport interface DayViewProps {\n model: CalendarModel;\n className?: string;\n}\n\nconst HOURS = Array.from({ length: 24 }, (_, i) => i);\n\nexport const DayView = observer<DayViewProps>(({ model, className = '' }) => {\n const d = model.currentDate;\n const dateKey = d.toISOString().slice(0, 10);\n const dayEvents = model.eventsByDay.get(dateKey) ?? [];\n const allDayEvents = dayEvents.filter(e => e.allDay);\n const timedEvents = dayEvents.filter(e => !e.allDay);\n\n return (\n <div className={`flex flex-col h-full overflow-auto ${className}`}>\n {/* Header */}\n <div className=\"border-b border-gray-200 px-4 py-2 sticky top-0 bg-white z-10\">\n <h2 className=\"text-lg font-medium text-gray-900\">\n {d.toLocaleDateString(undefined, { weekday: 'long', month: 'long', day: 'numeric' })}\n </h2>\n {allDayEvents.length > 0 && (\n <div className=\"flex gap-1 mt-1\">\n {allDayEvents.map(ev => (\n <button\n key={ev.id}\n onClick={() => model.selectEvent(ev)}\n className=\"text-xs px-2 py-0.5 rounded\"\n style={{ backgroundColor: `${ev.color ?? '#3b82f6'}20`, color: ev.color ?? '#3b82f6' }}\n >\n {ev.title}\n </button>\n ))}\n </div>\n )}\n </div>\n\n {/* Time slots */}\n <div className=\"flex-1\">\n {HOURS.map(hour => {\n const hourEvents = timedEvents.filter(e => e.startDate.getHours() === hour);\n return (\n <div key={hour} className=\"grid grid-cols-[60px_1fr] border-b border-gray-50 min-h-[48px]\">\n <div className=\"text-[10px] text-gray-400 text-right pr-2 -mt-2\">\n {hour === 0 ? '' : `${hour % 12 || 12} ${hour < 12 ? 'AM' : 'PM'}`}\n </div>\n <div className=\"border-l border-gray-100 relative pl-1\">\n {hourEvents.map(ev => (\n <button\n key={ev.id}\n onClick={() => model.selectEvent(ev)}\n className=\"w-full text-left text-xs p-1.5 rounded mb-0.5\"\n style={{\n backgroundColor: `${ev.color ?? '#3b82f6'}15`,\n color: ev.color ?? '#3b82f6',\n borderLeft: `2px solid ${ev.color ?? '#3b82f6'}`\n }}\n >\n <span className=\"font-medium\">{ev.title}</span>\n <span className=\"ml-2 opacity-70\">\n {ev.startDate.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}\n </span>\n </button>\n ))}\n </div>\n </div>\n );\n })}\n </div>\n </div>\n );\n});\n","import React from 'react';\nimport { observer } from 'mobx-react-lite';\nimport type { CalendarModel } from './CalendarModel';\nimport { EventCard } from './EventCard';\n\nexport interface AgendaViewProps {\n model: CalendarModel;\n className?: string;\n}\n\nexport const AgendaView = observer<AgendaViewProps>(({ model, className = '' }) => {\n const sortedEntries = Array.from(model.eventsByDay.entries())\n .sort(([a], [b]) => a.localeCompare(b));\n\n return (\n <div className={`overflow-y-auto p-4 space-y-4 ${className}`}>\n {sortedEntries.length === 0 && (\n <div className=\"flex items-center justify-center h-32 text-gray-400 text-sm\">No upcoming events</div>\n )}\n {sortedEntries.map(([dateKey, events]) => {\n const date = new Date(dateKey + 'T00:00:00');\n return (\n <div key={dateKey}>\n <h3 className=\"text-sm font-semibold text-gray-700 mb-2 sticky top-0 bg-white/90 backdrop-blur-sm py-1\">\n {date.toLocaleDateString(undefined, { weekday: 'long', month: 'long', day: 'numeric' })}\n </h3>\n <div className=\"space-y-1.5\">\n {events.map(ev => (\n <EventCard key={ev.id} event={ev} onClick={() => model.selectEvent(ev)} />\n ))}\n </div>\n </div>\n );\n })}\n </div>\n );\n});\n","import React from 'react';\nimport { observer } from 'mobx-react-lite';\nimport { ChevronLeft, ChevronRight } from 'lucide-react';\nimport type { CalendarModel } from './CalendarModel';\n\nexport interface CalendarSidebarProps {\n model: CalendarModel;\n className?: string;\n}\n\nconst DAYS = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'];\n\nexport const CalendarSidebar = observer<CalendarSidebarProps>(({ model, className = '' }) => {\n const d = model.currentDate;\n const year = d.getFullYear();\n const month = d.getMonth();\n\n const firstDay = new Date(year, month, 1).getDay();\n const daysInMonth = new Date(year, month + 1, 0).getDate();\n const today = new Date();\n\n const cells: (number | null)[] = [];\n for (let i = 0; i < firstDay; i++) cells.push(null);\n for (let i = 1; i <= daysInMonth; i++) cells.push(i);\n\n const isToday = (day: number) =>\n day === today.getDate() && month === today.getMonth() && year === today.getFullYear();\n\n const isSelected = (day: number) =>\n day === d.getDate();\n\n return (\n <div className={`w-56 border-r border-gray-200 bg-gray-50 p-3 ${className}`}>\n {/* Mini month */}\n <div className=\"mb-4\">\n <div className=\"flex items-center justify-between mb-2\">\n <button onClick={() => model.navigateBack()} className=\"p-1 hover:bg-gray-200 rounded\">\n <ChevronLeft size={14} />\n </button>\n <span className=\"text-sm font-medium\">\n {d.toLocaleDateString(undefined, { month: 'long', year: 'numeric' })}\n </span>\n <button onClick={() => model.navigateForward()} className=\"p-1 hover:bg-gray-200 rounded\">\n <ChevronRight size={14} />\n </button>\n </div>\n <div className=\"grid grid-cols-7 gap-0.5 text-center\">\n {DAYS.map(day => (\n <div key={day} className=\"text-[10px] text-gray-400 font-medium py-0.5\">{day}</div>\n ))}\n {cells.map((day, i) => (\n <button\n key={i}\n disabled={day === null}\n onClick={() => day && model.setDate(new Date(year, month, day))}\n className={`text-xs py-0.5 rounded ${\n day === null ? '' :\n isSelected(day) ? 'bg-blue-500 text-white' :\n isToday(day) ? 'bg-blue-100 text-blue-700 font-bold' :\n 'text-gray-700 hover:bg-gray-200'\n }`}\n >\n {day}\n </button>\n ))}\n </div>\n </div>\n\n {/* Calendar list */}\n <div>\n <h3 className=\"text-xs font-semibold text-gray-500 uppercase tracking-wider mb-2\">Calendars</h3>\n {model.calendars.map(cal => (\n <div key={cal.id} className=\"flex items-center gap-2 px-2 py-1.5 text-sm text-gray-700\">\n <div className=\"w-3 h-3 rounded-full\" style={{ backgroundColor: cal.color }} />\n <span className=\"truncate\" title={cal.name}>{cal.name}</span>\n </div>\n ))}\n </div>\n </div>\n );\n});\n","import React, { useEffect } from 'react';\nimport { observer } from 'mobx-react-lite';\nimport { ChevronLeft, ChevronRight, Loader2 } from 'lucide-react';\nimport { BrowserError } from '@anymux/ui/components/browser-error';\nimport type { CalendarModel, CalendarViewMode } from './CalendarModel';\nimport { MonthView } from './MonthView';\nimport { WeekView } from './WeekView';\nimport { DayView } from './DayView';\nimport { AgendaView } from './AgendaView';\nimport { CalendarSidebar } from './CalendarSidebar';\n\nexport interface CalendarBrowserProps {\n model: CalendarModel;\n className?: string;\n showSidebar?: boolean;\n}\n\nconst VIEW_LABELS: Record<CalendarViewMode, string> = {\n month: 'Month',\n week: 'Week',\n day: 'Day',\n agenda: 'Agenda',\n};\n\nexport const CalendarBrowser = observer<CalendarBrowserProps>(({ model, className = '', showSidebar = true }) => {\n useEffect(() => { model.loadEvents(); }, [model]);\n\n return (\n <div className={`flex h-full bg-white rounded-xl border border-gray-200 overflow-hidden ${className}`}>\n {showSidebar && <CalendarSidebar model={model} />}\n\n <div className=\"flex-1 flex flex-col min-w-0\">\n {/* Toolbar */}\n <div className=\"flex items-center gap-2 px-4 py-2 border-b border-gray-200\">\n <button onClick={() => model.today()} className=\"text-sm px-3 py-1.5 border border-gray-200 rounded-lg hover:bg-gray-50\">\n Today\n </button>\n <button onClick={() => model.navigateBack()} className=\"p-1.5 hover:bg-gray-100 rounded-lg\">\n <ChevronLeft size={16} />\n </button>\n <button onClick={() => model.navigateForward()} className=\"p-1.5 hover:bg-gray-100 rounded-lg\">\n <ChevronRight size={16} />\n </button>\n <h2 className=\"text-sm font-medium text-gray-900 ml-2\">\n {model.currentDate.toLocaleDateString(undefined, {\n month: 'long',\n year: 'numeric',\n ...(model.viewMode === 'day' ? { day: 'numeric', weekday: 'long' } : {})\n })}\n </h2>\n <div className=\"ml-auto flex items-center border border-gray-200 rounded-lg overflow-hidden\">\n {(Object.keys(VIEW_LABELS) as CalendarViewMode[]).map(mode => (\n <button\n key={mode}\n onClick={() => model.setViewMode(mode)}\n className={`px-3 py-1.5 text-xs font-medium ${\n model.viewMode === mode ? 'bg-blue-50 text-blue-600' : 'text-gray-500 hover:bg-gray-50'\n }`}\n >\n {VIEW_LABELS[mode]}\n </button>\n ))}\n </div>\n </div>\n\n {/* Content */}\n <div className=\"flex-1 overflow-hidden\">\n {model.loading ? (\n <div className=\"flex items-center justify-center h-64\">\n <Loader2 size={24} className=\"animate-spin text-gray-400\" />\n </div>\n ) : model.error ? (\n <BrowserError\n error={model.error}\n context=\"Calendar\"\n onRetry={() => model.loadEvents()}\n />\n ) : (\n <>\n {model.viewMode === 'month' && <MonthView model={model} />}\n {model.viewMode === 'week' && <WeekView model={model} />}\n {model.viewMode === 'day' && <DayView model={model} />}\n {model.viewMode === 'agenda' && <AgendaView model={model} />}\n </>\n )}\n </div>\n </div>\n </div>\n );\n});\n","import type { ICalendarProvider, CalendarEvent, CalendarInfo } from './types';\n\nconst CALENDARS: CalendarInfo[] = [\n { id: 'personal', name: 'Personal', color: '#3b82f6' },\n { id: 'work', name: 'Work', color: '#10b981' },\n { id: 'family', name: 'Family', color: '#f59e0b' },\n];\n\nconst EVENT_TITLES = [\n 'Team standup', 'Lunch with Sarah', 'Design review', 'Gym session',\n 'Doctor appointment', 'Code review', 'Sprint planning', 'Movie night',\n 'Grocery shopping', 'Piano lesson', 'Board meeting', 'Yoga class',\n 'Project deadline', 'Coffee with Alex', 'Dentist', 'Book club',\n];\n\nconst LOCATIONS = ['Office', 'Zoom', 'Conference Room A', 'Downtown Cafe', 'Home', undefined];\n\nfunction generateEvents(): CalendarEvent[] {\n const events: CalendarEvent[] = [];\n const now = new Date();\n const baseDate = new Date(now.getFullYear(), now.getMonth(), 1);\n\n for (let i = 0; i < 40; i++) {\n const day = Math.floor(Math.random() * 35) - 5;\n const hour = 8 + Math.floor(Math.random() * 10);\n const duration = 1 + Math.floor(Math.random() * 3);\n const allDay = i % 8 === 0;\n const calendar = CALENDARS[i % CALENDARS.length];\n\n const startDate = new Date(baseDate);\n startDate.setDate(startDate.getDate() + day);\n startDate.setHours(hour, 0, 0, 0);\n\n const endDate = new Date(startDate);\n if (allDay) {\n endDate.setHours(23, 59, 59, 999);\n } else {\n endDate.setHours(hour + duration);\n }\n\n events.push({\n id: `event-${i}`,\n type: 'calendar-event',\n title: EVENT_TITLES[i % EVENT_TITLES.length],\n startDate,\n endDate,\n allDay,\n location: LOCATIONS[i % LOCATIONS.length],\n attendees: i % 3 === 0 ? ['alice@example.com', 'bob@example.com'] : undefined,\n color: calendar.color,\n calendarId: calendar.id,\n createdAt: now,\n updatedAt: now,\n });\n }\n return events;\n}\n\nexport class MockCalendarProvider implements ICalendarProvider {\n private events = generateEvents();\n\n async listItems() { return this.events; }\n\n async getItem(id: string) { return this.events.find(e => e.id === id) ?? null; }\n\n async createItem(item: Omit<CalendarEvent, 'id' | 'createdAt' | 'updatedAt'>) {\n const now = new Date();\n const created: CalendarEvent = { ...item, id: `event-${Date.now()}`, createdAt: now, updatedAt: now } as CalendarEvent;\n this.events.push(created);\n return created;\n }\n\n async updateItem(id: string, updates: Partial<CalendarEvent>) {\n const idx = this.events.findIndex(e => e.id === id);\n if (idx === -1) throw new Error('Not found');\n this.events[idx] = { ...this.events[idx], ...updates, updatedAt: new Date() };\n return this.events[idx];\n }\n\n async deleteItem(id: string) {\n this.events = this.events.filter(e => e.id !== id);\n }\n\n async search(query: string) {\n const q = query.toLowerCase();\n return this.events.filter(e => e.title.toLowerCase().includes(q));\n }\n\n async getCalendars() { return CALENDARS; }\n\n async getEventsByRange(start: Date, end: Date) {\n return this.events.filter(e => e.endDate >= start && e.startDate <= end);\n }\n\n async getEventsByCalendar(calendarId: string) {\n return this.events.filter(e => e.calendarId === calendarId);\n }\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"contacts-DQXTZzHc.js","names":["provider: IContactProvider","err: any","contact: ContactItem | null","groupId: string | null","query: string","sortBy: ContactSortBy","contact: Omit<ContactItem, 'id' | 'createdAt' | 'updatedAt'>","id: string","contacts: ContactItem[]","GROUPS_DATA: ContactGroup[]","contacts: ContactItem[]","id: string","item: Omit<ContactItem, 'id' | 'createdAt' | 'updatedAt'>","created: ContactItem","updates: Partial<ContactItem>","query: string","groupId: string","name: string"],"sources":["../src/contacts/ContactListModel.ts","../src/contacts/ContactAvatar.tsx","../src/contacts/ContactCard.tsx","../src/contacts/ContactList.tsx","../src/contacts/ContactDetail.tsx","../src/contacts/ContactGroupSidebar.tsx","../src/contacts/ContactBrowser.tsx","../src/contacts/MockContactProvider.ts"],"sourcesContent":["import { makeAutoObservable, runInAction } from 'mobx';\nimport type { IContactProvider, ContactItem, ContactGroup } from './types';\n\nexport type ContactSortBy = 'firstName' | 'lastName' | 'company';\n\nexport class ContactListModel {\n contacts: ContactItem[] = [];\n selectedContact: ContactItem | null = null;\n groups: ContactGroup[] = [];\n currentGroup: string | null = null;\n searchQuery = '';\n sortBy: ContactSortBy = 'lastName';\n loading = false;\n error: string | null = null;\n\n constructor(private provider: IContactProvider) {\n makeAutoObservable(this);\n }\n\n get filteredContacts(): ContactItem[] {\n let result = this.contacts;\n if (this.searchQuery) {\n const q = this.searchQuery.toLowerCase();\n result = result.filter(c =>\n c.firstName.toLowerCase().includes(q) ||\n c.lastName.toLowerCase().includes(q) ||\n c.email?.toLowerCase().includes(q) ||\n c.company?.toLowerCase().includes(q)\n );\n }\n return this.sortContacts(result);\n }\n\n get groupedByLetter(): Map<string, ContactItem[]> {\n const groups = new Map<string, ContactItem[]>();\n for (const contact of this.filteredContacts) {\n const letter = (this.sortBy === 'firstName' ? contact.firstName : contact.lastName)\n .charAt(0).toUpperCase();\n const group = groups.get(letter) ?? [];\n group.push(contact);\n groups.set(letter, group);\n }\n return groups;\n }\n\n get groupedByGroup(): Map<string, ContactItem[]> {\n const groups = new Map<string, ContactItem[]>();\n for (const contact of this.filteredContacts) {\n for (const groupName of contact.groups ?? ['Ungrouped']) {\n const group = groups.get(groupName) ?? [];\n group.push(contact);\n groups.set(groupName, group);\n }\n }\n return groups;\n }\n\n async loadContacts() {\n this.loading = true;\n this.error = null;\n try {\n const [contacts, groups] = await Promise.all([\n this.currentGroup\n ? this.provider.getByGroup(this.currentGroup)\n : this.provider.listItems(),\n this.provider.getGroups()\n ]);\n runInAction(() => {\n this.contacts = contacts;\n this.groups = groups;\n });\n } catch (err: any) {\n runInAction(() => { this.error = err?.message || 'Failed to load contacts'; });\n } finally {\n runInAction(() => { this.loading = false; });\n }\n }\n\n selectContact(contact: ContactItem | null) {\n this.selectedContact = contact;\n }\n\n setGroup(groupId: string | null) {\n this.currentGroup = groupId;\n this.loadContacts();\n }\n\n setSearch(query: string) {\n this.searchQuery = query;\n }\n\n setSort(sortBy: ContactSortBy) {\n this.sortBy = sortBy;\n }\n\n async addContact(contact: Omit<ContactItem, 'id' | 'createdAt' | 'updatedAt'>) {\n const created = await this.provider.createItem(contact);\n runInAction(() => { this.contacts.push(created); });\n return created;\n }\n\n async deleteContact(id: string) {\n await this.provider.deleteItem(id);\n runInAction(() => {\n this.contacts = this.contacts.filter(c => c.id !== id);\n if (this.selectedContact?.id === id) this.selectedContact = null;\n });\n }\n\n private sortContacts(contacts: ContactItem[]): ContactItem[] {\n return [...contacts].sort((a, b) => {\n switch (this.sortBy) {\n case 'firstName': return a.firstName.localeCompare(b.firstName);\n case 'lastName': return a.lastName.localeCompare(b.lastName);\n case 'company': return (a.company ?? '').localeCompare(b.company ?? '');\n default: return 0;\n }\n });\n }\n}\n","import React from 'react';\n\nexport interface ContactAvatarProps {\n firstName: string;\n lastName: string;\n avatar?: string;\n size?: 'sm' | 'md' | 'lg';\n className?: string;\n}\n\nconst sizeClasses = {\n sm: 'w-8 h-8 text-xs',\n md: 'w-10 h-10 text-sm',\n lg: 'w-16 h-16 text-xl',\n};\n\nconst bgColors = [\n 'bg-blue-500', 'bg-green-500', 'bg-purple-500', 'bg-pink-500',\n 'bg-indigo-500', 'bg-teal-500', 'bg-orange-500', 'bg-red-500',\n];\n\nexport const ContactAvatar = ({ firstName, lastName, avatar, size = 'md', className = '' }: ContactAvatarProps) => {\n const initials = `${firstName.charAt(0)}${lastName.charAt(0)}`.toUpperCase();\n const colorIdx = (firstName.charCodeAt(0) + lastName.charCodeAt(0)) % bgColors.length;\n\n if (avatar) {\n return <img src={avatar} alt={`${firstName} ${lastName}`} className={`${sizeClasses[size]} rounded-full object-cover ${className}`} />;\n }\n\n return (\n <div className={`${sizeClasses[size]} ${bgColors[colorIdx]} rounded-full flex items-center justify-center text-white font-medium ${className}`}>\n {initials}\n </div>\n );\n};\n","import React from 'react';\nimport { Mail, Phone, Building } from 'lucide-react';\nimport type { ContactItem } from './types';\nimport { ContactAvatar } from './ContactAvatar';\n\nexport interface ContactCardProps {\n contact: ContactItem;\n selected?: boolean;\n onClick?: () => void;\n className?: string;\n}\n\nexport const ContactCard = ({ contact, selected = false, onClick, className = '' }: ContactCardProps) => (\n <button\n onClick={onClick}\n className={`flex items-center gap-3 px-4 py-3 w-full text-left transition-colors ${\n selected ? 'bg-blue-50 border-l-2 border-blue-500' : 'hover:bg-gray-50 border-l-2 border-transparent'\n } ${className}`}\n >\n <ContactAvatar firstName={contact.firstName} lastName={contact.lastName} avatar={contact.avatar} />\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-sm font-medium text-gray-900 truncate\" title={`${contact.firstName} ${contact.lastName}`}>\n {contact.firstName} {contact.lastName}\n </p>\n {contact.company && (\n <p className=\"text-xs text-gray-500 flex items-center gap-1 truncate\" title={contact.company}>\n <Building size={12} />\n {contact.company}\n </p>\n )}\n </div>\n <div className=\"flex items-center gap-1.5 text-gray-400\">\n {contact.email && <Mail size={14} />}\n {contact.phone && <Phone size={14} />}\n </div>\n </button>\n);\n","import React from 'react';\nimport { observer } from 'mobx-react-lite';\nimport type { ContactListModel } from './ContactListModel';\nimport { ContactCard } from './ContactCard';\n\nexport interface ContactListProps {\n model: ContactListModel;\n className?: string;\n}\n\nexport const ContactList = observer<ContactListProps>(({ model, className = '' }) => (\n <div className={`overflow-y-auto ${className}`}>\n {Array.from(model.groupedByLetter.entries()).map(([letter, contacts]) => (\n <div key={letter}>\n <div className=\"sticky top-0 bg-gray-50/90 backdrop-blur-sm px-4 py-1 border-b border-gray-100\">\n <span className=\"text-xs font-semibold text-gray-500\">{letter}</span>\n </div>\n {contacts.map(contact => (\n <ContactCard\n key={contact.id}\n contact={contact}\n selected={model.selectedContact?.id === contact.id}\n onClick={() => model.selectContact(contact)}\n />\n ))}\n </div>\n ))}\n {model.filteredContacts.length === 0 && (\n <div className=\"flex items-center justify-center h-32 text-gray-400 text-sm\">No contacts found</div>\n )}\n </div>\n));\n","import React from 'react';\nimport { observer } from 'mobx-react-lite';\nimport { Mail, Phone, MapPin, Building, Calendar, Tag } from 'lucide-react';\nimport type { ContactListModel } from './ContactListModel';\nimport { ContactAvatar } from './ContactAvatar';\n\nexport interface ContactDetailProps {\n model: ContactListModel;\n className?: string;\n}\n\nconst DetailRow = ({ icon: Icon, label, value }: { icon: React.ElementType; label: string; value: string }) => (\n <div className=\"flex items-start gap-3 py-2\">\n <Icon size={16} className=\"text-gray-400 mt-0.5 flex-shrink-0\" />\n <div>\n <p className=\"text-xs text-gray-500\">{label}</p>\n <p className=\"text-sm text-gray-900\">{value}</p>\n </div>\n </div>\n);\n\nexport const ContactDetail = observer<ContactDetailProps>(({ model, className = '' }) => {\n const contact = model.selectedContact;\n\n if (!contact) {\n return (\n <div className={`flex items-center justify-center h-full text-gray-400 text-sm ${className}`}>\n Select a contact to view details\n </div>\n );\n }\n\n return (\n <div className={`p-6 overflow-y-auto ${className}`}>\n <div className=\"flex flex-col items-center mb-6\">\n <ContactAvatar firstName={contact.firstName} lastName={contact.lastName} avatar={contact.avatar} size=\"lg\" />\n <h2 className=\"mt-3 text-lg font-semibold text-gray-900\">{contact.firstName} {contact.lastName}</h2>\n {contact.company && <p className=\"text-sm text-gray-500\">{contact.company}</p>}\n </div>\n\n <div className=\"divide-y divide-gray-100\">\n {contact.email && <DetailRow icon={Mail} label=\"Email\" value={contact.email} />}\n {contact.phone && <DetailRow icon={Phone} label=\"Phone\" value={contact.phone} />}\n {contact.company && <DetailRow icon={Building} label=\"Company\" value={contact.company} />}\n {contact.address && <DetailRow icon={MapPin} label=\"Address\" value={contact.address} />}\n {contact.birthday && <DetailRow icon={Calendar} label=\"Birthday\" value={contact.birthday.toLocaleDateString()} />}\n {contact.groups && contact.groups.length > 0 && (\n <div className=\"flex items-start gap-3 py-2\">\n <Tag size={16} className=\"text-gray-400 mt-0.5 flex-shrink-0\" />\n <div>\n <p className=\"text-xs text-gray-500\">Groups</p>\n <div className=\"flex flex-wrap gap-1 mt-1\">\n {contact.groups.map(g => (\n <span key={g} className=\"text-xs bg-gray-100 text-gray-600 px-2 py-0.5 rounded-full\">{g}</span>\n ))}\n </div>\n </div>\n </div>\n )}\n </div>\n </div>\n );\n});\n","import React from 'react';\nimport { observer } from 'mobx-react-lite';\nimport { Users, User } from 'lucide-react';\nimport type { ContactListModel } from './ContactListModel';\n\nexport interface ContactGroupSidebarProps {\n model: ContactListModel;\n className?: string;\n}\n\nexport const ContactGroupSidebar = observer<ContactGroupSidebarProps>(({ model, className = '' }) => (\n <div className={`w-56 border-r border-gray-200 bg-gray-50 overflow-y-auto ${className}`}>\n <div className=\"p-3\">\n <h3 className=\"text-xs font-semibold text-gray-500 uppercase tracking-wider mb-2\">Groups</h3>\n <button\n onClick={() => model.setGroup(null)}\n className={`flex items-center gap-2 w-full px-3 py-2 rounded-lg text-sm transition-colors ${\n model.currentGroup === null ? 'bg-blue-100 text-blue-700' : 'text-gray-700 hover:bg-gray-100'\n }`}\n >\n <Users size={16} />\n <span>All Contacts</span>\n <span className=\"ml-auto text-xs text-gray-400\">{model.contacts.length}</span>\n </button>\n {model.groups.map(group => (\n <button\n key={group.id}\n onClick={() => model.setGroup(group.id)}\n className={`flex items-center gap-2 w-full px-3 py-2 rounded-lg text-sm transition-colors ${\n model.currentGroup === group.id ? 'bg-blue-100 text-blue-700' : 'text-gray-700 hover:bg-gray-100'\n }`}\n >\n <User size={16} />\n <span className=\"truncate\" title={group.name}>{group.name}</span>\n <span className=\"ml-auto text-xs text-gray-400\">{group.count}</span>\n </button>\n ))}\n </div>\n </div>\n));\n","import React, { useEffect } from 'react';\nimport { observer } from 'mobx-react-lite';\nimport { Search, Loader2 } from 'lucide-react';\nimport { BrowserError } from '@anymux/ui/components/browser-error';\nimport type { ContactListModel } from './ContactListModel';\nimport { ContactList } from './ContactList';\nimport { ContactDetail } from './ContactDetail';\nimport { ContactGroupSidebar } from './ContactGroupSidebar';\n\nexport interface ContactBrowserProps {\n model: ContactListModel;\n className?: string;\n showSidebar?: boolean;\n}\n\nexport const ContactBrowser = observer<ContactBrowserProps>(({ model, className = '', showSidebar = true }) => {\n useEffect(() => { model.loadContacts(); }, [model]);\n\n return (\n <div className={`flex h-full bg-white rounded-xl border border-gray-200 overflow-hidden ${className}`}>\n {showSidebar && <ContactGroupSidebar model={model} />}\n\n <div className=\"flex-1 flex flex-col min-w-0 border-r border-gray-200\" style={{ maxWidth: '380px' }}>\n {/* Search */}\n <div className=\"px-4 py-2 border-b border-gray-200\">\n <div className=\"relative\">\n <Search size={16} className=\"absolute left-3 top-1/2 -translate-y-1/2 text-gray-400\" />\n <input\n type=\"text\"\n placeholder=\"Search contacts...\"\n value={model.searchQuery}\n onChange={e => model.setSearch(e.target.value)}\n className=\"w-full pl-9 pr-3 py-1.5 text-sm border border-gray-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500\"\n />\n </div>\n </div>\n\n {model.loading ? (\n <div className=\"flex items-center justify-center h-64\">\n <Loader2 size={24} className=\"animate-spin text-gray-400\" />\n </div>\n ) : model.error ? (\n <BrowserError\n error={model.error}\n context=\"Contacts\"\n onRetry={() => model.loadContacts()}\n />\n ) : (\n <ContactList model={model} className=\"flex-1\" />\n )}\n </div>\n\n <ContactDetail model={model} className=\"flex-1\" />\n </div>\n );\n});\n","import type { IContactProvider, ContactItem, ContactGroup } from './types';\n\nconst FIRST_NAMES = ['Alice', 'Bob', 'Charlie', 'Diana', 'Emma', 'Frank', 'Grace', 'Henry', 'Iris', 'Jack', 'Karen', 'Leo', 'Mia', 'Nathan', 'Olivia', 'Paul', 'Quinn', 'Rachel', 'Sam', 'Tina', 'Uma', 'Victor', 'Wendy', 'Xavier', 'Yara', 'Zach'];\nconst LAST_NAMES = ['Anderson', 'Baker', 'Chen', 'Davis', 'Evans', 'Fisher', 'Garcia', 'Hall', 'Ibrahim', 'Jones', 'Kim', 'Lee', 'Martinez', 'Nguyen', 'O\\'Brien', 'Park', 'Quinn', 'Robinson', 'Smith', 'Taylor', 'Ueda', 'Vega', 'Wilson', 'Xu', 'Yang', 'Zhang'];\nconst COMPANIES = ['Acme Corp', 'TechStart Inc', 'Global Systems', 'DataFlow', 'CloudNine', 'PixelPerfect'];\nconst GROUPS_DATA: ContactGroup[] = [\n { id: 'family', name: 'Family', count: 8 },\n { id: 'work', name: 'Work', count: 12 },\n { id: 'friends', name: 'Friends', count: 10 },\n { id: 'vip', name: 'VIP', count: 5 },\n];\n\nfunction generateContacts(): ContactItem[] {\n const contacts: ContactItem[] = [];\n const now = new Date();\n for (let i = 0; i < FIRST_NAMES.length; i++) {\n contacts.push({\n id: `contact-${i}`,\n type: 'contact',\n title: `${FIRST_NAMES[i]} ${LAST_NAMES[i]}`,\n firstName: FIRST_NAMES[i],\n lastName: LAST_NAMES[i],\n email: `${FIRST_NAMES[i].toLowerCase()}.${LAST_NAMES[i].toLowerCase()}@example.com`,\n phone: `+1 (555) ${String(100 + i).padStart(3, '0')}-${String(1000 + i * 37).slice(0, 4)}`,\n company: COMPANIES[i % COMPANIES.length],\n address: `${100 + i} Main St, City ${i % 10}, ST ${10000 + i}`,\n birthday: new Date(1985 + (i % 20), i % 12, 1 + (i % 28)),\n groups: [GROUPS_DATA[i % GROUPS_DATA.length].id],\n createdAt: now,\n updatedAt: now,\n });\n }\n return contacts;\n}\n\nexport class MockContactProvider implements IContactProvider {\n private contacts = generateContacts();\n\n async listItems() { return this.contacts; }\n\n async getItem(id: string) { return this.contacts.find(c => c.id === id) ?? null; }\n\n async createItem(item: Omit<ContactItem, 'id' | 'createdAt' | 'updatedAt'>) {\n const now = new Date();\n const created: ContactItem = { ...item, id: `contact-${Date.now()}`, createdAt: now, updatedAt: now } as ContactItem;\n this.contacts.push(created);\n return created;\n }\n\n async updateItem(id: string, updates: Partial<ContactItem>) {\n const idx = this.contacts.findIndex(c => c.id === id);\n if (idx === -1) throw new Error('Not found');\n this.contacts[idx] = { ...this.contacts[idx], ...updates, updatedAt: new Date() };\n return this.contacts[idx];\n }\n\n async deleteItem(id: string) {\n this.contacts = this.contacts.filter(c => c.id !== id);\n }\n\n async search(query: string) {\n const q = query.toLowerCase();\n return this.contacts.filter(c =>\n c.firstName.toLowerCase().includes(q) || c.lastName.toLowerCase().includes(q)\n );\n }\n\n async getGroups() { return GROUPS_DATA; }\n\n async getByGroup(groupId: string) {\n return this.contacts.filter(c => c.groups?.includes(groupId));\n }\n\n async searchByName(name: string) {\n return this.search(name);\n }\n}\n"],"mappings":"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"}