feat: team indeling in matchmaking + team_swap callback

This commit is contained in:
Nova Coder
2026-05-25 08:33:45 +00:00
parent 208fbe08a5
commit a88d931aab
+92 -3
View File
@@ -555,7 +555,9 @@ bot.onText(/\/match(@padel_nl_bot)?/, async (msg) => {
return;
}
const names = result.players.map(p => p.name).join(', ');
const msgText = '🎾 **Match gevonden!**\n\n📅 ' + result.day + '\n⏰ ' + result.start + '-' + result.end + '\n👥 ' + names + '\n\nReageer met ✅ of ❌';
const t1 = (result.proposedTeam1 || []).map(p => p.name).join(' + ');
const t2 = (result.proposedTeam2 || []).map(p => p.name).join(' + ');
const msgText = '🎾 **Match gevonden!**\n\n📅 ' + result.day + '\n⏰ ' + result.start + '-' + result.end + '\n\n🏆 **Teams:**\n🟡 ' + t1 + '\n🔵 ' + t2 + '\n\nReageer met ✅ of ❌';
const opts = {
parse_mode: 'Markdown',
reply_markup: {
@@ -1501,6 +1503,62 @@ bot.on('callback_query', async (query) => {
logError('match response error:', e.message);
bot.answerCallbackQuery(query.id, { text: 'Fout' }).catch(() => {});
}
} else if (data.startsWith('team_swap_')) {
const matchId = data.split('_')[2];
try {
const teams = await api('/matches/' + matchId + '/teams');
if (!teams || !teams.teams) {
return bot.answerCallbackQuery(query.id, { text: 'Geen teams om te wisselen' }).catch(() => {});
}
// Wissel team1 en team2
const { team1, team2 } = teams.teams;
await api('/matches/' + matchId + '/teams', 'POST', {
team1: team2,
team2: team1
});
// Haal spelernamen op
const players = await api('/players');
const getName = id => { const p = players.find(x => x.id === id); return p ? p.name : '?'; };
const t1 = team2.map(getName).join(' + ');
const t2 = team1.map(getName).join(' + ');
// Stuur DM naar alle spelers
const matchInfo = await api('/matches/' + matchId);
if (matchInfo && Array.isArray(matchInfo.players)) {
for (const pid of matchInfo.players) {
const p = players.find(x => x.id === pid);
if (p && p.telegram_id) {
sendMsg(p.telegram_id,
'🔄 **Teams gewisseld!**\n\nNieuwe indeling voor ' + matchInfo.date + ' ' + matchInfo.start + ':\n🟡 ' + t1 + '\n🔵 ' + t2,
{ parse_mode: 'Markdown' }
);
}
}
}
// Update het originele bericht
bot.editMessageText(
'🎾 **Match — teams gewisseld!**\n\n📅 ' + (matchInfo ? matchInfo.date + ' ' + matchInfo.start : '') + '\n\n🏆 **Teams:**\n🟡 ' + t1 + '\n🔵 ' + t2 + '\n\nReageer met ✅ of ❌',
{
chat_id: query.message.chat.id,
message_id: query.message.message_id,
parse_mode: 'Markdown',
reply_markup: {
inline_keyboard: [
[{ text: '✅ Ja, ik kan!', callback_data: 'match_accept_' + matchId },
{ text: '❌ Nee', callback_data: 'match_reject_' + matchId }],
[{ text: '🔄 Weer wisselen', callback_data: 'team_swap_' + matchId }]
]
}
}
).catch(e => logError('team_swap edit fail:', e.message));
bot.answerCallbackQuery(query.id, { text: 'Teams gewisseld!' }).catch(() => {});
} catch (e) {
logError('team_swap error:', e.message);
bot.answerCallbackQuery(query.id, { text: 'Fout bij wisselen' }).catch(() => {});
}
}
});
@@ -1736,23 +1794,54 @@ async function runMatching() {
}
}
// Balanceer 4 spelers in 2 teams: hoog + laag vs mid
const sorted = [...best4].sort((a, b) => (a.level || 5) - (b.level || 5));
const proposedTeam1 = [sorted[0], sorted[3]]; // hoogste + laagste
const proposedTeam2 = [sorted[1], sorted[2]]; // midden twee
const match = await api('/matches', 'POST', {
day, start, end, date: matchDateStr,
players: best4.map(p => p.id),
telegram_ids: best4.filter(p => p.telegram_id).map(p => p.telegram_id)
});
// Sla voorgestelde teams op
await api('/matches/' + match.id + '/teams', 'POST', {
team1: proposedTeam1.map(p => p.id),
team2: proposedTeam2.map(p => p.id)
});
const t1names = proposedTeam1.map(p => p.name).join(' + ');
const t2names = proposedTeam2.map(p => p.name).join(' + ');
for (const p of best4) {
if (p.telegram_id) {
const levels = best4.map(x => x.name + ' (Lv.' + (x.level || '?') + ')').join(', ');
sendMsg(p.telegram_id,
'🎾 **Match voorgesteld!**\n\n📅 ' + day + ' ' + matchDateStr + '\n⏰ ' + start + '-' + end + '\n👥 ' + levels + '\n\n📍 ' + peakzLocation + ' — baan vrij!\nReageer met /matches of stuur ✅/❌',
'🎾 **Match voorgesteld!**\n\n📅 ' + day + ' ' + matchDateStr + '\n⏰ ' + start + '-' + end + '\n\n🏆 **Teams:**\n🟡 ' + t1names + '\n🔵 ' + t2names + '\n\n📍 ' + peakzLocation + ' — baan vrij!\nStuur /matches om te reageren.',
{ parse_mode: 'Markdown' }
);
}
}
return { day, start, end, players: best4, match };
// Ook naar groeps-chat met team indeling
if (targetChat) {
sendMsg(targetChat,
'🎾 **Match gevonden!**\n\n📅 ' + day + ' ' + matchDateStr + '\n⏰ ' + start + '-' + end + '\n\n🏆 **Teams:**\n🟡 ' + t1names + '\n🔵 ' + t2names + '\n\n📍 ' + peakzLocation + '\n\nReageer met ✅ of ❌',
{
parse_mode: 'Markdown',
reply_markup: {
inline_keyboard: [
[{ text: '✅ Ja, ik kan!', callback_data: 'match_accept_' + match.id },
{ text: '❌ Nee', callback_data: 'match_reject_' + match.id }],
[{ text: '🔄 Andere teams', callback_data: 'team_swap_' + match.id }]
]
}
}
);
}
return { day, start, end, players: best4, match, proposedTeam1, proposedTeam2 };
}
}
return null;