crm-widget
v0.1.12
Published
Встраиваемый CRM виджет на базе Vue.js для интеграции в веб-приложения.
Maintainers
Readme
CRM Widget
Встраиваемый CRM виджет на базе Vue.js для интеграции в веб-приложения.
🚀 Быстрый старт
Установка
npm install crm-widgetИспользование
1. Подключение через script tag
<!DOCTYPE html>
<html>
<head>
<title>CRM Widget</title>
</head>
<body>
<div id="crm-widget"></div>
<script src="./dist/crm-widget.umd.js"></script>
<script>
const widget = window.CrmWidget.init('#crm-widget', {
msg: 'Добро пожаловать в CRM',
})
</script>
</body>
</html>2. Импорт как ES модуль
import { initCrmWidget } from 'crm-widget'
const widget = initCrmWidget('#my-widget', {
msg: 'Мой CRM виджет',
})3. Использование в React
import React, { useEffect, useRef } from 'react'
import { initCrmWidget } from 'crm-widget'
function CrmWidgetComponent({ options }) {
const widgetRef = useRef(null)
const instanceRef = useRef(null)
useEffect(() => {
if (widgetRef.current) {
instanceRef.current = initCrmWidget(widgetRef.current, options)
}
return () => {
if (instanceRef.current) {
instanceRef.current.destroy()
}
}
}, [options])
return <div ref={widgetRef}></div>
}📋 API
initCrmWidget(selector, options)
Инициализирует виджет в указанном контейнере.
Параметры:
selector(string|HTMLElement) - CSS селектор или DOM элементoptions(object) - Опции конфигурации виджета
Возвращает: Объект с методами управления виджетом
Опции конфигурации:
interface WidgetOptions {
msg?: string
locationId?: string
eventId?: string
outputFormat?: 'json' | 'string'
withEncode?: boolean
// Инициализированные данные о выбранных ячейках бронирования
initialData?: {
selectedCells?: string[] // Массив ключей выбранных ячеек
selectedEventId?: string // ID выбранного события
multipleBookings?: boolean // Режим множественных бронирований
}
}Примеры:
// Базовое использование
const widget = initCrmWidget('#widget-container', {
msg: 'Привет от CRM виджета',
locationId: '123e4567-e89b-12d3-a456-426614174000',
})
// С инициализированными выбранными ячейками
const widgetWithData = initCrmWidget('#widget-container', {
locationId: 'location-123',
eventId: 'event-456',
initialData: {
selectedCells: [
'0-1-2024-01-15-2024-01-15', // Понедельник, 9:00, 15 января
'1-1-2024-01-15-2024-01-15', // Понедельник, 10:00, 15 января
'2-1-2024-01-15-2024-01-15', // Понедельник, 11:00, 15 января
],
selectedEventId: 'event-456',
multipleBookings: false,
},
})🚀 Инициализация выбранных ячеек
CRM Widget поддерживает передачу инициализированных данных о выбранных ячейках бронирования для восстановления состояния пользователя.
Преимущества инициализации
- Восстановление состояния - виджет сразу показывает выбранные пользователем ячейки
- Сохранение прогресса - пользователь не теряет сделанный выбор при перезагрузке
- Интеграция с внешними системами - возможность синхронизации с другими компонентами
- Улучшенный UX - плавный переход между страницами без потери данных
Структура initialData
interface InitialData {
selectedCells?: string[] // Массив ключей выбранных ячеек
selectedEventId?: string // ID выбранного события
multipleBookings?: boolean // Режим множественных бронирований
// Или готовые данные бронирования (закодированные или нет)
bookingData?: BookingData // Готовые данные бронирования
encodedBookingData?: string // Закодированные данные бронирования
}Формат ключей ячеек
Ключи ячеек имеют формат: {timeIndex}-{dayIndex}-{date}-{weekStart}
timeIndex- индекс временного слота (0 = 9:00, 1 = 10:00, и т.д.)dayIndex- индекс дня недели (0 = воскресенье, 1 = понедельник, и т.д.)date- дата в формате YYYY-MM-DDweekStart- дата начала недели в формате YYYY-MM-DD
Пример: '0-1-2024-01-15-2024-01-15' = Понедельник, 9:00, 15 января 2024
Примеры использования
Обычное бронирование
const widget = initCrmWidget('#widget', {
locationId: 'studio-1',
eventId: 'photo-session',
initialData: {
selectedCells: [
'0-1-2024-01-15-2024-01-15', // Понедельник, 9:00, 15 января
'1-1-2024-01-15-2024-01-15', // Понедельник, 10:00, 15 января
'2-1-2024-01-15-2024-01-15', // Понедельник, 11:00, 15 января
],
selectedEventId: 'photo-session',
multipleBookings: false,
},
})Множественные бронирования
const widget = initCrmWidget('#widget', {
locationId: 'studio-2',
eventId: 'video-shoot',
initialData: {
selectedCells: [
'0-1-2024-01-15-2024-01-15', // Понедельник, 9:00, 15 января
'1-1-2024-01-15-2024-01-15', // Понедельник, 10:00, 15 января
'0-2-2024-01-16-2024-01-15', // Вторник, 9:00, 16 января
'1-2-2024-01-16-2024-01-15', // Вторник, 10:00, 16 января
],
selectedEventId: 'video-shoot',
multipleBookings: true,
},
})Восстановление из localStorage
// Сохранение состояния
function saveSelection() {
const calendarStore = useCalendarStore()
const selection = {
selectedCells: Array.from(calendarStore.selectedCells),
selectedEventId: calendarStore.selectedEventId,
multipleBookings: calendarStore.multipleBookings,
}
localStorage.setItem('crm-widget-selection', JSON.stringify(selection))
}
// Восстановление состояния
function restoreSelection() {
const savedData = localStorage.getItem('crm-widget-selection')
if (savedData) {
const parsedData = JSON.parse(savedData)
return initCrmWidget('#widget', {
locationId: 'studio-1',
eventId: 'photo-session',
initialData: parsedData,
})
}
return initCrmWidget('#widget', { locationId: 'studio-1' })
}Работа с готовыми данными бронирования
// Инициализация с готовыми данными бронирования
function initializeWithBookingData(bookingData) {
return initCrmWidget('#widget', {
locationId: bookingData.locationId,
eventId: bookingData.locationEventId,
initialData: {
bookingData: bookingData,
},
})
}
// Инициализация с закодированными данными
function initializeWithEncodedData(encodedData) {
return initCrmWidget('#widget', {
locationId: 'studio-1',
initialData: {
encodedBookingData: encodedData,
},
})
}
// Полный цикл: получение -> сохранение -> восстановление
function handleBooking(bookingData) {
console.log('Получены данные бронирования:', bookingData)
// Сохраняем для последующего восстановления
localStorage.setItem('last-booking-data', JSON.stringify(bookingData))
// Если данные закодированы, сохраняем и закодированную версию
if (bookingData.encoded) {
localStorage.setItem('last-encoded-booking', bookingData.encoded)
}
}
// Восстановление с последними данными
function restoreLastBooking() {
const savedData = localStorage.getItem('last-booking-data')
const savedEncoded = localStorage.getItem('last-encoded-booking')
if (savedEncoded) {
return initializeWithEncodedData(savedEncoded)
} else if (savedData) {
const bookingData = JSON.parse(savedData)
return initializeWithBookingData(bookingData)
}
return null
}Методы виджета
destroy()
Удаляет виджет из DOM и очищает ресурсы.
widget.destroy()update(newOptions)
Обновляет виджет с новыми опциями.
widget.update({
msg: 'Обновленное сообщение',
})🛠️ Разработка
Требования
- Node.js 16+
- npm или yarn
Установка зависимостей
npm installПеременные окружения
Создайте файл .env в корне проекта:
# API Configuration
VITE_API_URL=http://localhost:3000/api
# Default Location ID for development
VITE_LOCATION_ID=123e4567-e89b-12d3-a456-426614174000Команды разработки
# Запуск в режиме разработки (порт 5173)
npm run dev
# Сборка виджета для продакшена
npm run build
# Предварительный просмотр сборки
npm run previewСтруктура проекта
crm-widget/
├── src/
│ ├── components/ # Vue компоненты
│ ├── App.vue # Основной компонент виджета
│ ├── main.js # Точка входа для разработки
│ ├── widget.js # Точка входа для виджета
│ └── style.css # Глобальные стили
├── dist/ # Собранные файлы
├── demo.html # Демо страница
├── package.json
├── vite.config.js # Конфигурация сборки
└── README.md🎨 Кастомизация
CSS переменные
Виджет использует CSS изоляцию через класс .crm-widget-container. Вы можете переопределить стили:
.crm-widget-container {
--primary-color: #your-color;
--background-color: #your-bg;
}Темизация
const widget = initCrmWidget('#widget', {
theme: 'dark',
primaryColor: '#007bff',
backgroundColor: '#ffffff',
})🧪 Тестирование
Откройте demo.html в браузере для интерактивного тестирования виджета.
📦 Сборка
Виджет собирается в двух форматах:
- ES модуль (
crm-widget.es.js) - для современных приложений - UMD (
crm-widget.umd.js) - для подключения через script tag
🤝 Совместимость
- Vue.js 3.x
- Современные браузеры (ES6+)
- IE11+ (требует полифиллов)
📄 Лицензия
MIT
🆘 Поддержка
Если у вас возникли вопросы или проблемы, создайте issue в репозитории проекта.
