@@ -9,95 +9,36 @@ const {
const { mClient } = require ( '../../..' ) ;
require ( 'dotenv' ) . config ( )
const db = mClient . db ( process . env . M _DB ) ; // adjust if needed
const coll = db . collection ( 'items_daily_numbers' ) ;
module . exports = {
data : new SlashCommandBuilder ( )
. setName ( 'ezd' )
. setDescription ( 'Zeigt die täglichen Erster/ Zweiter/ Dritter Ergebnisse ' ) ,
. setDescription ( 'Ersti Zweiti Dritti ' )
. addSubcommand ( s =>
s
. setName ( 'show' )
. setDescription ( 'Zeigt die täglichen Erster/Zweiter/Dritter Ergebnisse' )
)
. addSubcommand ( s =>
s
. setName ( 'leaderboard' )
. setDescription ( 'Zeigt die Rangliste der EZDler' )
)
,
async execute ( interaction , client ) {
const db = mClient . db ( process . env . M _DB ) ; // adjust if needed
const coll = db . collection ( 'items_daily_numbers' ) ;
switch ( interaction . options . _subcommand ) {
case 'show' :
ezdShow ( interaction )
break ;
case 'leaderboard' :
ezdLeaderboard ( interaction )
break ;
const today = new Date ( ) . toLocaleDateString ( "en-CA" , {
timeZone : "Europe/Berlin"
} ) ;
let currentDate = today ;
const sessionId = ` ${ interaction . user . id } - ${ Date . now ( ) } ` ;
const buildEmbed = ( doc , date ) => {
const p = doc ? . positions || { } ;
const line = ( emoji , label , key ) => {
const v = p [ key ] ;
return ` ${ emoji } ** ${ label } :** ${ v ? ` <@ ${ v . userId } > ` : "—" } ` ;
} ;
const germanDate = new Date ( ` ${ date } T00:00:00 ` ) . toLocaleDateString ( "de-DE" , {
timeZone : "Europe/Berlin" ,
day : "2-digit" ,
month : "2-digit" ,
year : "numeric"
} ) ;
return new EmbedBuilder ( )
. setTitle ( ` 📊 EZD Übersicht – ${ germanDate } ` )
. setColor ( 0x2b2d31 )
. setDescription ( [
line ( "🥇" , "Ersti" , "Ersti" ) ,
line ( "🥈" , "Zweiti" , "Zweiti" ) ,
line ( "🥉" , "Dritti" , "Dritti" )
] . join ( "\n" ) ) ;
} ;
const buildButtons = ( date ) => {
return new ActionRowBuilder ( ) . addComponents (
new ButtonBuilder ( )
. setCustomId ( ` ezd_prev ` )
. setLabel ( "⬅️" )
. setStyle ( ButtonStyle . Secondary ) ,
new ButtonBuilder ( )
. setCustomId ( ` ezd_next ` )
. setLabel ( "➡️" )
. setStyle ( ButtonStyle . Secondary )
) ;
} ;
const doc = await coll . findOne ( { date : currentDate } ) ;
const msg = await interaction . reply ( {
embeds : [ buildEmbed ( doc , currentDate ) ] ,
components : [ buildButtons ( currentDate ) ]
} ) ;
const collector = msg . createMessageComponentCollector ( {
time : 1000 * 60 * 10 // 10 minutes
} ) ;
collector . on ( "collect" , async ( btn ) => {
if ( btn . user . id !== interaction . user . id ) {
return btn . reply ( {
content : "❌ Diese Buttons gehören nicht dir." ,
flags : MessageFlags . Ephemeral
} ) ;
}
if ( btn . customId === ` ezd_prev ` ) {
currentDate = shiftDate ( currentDate , - 1 ) ;
}
if ( btn . customId === ` ezd_next ` ) {
currentDate = shiftDate ( currentDate , 1 ) ;
}
const newDoc = await coll . findOne ( { date : currentDate } ) ;
await btn . update ( {
embeds : [ buildEmbed ( newDoc , currentDate ) ] ,
components : [ buildButtons ( currentDate ) ]
} ) ;
} ) ;
default :
break ;
}
}
} ;
@@ -107,3 +48,202 @@ function shiftDate(dateStr, offset) {
d . setDate ( d . getDate ( ) + offset ) ;
return d . toISOString ( ) . slice ( 0 , 10 ) ;
}
async function ezdShow ( interaction ) {
const today = new Date ( ) . toLocaleDateString ( "en-CA" , {
timeZone : "Europe/Berlin"
} ) ;
let currentDate = today ;
const sessionId = ` ${ interaction . user . id } - ${ Date . now ( ) } ` ;
const buildEmbed = ( doc , date ) => {
const p = doc ? . positions || { } ;
const line = ( emoji , label , key ) => {
const v = p [ key ] ;
return ` ${ emoji } ** ${ label } :** ${ v ? ` <@ ${ v . userId } > ` : "—" } ` ;
} ;
const germanDate = new Date ( ` ${ date } T00:00:00 ` ) . toLocaleDateString ( "de-DE" , {
timeZone : "Europe/Berlin" ,
day : "2-digit" ,
month : "2-digit" ,
year : "numeric"
} ) ;
return new EmbedBuilder ( )
. setTitle ( ` 📊 EZD Übersicht – ${ germanDate } ` )
. setColor ( 0x2b2d31 )
. setDescription ( [
line ( "🥇" , "Ersti" , "Ersti" ) ,
line ( "🥈" , "Zweiti" , "Zweiti" ) ,
line ( "🥉" , "Dritti" , "Dritti" )
] . join ( "\n" ) ) ;
} ;
const buildButtons = ( date ) => {
return new ActionRowBuilder ( ) . addComponents (
new ButtonBuilder ( )
. setCustomId ( ` ezd_prev ` )
. setLabel ( "⬅️" )
. setStyle ( ButtonStyle . Secondary ) ,
new ButtonBuilder ( )
. setCustomId ( ` ezd_next ` )
. setLabel ( "➡️" )
. setStyle ( ButtonStyle . Secondary )
) ;
} ;
const doc = await coll . findOne ( { date : currentDate } ) ;
const msg = await interaction . reply ( {
embeds : [ buildEmbed ( doc , currentDate ) ] ,
components : [ buildButtons ( currentDate ) ]
} ) ;
const collector = msg . createMessageComponentCollector ( {
time : 1000 * 60 * 10 // 10 minutes
} ) ;
collector . on ( "collect" , async ( btn ) => {
if ( btn . user . id !== interaction . user . id ) {
return btn . reply ( {
content : "❌ Diese Buttons gehören nicht dir." ,
flags : MessageFlags . Ephemeral
} ) ;
}
if ( btn . customId === ` ezd_prev ` ) {
currentDate = shiftDate ( currentDate , - 1 ) ;
}
if ( btn . customId === ` ezd_next ` ) {
currentDate = shiftDate ( currentDate , 1 ) ;
}
const newDoc = await coll . findOne ( { date : currentDate } ) ;
await btn . update ( {
embeds : [ buildEmbed ( newDoc , currentDate ) ] ,
components : [ buildButtons ( currentDate ) ]
} ) ;
} ) ;
}
async function ezdLeaderboard ( interaction ) {
const docs = await coll . find ( { } ) . toArray ( ) ;
const leaderboard = new Map ( ) ;
const add = ( entry , place ) => {
if ( ! entry ? . userId ) return ;
if ( ! leaderboard . has ( entry . userId ) ) {
leaderboard . set ( entry . userId , {
userId : entry . userId ,
points : 0 ,
Ersti : 0 ,
Zweiti : 0 ,
Dritti : 0
} ) ;
}
const user = leaderboard . get ( entry . userId ) ;
user [ place ] ++ ;
if ( place === "Ersti" ) user . points += 3 ;
if ( place === "Zweiti" ) user . points += 2 ;
if ( place === "Dritti" ) user . points += 1 ;
} ;
for ( const doc of docs ) {
const p = doc . positions || { } ;
add ( p . Ersti , "Ersti" ) ;
add ( p . Zweiti , "Zweiti" ) ;
add ( p . Dritti , "Dritti" ) ;
}
const users = [ ... leaderboard . values ( ) ] . sort ( ( a , b ) => {
if ( b . points !== a . points ) return b . points - a . points ;
if ( b . Ersti !== a . Ersti ) return b . Ersti - a . Ersti ;
if ( b . Zweiti !== a . Zweiti ) return b . Zweiti - a . Zweiti ;
return b . Dritti - a . Dritti ;
} ) ;
const PAGE _SIZE = 5 ;
const pageCount = Math . max ( 1 , Math . ceil ( users . length / PAGE _SIZE ) ) ;
let page = 0 ;
const buildEmbed = ( ) => {
const slice = users . slice (
page * PAGE _SIZE ,
page * PAGE _SIZE + PAGE _SIZE
) ;
const description = slice . length
? slice . map ( ( u , i ) => {
const rank = page * PAGE _SIZE + i + 1 ;
return ` **# ${ rank } ** <@ ${ u . userId } > — ** ${ u . points } **
🥇 ${ u . Ersti } · 🥈 ${ u . Zweiti } · 🥉 ${ u . Dritti } ` ;
} ) . join ( "\n\n" )
: "—" ;
return new EmbedBuilder ( )
. setTitle ( "🏆 EZD Rangliste" )
. setColor ( 0x2b2d31 )
. setDescription ( description ) ;
} ;
const buildButtons = ( ) =>
new ActionRowBuilder ( ) . addComponents (
new ButtonBuilder ( )
. setCustomId ( "ezd_lb_prev" )
. setLabel ( "⬅️" )
. setStyle ( ButtonStyle . Secondary ) ,
new ButtonBuilder ( )
. setCustomId ( "ezd_lb_page" )
. setLabel ( ` ${ page + 1 } / ${ pageCount } ` )
. setStyle ( ButtonStyle . Primary )
. setDisabled ( true ) ,
new ButtonBuilder ( )
. setCustomId ( "ezd_lb_next" )
. setLabel ( "➡️" )
. setStyle ( ButtonStyle . Secondary )
) ;
const msg = await interaction . reply ( {
embeds : [ buildEmbed ( ) ] ,
components : [ buildButtons ( ) ]
} ) ;
const collector = msg . createMessageComponentCollector ( {
time : 1000 * 60 * 10
} ) ;
collector . on ( "collect" , async btn => {
if ( btn . user . id !== interaction . user . id ) {
return btn . reply ( {
content : "❌ Diese Buttons gehören nicht dir." ,
flags : MessageFlags . Ephemeral
} ) ;
}
if ( btn . customId === "ezd_lb_prev" )
page = ( page - 1 + pageCount ) % pageCount ;
if ( btn . customId === "ezd_lb_next" )
page = ( page + 1 ) % pageCount ;
await btn . update ( {
embeds : [ buildEmbed ( ) ] ,
components : [ buildButtons ( ) ]
} ) ;
} ) ;
}