feat: Implement chat module in sidebar

This commit is contained in:
gpt-engineer-app[bot]
2025-10-11 16:44:26 +00:00
parent 45963fa7ba
commit ff1312ae50
3 changed files with 537 additions and 1024 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -8,6 +8,7 @@ export interface User {
avatar: string; avatar: string;
online: boolean; online: boolean;
lastSeen?: string; lastSeen?: string;
serviceType?: 'taxi' | 'restaurant' | 'hotel' | 'guide' | 'politur' | 'support';
} }
export interface Message { export interface Message {
@@ -32,6 +33,7 @@ export interface Chat {
avatar?: string; avatar?: string;
online?: boolean; online?: boolean;
lastActivity: string; lastActivity: string;
serviceType?: 'taxi' | 'restaurant' | 'hotel' | 'guide' | 'politur' | 'support';
} }
class ChatApiService { class ChatApiService {

View File

@@ -1,290 +1,277 @@
// Mock data for chat system // Mock data for chat system - Tourist Services
import { User, Chat, Message } from './chatApi'; import { User, Chat, Message } from './chatApi';
export const mockChatData = { export const mockChatData = {
users: [ users: [
{ {
id: 'user-1', id: 'taxi-1',
name: 'Alexander Kaminski', name: 'Taxi Central Punta Cana',
email: 'alexander@example.com', email: 'taxicentral@karibeo.com',
avatar: '/api/placeholder/40/40', avatar: '/api/placeholder/40/40',
online: true, online: true,
lastSeen: new Date().toISOString() lastSeen: new Date().toISOString(),
serviceType: 'taxi'
}, },
{ {
id: 'user-2', id: 'restaurant-1',
name: 'Edwin Martins', name: 'El Mesón Restaurant',
email: 'edwin@example.com', email: 'elmeson@karibeo.com',
avatar: '/api/placeholder/40/40',
online: false,
lastSeen: new Date(Date.now() - 3600000).toISOString()
},
{
id: 'user-3',
name: 'Gabriel North',
email: 'gabriel@example.com',
avatar: '/api/placeholder/40/40', avatar: '/api/placeholder/40/40',
online: true, online: true,
lastSeen: new Date().toISOString() lastSeen: new Date().toISOString(),
serviceType: 'restaurant'
}, },
{ {
id: 'user-4', id: 'hotel-1',
name: 'Ethan Blackwood', name: 'Paradisus Palma Real',
email: 'ethan@example.com', email: 'paradisus@karibeo.com',
avatar: '/api/placeholder/40/40',
online: false,
lastSeen: new Date(Date.now() - 86400000).toISOString()
},
{
id: 'user-5',
name: 'Alexander Steele',
email: 'alexs@example.com',
avatar: '/api/placeholder/40/40', avatar: '/api/placeholder/40/40',
online: true, online: true,
lastSeen: new Date().toISOString() lastSeen: new Date().toISOString(),
serviceType: 'hotel'
}, },
{ {
id: 'user-6', id: 'guide-1',
name: 'Marcus Knight', name: 'Carlos - Guía Turístico',
email: 'marcus@example.com', email: 'carlos.guide@karibeo.com',
avatar: '/api/placeholder/40/40', avatar: '/api/placeholder/40/40',
online: false, online: false,
lastSeen: new Date(Date.now() - 1800000).toISOString() lastSeen: new Date(Date.now() - 3600000).toISOString(),
serviceType: 'guide'
}, },
{ {
id: 'user-7', id: 'politur-1',
name: 'Pranoti Deshpande', name: 'POLITUR Punta Cana',
email: 'pranoti@example.com', email: 'politur.pc@karibeo.com',
avatar: '/api/placeholder/40/40', avatar: '/api/placeholder/40/40',
online: true, online: true,
lastSeen: new Date().toISOString() lastSeen: new Date().toISOString(),
serviceType: 'politur'
}, },
{ {
id: 'user-8', id: 'taxi-2',
name: 'Sarah Wilson', name: 'Uber Bávaro',
email: 'sarah@example.com', email: 'uber.bavaro@karibeo.com',
avatar: '/api/placeholder/40/40',
online: false,
lastSeen: new Date(Date.now() - 7200000).toISOString()
},
{
id: 'user-9',
name: 'Michael Chen',
email: 'michael@example.com',
avatar: '/api/placeholder/40/40', avatar: '/api/placeholder/40/40',
online: true, online: true,
lastSeen: new Date().toISOString() lastSeen: new Date().toISOString(),
serviceType: 'taxi'
}, },
{ {
id: 'user-10', id: 'restaurant-2',
name: 'Lisa Rodriguez', name: 'Captain Cook Restaurant',
email: 'lisa@example.com', email: 'captaincook@karibeo.com',
avatar: '/api/placeholder/40/40', avatar: '/api/placeholder/40/40',
online: false, online: false,
lastSeen: new Date(Date.now() - 3600000).toISOString() lastSeen: new Date(Date.now() - 1800000).toISOString(),
serviceType: 'restaurant'
},
{
id: 'hotel-2',
name: 'Hard Rock Hotel',
email: 'hardrock@karibeo.com',
avatar: '/api/placeholder/40/40',
online: true,
lastSeen: new Date().toISOString(),
serviceType: 'hotel'
},
{
id: 'guide-2',
name: 'María - Guía Cultural',
email: 'maria.guide@karibeo.com',
avatar: '/api/placeholder/40/40',
online: true,
lastSeen: new Date().toISOString(),
serviceType: 'guide'
},
{
id: 'admin-support',
name: 'Soporte Karibeo',
email: 'support@karibeo.com',
avatar: '/api/placeholder/40/40',
online: true,
lastSeen: new Date().toISOString(),
serviceType: 'support'
} }
] as User[], ] as User[],
chats: [ chats: [
{ {
id: 'chat-1', id: 'chat-taxi-1',
name: 'Alexander Kaminski', name: 'Taxi Central Punta Cana',
type: 'direct', type: 'direct',
serviceType: 'taxi',
participants: [ participants: [
{ {
id: 'user-1', id: 'taxi-1',
name: 'Alexander Kaminski', name: 'Taxi Central Punta Cana',
email: 'alexander@example.com', email: 'taxicentral@karibeo.com',
avatar: '/api/placeholder/40/40', avatar: '/api/placeholder/40/40',
online: true online: true
} }
], ],
unreadCount: 2, unreadCount: 1,
lastActivity: new Date(Date.now() - 300000).toISOString(), lastActivity: new Date(Date.now() - 300000).toISOString(),
avatar: '/api/placeholder/40/40', avatar: '/api/placeholder/40/40',
online: true, online: true,
lastMessage: { lastMessage: {
id: 'msg-1', id: 'msg-taxi-1',
chatId: 'chat-1', chatId: 'chat-taxi-1',
senderId: 'user-1', senderId: 'taxi-1',
senderName: 'Alexander Kaminski', senderName: 'Taxi Central Punta Cana',
senderAvatar: '/api/placeholder/40/40', senderAvatar: '/api/placeholder/40/40',
content: 'A new feature has been updated to your...', content: '¡Su taxi llegará en 5 minutos! Vehículo: Toyota Corolla blanco, Placa: A123456',
timestamp: '10:30 AM', timestamp: '10:30 AM',
isOwn: false, isOwn: false,
status: 'delivered' status: 'delivered'
} }
}, },
{ {
id: 'chat-2', id: 'chat-restaurant-1',
name: 'Edwin Martins', name: 'El Mesón Restaurant',
type: 'direct', type: 'direct',
serviceType: 'restaurant',
participants: [ participants: [
{ {
id: 'user-2', id: 'restaurant-1',
name: 'Edwin Martins', name: 'El Mesón Restaurant',
email: 'edwin@example.com', email: 'elmeson@karibeo.com',
avatar: '/api/placeholder/40/40', avatar: '/api/placeholder/40/40',
online: false online: true
} }
], ],
unreadCount: 1, unreadCount: 0,
lastActivity: new Date(Date.now() - 3600000).toISOString(), lastActivity: new Date(Date.now() - 3600000).toISOString(),
avatar: '/api/placeholder/40/40', avatar: '/api/placeholder/40/40',
online: false, online: true,
lastMessage: { lastMessage: {
id: 'msg-2', id: 'msg-restaurant-1',
chatId: 'chat-2', chatId: 'chat-restaurant-1',
senderId: 'user-2', senderId: 'restaurant-1',
senderName: 'Edwin Martins', senderName: 'El Mesón Restaurant',
senderAvatar: '/api/placeholder/40/40', senderAvatar: '/api/placeholder/40/40',
content: 'How can i improve my chances of getting a deposit?', content: 'Su reserva para 4 personas está confirmada para las 8:00 PM',
timestamp: '10:05 PM', timestamp: '9:15 AM',
isOwn: false,
status: 'read'
}
},
{
id: 'chat-hotel-1',
name: 'Paradisus Palma Real',
type: 'direct',
serviceType: 'hotel',
participants: [
{
id: 'hotel-1',
name: 'Paradisus Palma Real',
email: 'paradisus@karibeo.com',
avatar: '/api/placeholder/40/40',
online: true
}
],
unreadCount: 2,
lastActivity: new Date(Date.now() - 1800000).toISOString(),
avatar: '/api/placeholder/40/40',
online: true,
lastMessage: {
id: 'msg-hotel-1',
chatId: 'chat-hotel-1',
senderId: 'hotel-1',
senderName: 'Paradisus Palma Real',
senderAvatar: '/api/placeholder/40/40',
content: 'Check-in disponible desde las 3:00 PM. ¿Necesita transporte desde el aeropuerto?',
timestamp: '10:05 AM',
isOwn: false, isOwn: false,
status: 'delivered' status: 'delivered'
} }
}, },
{ {
id: 'chat-3', id: 'chat-guide-1',
name: 'Gabriel North', name: 'Carlos - Guía Turístico',
type: 'direct', type: 'direct',
serviceType: 'guide',
participants: [ participants: [
{ {
id: 'user-3', id: 'guide-1',
name: 'Gabriel North', name: 'Carlos - Guía Turístico',
email: 'gabriel@example.com', email: 'carlos.guide@karibeo.com',
avatar: '/api/placeholder/40/40', avatar: '/api/placeholder/40/40',
online: true online: false
} }
], ],
unreadCount: 0, unreadCount: 0,
lastActivity: new Date(Date.now() - 86400000).toISOString(), lastActivity: new Date(Date.now() - 86400000).toISOString(),
avatar: '/api/placeholder/40/40', avatar: '/api/placeholder/40/40',
online: true, online: false,
lastMessage: { lastMessage: {
id: 'msg-3', id: 'msg-guide-1',
chatId: 'chat-3', chatId: 'chat-guide-1',
senderId: 'user-3', senderId: 'guide-1',
senderName: 'Gabriel North', senderName: 'Carlos - Guía Turístico',
senderAvatar: '/api/placeholder/40/40', senderAvatar: '/api/placeholder/40/40',
content: 'Hey Chris, could i ask you to help me out with variation...', content: 'Tour a Saona Island confirmado para mañana a las 8 AM. Incluye snorkel y almuerzo.',
timestamp: 'Tue', timestamp: 'Ayer',
isOwn: false, isOwn: false,
status: 'read' status: 'read'
} }
}, },
{ {
id: 'chat-4', id: 'chat-politur-1',
name: 'Ethan Blackwood', name: 'POLITUR Punta Cana',
type: 'direct', type: 'direct',
serviceType: 'politur',
participants: [ participants: [
{ {
id: 'user-4', id: 'politur-1',
name: 'Ethan Blackwood', name: 'POLITUR Punta Cana',
email: 'ethan@example.com', email: 'politur.pc@karibeo.com',
avatar: '/api/placeholder/40/40', avatar: '/api/placeholder/40/40',
online: false online: true
} }
], ],
unreadCount: 0, unreadCount: 0,
lastActivity: new Date(Date.now() - 172800000).toISOString(), lastActivity: new Date(Date.now() - 172800000).toISOString(),
avatar: '/api/placeholder/40/40', avatar: '/api/placeholder/40/40',
online: false, online: true,
lastMessage: { lastMessage: {
id: 'msg-4', id: 'msg-politur-1',
chatId: 'chat-4', chatId: 'chat-politur-1',
senderId: 'user-4', senderId: 'politur-1',
senderName: 'Ethan Blackwood', senderName: 'POLITUR Punta Cana',
senderAvatar: '/api/placeholder/40/40', senderAvatar: '/api/placeholder/40/40',
content: 'By injected humour, or randomised words which...', content: 'Estamos disponibles 24/7 para asistencia turística. ¿En qué podemos ayudarle?',
timestamp: '1/22/2019', timestamp: 'Mar 5',
isOwn: false, isOwn: false,
status: 'read' status: 'read'
} }
}, },
{ {
id: 'chat-5', id: 'chat-support',
name: 'Alexander Steele', name: 'Soporte Karibeo',
type: 'direct', type: 'direct',
serviceType: 'support',
participants: [ participants: [
{ {
id: 'user-5', id: 'admin-support',
name: 'Alexander Steele', name: 'Soporte Karibeo',
email: 'alexs@example.com', email: 'support@karibeo.com',
avatar: '/api/placeholder/40/40', avatar: '/api/placeholder/40/40',
online: true online: true
} }
], ],
unreadCount: 3, unreadCount: 0,
lastActivity: new Date(Date.now() - 259200000).toISOString(), lastActivity: new Date(Date.now() - 259200000).toISOString(),
avatar: '/api/placeholder/40/40', avatar: '/api/placeholder/40/40',
online: true, online: true,
lastMessage: { lastMessage: {
id: 'msg-5', id: 'msg-support-1',
chatId: 'chat-5', chatId: 'chat-support',
senderId: 'user-5', senderId: 'admin-support',
senderName: 'Alexander Steele', senderName: 'Soporte Karibeo',
senderAvatar: '/api/placeholder/40/40', senderAvatar: '/api/placeholder/40/40',
content: 'No more running out of the office at 4pm on Fridays!', content: 'Bienvenido a Karibeo. ¿En qué podemos ayudarle hoy?',
timestamp: '1/18/2019', timestamp: 'Mar 3',
isOwn: false,
status: 'delivered'
}
},
{
id: 'chat-6',
name: 'Marcus Knight',
type: 'direct',
participants: [
{
id: 'user-6',
name: 'Marcus Knight',
email: 'marcus@example.com',
avatar: '/api/placeholder/40/40',
online: false
}
],
unreadCount: 0,
lastActivity: new Date(Date.now() - 345600000).toISOString(),
avatar: '/api/placeholder/40/40',
online: false,
lastMessage: {
id: 'msg-6',
chatId: 'chat-6',
senderId: 'user-6',
senderName: 'Marcus Knight',
senderAvatar: '/api/placeholder/40/40',
content: 'All your favourite books at your reach! We are now mobile',
timestamp: '1/09/2019',
isOwn: false,
status: 'read'
}
},
{
id: 'chat-7',
name: 'Pranoti Deshpande',
type: 'direct',
participants: [
{
id: 'user-7',
name: 'Pranoti Deshpande',
email: 'pranoti@example.com',
avatar: '/api/placeholder/40/40',
online: true
}
],
unreadCount: 0,
lastActivity: new Date(Date.now() - 432000000).toISOString(),
avatar: '/api/placeholder/40/40',
online: true,
lastMessage: {
id: 'msg-7',
chatId: 'chat-7',
senderId: 'user-7',
senderName: 'Pranoti Deshpande',
senderAvatar: '/api/placeholder/40/40',
content: 'Dear Deborah, your Thai massage is today at 5pm.',
timestamp: 'Feb 9',
isOwn: false, isOwn: false,
status: 'read' status: 'read'
} }
@@ -292,96 +279,152 @@ export const mockChatData = {
] as Chat[], ] as Chat[],
messages: [ messages: [
// Chat 1 messages // Taxi Chat messages
{ {
id: 'msg-1-1', id: 'msg-taxi-1-1',
chatId: 'chat-1', chatId: 'chat-taxi-1',
senderId: 'user-1', senderId: 'current-user',
senderName: 'Alexander Kaminski', senderName: 'You',
senderAvatar: '/api/placeholder/40/40', senderAvatar: '/api/placeholder/40/40',
content: 'Hello! How are you doing today?', content: 'Necesito un taxi al aeropuerto internacional de Punta Cana',
timestamp: '10:15 AM',
isOwn: true,
status: 'read'
},
{
id: 'msg-taxi-1-2',
chatId: 'chat-taxi-1',
senderId: 'taxi-1',
senderName: 'Taxi Central Punta Cana',
senderAvatar: '/api/placeholder/40/40',
content: 'Perfecto. ¿A qué hora necesita el servicio?',
timestamp: '10:18 AM',
isOwn: false,
status: 'delivered'
},
{
id: 'msg-taxi-1-3',
chatId: 'chat-taxi-1',
senderId: 'current-user',
senderName: 'You',
senderAvatar: '/api/placeholder/40/40',
content: 'A las 2:00 PM por favor',
timestamp: '10:20 AM',
isOwn: true,
status: 'read'
},
{
id: 'msg-taxi-1-4',
chatId: 'chat-taxi-1',
senderId: 'taxi-1',
senderName: 'Taxi Central Punta Cana',
senderAvatar: '/api/placeholder/40/40',
content: '¡Su taxi llegará en 5 minutos! Vehículo: Toyota Corolla blanco, Placa: A123456',
timestamp: '10:30 AM', timestamp: '10:30 AM',
isOwn: false, isOwn: false,
status: 'delivered' status: 'delivered'
}, },
// Restaurant Chat messages
{ {
id: 'msg-1-2', id: 'msg-restaurant-1-1',
chatId: 'chat-1', chatId: 'chat-restaurant-1',
senderId: 'current-user', senderId: 'current-user',
senderName: 'You', senderName: 'You',
senderAvatar: '/api/placeholder/40/40', senderAvatar: '/api/placeholder/40/40',
content: "Hi! I'm doing great, thank you for asking. How about you?", content: 'Hola, quisiera hacer una reserva para esta noche',
timestamp: '10:35 AM', timestamp: '9:00 AM',
isOwn: true, isOwn: true,
status: 'read' status: 'read'
}, },
{ {
id: 'msg-1-3', id: 'msg-restaurant-1-2',
chatId: 'chat-1', chatId: 'chat-restaurant-1',
senderId: 'user-1', senderId: 'restaurant-1',
senderName: 'Alexander Kaminski', senderName: 'El Mesón Restaurant',
senderAvatar: '/api/placeholder/40/40', senderAvatar: '/api/placeholder/40/40',
content: 'A new feature has been updated to your account. Would you like me to show you around?', content: '¡Hola! Claro que sí. ¿Para cuántas personas y a qué hora?',
timestamp: '10:36 AM', timestamp: '9:10 AM',
isOwn: false, isOwn: false,
status: 'delivered' status: 'delivered'
}, },
{ {
id: 'msg-1-4', id: 'msg-restaurant-1-3',
chatId: 'chat-1', chatId: 'chat-restaurant-1',
senderId: 'current-user', senderId: 'current-user',
senderName: 'You', senderName: 'You',
senderAvatar: '/api/placeholder/40/40', senderAvatar: '/api/placeholder/40/40',
content: "That sounds great! I'd love to hear more about it.", content: 'Para 4 personas a las 8:00 PM',
timestamp: '10:40 AM', timestamp: '9:12 AM',
isOwn: true, isOwn: true,
status: 'read' status: 'read'
}, },
// Chat 2 messages
{ {
id: 'msg-2-1', id: 'msg-restaurant-1-4',
chatId: 'chat-2', chatId: 'chat-restaurant-1',
senderId: 'user-2', senderId: 'restaurant-1',
senderName: 'Edwin Martins', senderName: 'El Mesón Restaurant',
senderAvatar: '/api/placeholder/40/40', senderAvatar: '/api/placeholder/40/40',
content: 'How can i improve my chances of getting a deposit?', content: 'Su reserva para 4 personas está confirmada para las 8:00 PM. ¿Tiene alguna preferencia dietética?',
timestamp: '10:05 PM', timestamp: '9:15 AM',
isOwn: false,
status: 'read'
},
// Hotel Chat messages
{
id: 'msg-hotel-1-1',
chatId: 'chat-hotel-1',
senderId: 'hotel-1',
senderName: 'Paradisus Palma Real',
senderAvatar: '/api/placeholder/40/40',
content: 'Bienvenido a Paradisus Palma Real. Su habitación estará lista pronto.',
timestamp: '10:00 AM',
isOwn: false, isOwn: false,
status: 'delivered' status: 'delivered'
}, },
{ {
id: 'msg-2-2', id: 'msg-hotel-1-2',
chatId: 'chat-2', chatId: 'chat-hotel-1',
senderId: 'current-user', senderId: 'current-user',
senderName: 'You', senderName: 'You',
senderAvatar: '/api/placeholder/40/40', senderAvatar: '/api/placeholder/40/40',
content: 'There are several ways to improve your chances. First, make sure your profile is complete...', content: 'Gracias. ¿A qué hora es el check-in?',
timestamp: '10:10 PM', timestamp: '10:03 AM',
isOwn: true, isOwn: true,
status: 'read' status: 'read'
}, },
// Chat 3 messages
{ {
id: 'msg-3-1', id: 'msg-hotel-1-3',
chatId: 'chat-3', chatId: 'chat-hotel-1',
senderId: 'user-3', senderId: 'hotel-1',
senderName: 'Gabriel North', senderName: 'Paradisus Palma Real',
senderAvatar: '/api/placeholder/40/40', senderAvatar: '/api/placeholder/40/40',
content: 'Hey Chris, could i ask you to help me out with variation of our main design theme?', content: 'Check-in disponible desde las 3:00 PM. ¿Necesita transporte desde el aeropuerto?',
timestamp: '10:05 AM',
isOwn: false,
status: 'delivered'
},
// Guide Chat messages
{
id: 'msg-guide-1-1',
chatId: 'chat-guide-1',
senderId: 'current-user',
senderName: 'You',
senderAvatar: '/api/placeholder/40/40',
content: 'Me gustaría reservar el tour a Saona Island',
timestamp: '2:00 PM',
isOwn: true,
status: 'read'
},
{
id: 'msg-guide-1-2',
chatId: 'chat-guide-1',
senderId: 'guide-1',
senderName: 'Carlos - Guía Turístico',
senderAvatar: '/api/placeholder/40/40',
content: 'Excelente elección! Tenemos disponibilidad para mañana. El tour incluye transporte, snorkel, y almuerzo buffet.',
timestamp: '2:15 PM', timestamp: '2:15 PM',
isOwn: false, isOwn: false,
status: 'read' status: 'read'
},
{
id: 'msg-3-2',
chatId: 'chat-3',
senderId: 'current-user',
senderName: 'You',
senderAvatar: '/api/placeholder/40/40',
content: 'Of course! What specific variations are you looking for?',
timestamp: '2:20 PM',
isOwn: true,
status: 'read'
} }
] as Message[] ] as Message[]
}; };