Files
hotline-planner/dev/ui-ux/Codex : deepseek (not good)/src/services/socket-service.js
2026-02-24 13:32:01 +01:00

285 lines
7.8 KiB
JavaScript

const { ref, reactive } = Vue;
const HUBS = [
{ id: 'DE', name: 'GERMANY HUB (DE)' },
{ id: 'IT', name: 'ITALY HUB (IT)' },
{ id: 'FR', name: 'FRANCE HUB (FR)' },
{ id: 'GB', name: 'UNITED KINGDOM (GB)' },
{ id: 'ES', name: 'SPAIN HUB (ES)' },
{ id: 'AE', name: 'UAE HUB (AE)' },
{ id: 'PL', name: 'POLAND HUB (PL)' }
];
const DEPARTMENTS = ['Support', 'Technical', 'Sales', 'VIP', 'Billing'];
const ROLES = ['Senior Lead', 'Specialist', 'Agent'];
const SKILLS = [
'English',
'German',
'French',
'Molecular App',
'Hardware',
'Billing Specialist',
'VIP Concierge',
'Technical Training'
];
const SHIFTS = [
{ id: 'm', label: 'MORNING', color: 'green-7', badgeClass: 'day-cell-shift-badge-green' },
{ id: 'a', label: 'AFTERNOON', color: 'blue-7', badgeClass: 'day-cell-shift-badge-blue' },
{ id: 'h', label: 'HOTLINE', color: 'indigo-7', badgeClass: 'day-cell-shift-badge-indigo' },
{ id: 'e', label: 'EOD ONLY', color: 'pink-7', badgeClass: 'day-cell-shift-badge-pink' }
];
const agents = ref([]);
const loading = ref(false);
const lockedCells = ref(new Set());
const onlineUsers = ref([]);
const assignments = reactive({});
const comments = reactive({});
const notes = reactive({});
const holidays = reactive({});
const specialDays = reactive({});
const MOCK_COMMENTS_TEXT = [
'Late arrival expected.',
'Dental appointment.',
'Swapped shift.',
'Priority focus.',
'Remote session.'
];
const MOCK_NOTES_TEXT = [
'Headset check.',
'VPN slow.',
'Training session.',
'Backup Billing.',
'Overtime pending.'
];
const ONLINE_USER_ROLES = ['Planner', 'Scheduler', 'Lead', 'Manager'];
const ONLINE_USERS_POOL = Array.from({ length: 28 }, (_, i) => {
const pravatarId = (i % 70) + 1;
return {
id: i + 1,
name: `User ${i + 1}`,
role: ONLINE_USER_ROLES[i % ONLINE_USER_ROLES.length],
img: `https://i.pravatar.cc/150?img=${pravatarId}`
};
});
const formatDateForId = (date) => {
if (!date) return '';
const d = new Date(date);
const month = '' + (d.getMonth() + 1);
const day = '' + d.getDate();
const year = d.getFullYear();
return [year, month.padStart(2, '0'), day.padStart(2, '0')].join('-');
};
const generateMockAgents = (count) => {
return Array.from({ length: count }, (_, i) => {
const hub = HUBS[Math.floor(Math.random() * HUBS.length)];
return {
id: i + 1,
name: `Agent ${i + 1}`,
dept: DEPARTMENTS[i % DEPARTMENTS.length],
role: ROLES[i % ROLES.length],
hub: hub.id,
hubName: hub.name,
skills: [SKILLS[i % SKILLS.length], SKILLS[(i + 2) % SKILLS.length]],
avatar: `https://api.dicebear.com/7.x/avataaars/svg?seed=Agent${i}`
};
});
};
const loadDataFromDatabase = (startDate, notify) => {
loading.value = true;
setTimeout(() => {
const fetchedAgents = generateMockAgents(800);
agents.value = fetchedAgents;
const mockStartDate = new Date(startDate);
fetchedAgents.forEach(agent => {
if (!assignments[agent.id]) assignments[agent.id] = {};
if (!comments[agent.id]) comments[agent.id] = {};
if (!notes[agent.id]) notes[agent.id] = {};
for (let i = 0; i < 60; i++) {
const d = new Date(mockStartDate);
d.setDate(d.getDate() + i);
const dStr = formatDateForId(d);
if ((agent.id + i) % 7 === 0) assignments[agent.id][dStr] = SHIFTS[0].id;
else if ((agent.id + i) % 5 === 0) assignments[agent.id][dStr] = SHIFTS[1].id;
if ((agent.id + i) % 20 === 0) comments[agent.id][dStr] = MOCK_COMMENTS_TEXT[(agent.id + i) % MOCK_COMMENTS_TEXT.length];
if ((agent.id + i) % 25 === 0) notes[agent.id][dStr] = MOCK_NOTES_TEXT[(agent.id + i) % MOCK_NOTES_TEXT.length];
}
});
for (const key in holidays) delete holidays[key];
for (const key in specialDays) delete specialDays[key];
const today = new Date();
const tomorrow = new Date(today);
tomorrow.setDate(today.getDate() + 1);
holidays[formatDateForId(tomorrow)] = 'Regional Holiday';
const eventDay = new Date(today);
eventDay.setDate(today.getDate() + 5);
specialDays[formatDateForId(eventDay)] = 'Quarterly Planning';
loading.value = false;
if (notify) {
notify({ message: 'Data Loaded: 800 Agents', color: 'positive', position: 'top', timeout: 1000 });
}
}, 2000);
};
const handleWssMessage = (type, payload, notify) => {
if (type === 'LOCK_CELL') {
const key = `${payload.agentId}:${payload.date}`;
lockedCells.value.add(key);
const agent = agents.value.find(a => a.id === payload.agentId);
const name = agent ? agent.name : 'Unknown Agent';
if (notify) {
notify({
message: `WSS: Cell Locked for ${name} on ${payload.date}`,
color: 'negative',
position: 'top',
icon: 'lock'
});
}
}
};
const simulateWssLock = (notify) => {
if (agents.value.length === 0) return;
const randomAgent = agents.value[Math.floor(Math.random() * agents.value.length)];
let targetDate = new Date();
const day = targetDate.getDay();
if (day === 0) {
targetDate.setDate(targetDate.getDate() + 1);
} else if (day === 6) {
targetDate.setDate(targetDate.getDate() + 2);
}
const dateStr = formatDateForId(targetDate);
handleWssMessage('LOCK_CELL', { agentId: randomAgent.id, date: dateStr }, notify);
};
const selectRandomItems = (list, count) => {
const pool = [...list];
const selected = [];
while (pool.length > 0 && selected.length < count) {
const idx = Math.floor(Math.random() * pool.length);
selected.push(pool.splice(idx, 1)[0]);
}
return selected;
};
const seedOnlineUsers = (count = 7) => {
onlineUsers.value = selectRandomItems(ONLINE_USERS_POOL, count);
};
const simulateWssOnlineUsersChange = (notify) => {
if (onlineUsers.value.length === 0) {
seedOnlineUsers(3);
return;
}
const maxOnline = 18;
const minOnline = 1;
const shouldAdd = Math.random() > 0.45;
const current = [...onlineUsers.value];
if (shouldAdd && current.length < maxOnline) {
const available = ONLINE_USERS_POOL.filter(
user => !current.some(existing => existing.id === user.id)
);
if (available.length === 0) return;
const joiner = available[Math.floor(Math.random() * available.length)];
onlineUsers.value = [...current, joiner];
if (notify) {
notify({
message: `WSS: ${joiner.name} joined`,
color: 'grey-8',
textColor: 'white',
position: 'bottom-right',
timeout: 700,
icon: 'group_add'
});
}
return;
}
if (current.length > minOnline) {
const leaverIndex = Math.floor(Math.random() * current.length);
const [leaver] = current.splice(leaverIndex, 1);
onlineUsers.value = current;
if (notify) {
notify({
message: `WSS: ${leaver.name} left`,
color: 'grey-8',
textColor: 'white',
position: 'bottom-right',
timeout: 700,
icon: 'person_remove'
});
}
}
};
const startOnlineUsersSimulation = (notify, options = {}) => {
const minDelay = options.minDelay ?? 1800;
const maxDelay = options.maxDelay ?? 5200;
let timeoutId = null;
let active = true;
if (onlineUsers.value.length === 0) {
seedOnlineUsers(options.seedCount ?? 7);
}
const scheduleNext = () => {
if (!active) return;
const delay = Math.floor(minDelay + Math.random() * (maxDelay - minDelay));
timeoutId = setTimeout(() => {
simulateWssOnlineUsersChange(notify);
scheduleNext();
}, delay);
};
scheduleNext();
return () => {
active = false;
if (timeoutId) clearTimeout(timeoutId);
};
};
export {
HUBS,
DEPARTMENTS,
ROLES,
SKILLS,
SHIFTS,
agents,
loading,
lockedCells,
onlineUsers,
assignments,
comments,
notes,
holidays,
specialDays,
loadDataFromDatabase,
handleWssMessage,
simulateWssLock,
seedOnlineUsers,
simulateWssOnlineUsersChange,
startOnlineUsersSimulation
};