MediaWiki:Gadget-resign-calculator.js: Difference between revisions

Re-sign calculator
 
The league is NBA RealGM
 
(10 intermediate revisions by the same user not shown)
Line 1: Line 1:
/**
/**
  * 1TC RealGM — re-sign salary calculator.
  * NBA RealGM — re-sign salary calculator.
  * Implements the formula on [[NBA:Re-Signing]]. If the two ever disagree,
  * Implements the formula on [[NBA:Re-Signing]]. If the two ever disagree,
  * the wiki page is the rule and this script is the bug.
  * the wiki page is the rule and this script is the bug.
Line 7: Line 7:
'use strict';
'use strict';


var MAX = 11500000,
// The league numbers a season by the year it ends in, so the season being
// signed for is always the next one up from the current calendar year.
var NEW_POST_URL = 'https://2teams1cup.com/forum/index.php?act=post&do=new_post&f=70';
 
var UPCOMING_SEASON = new Date().getFullYear() + 1,
MAX = 11500000,
DISCOUNT = 1500000,
DISCOUNT = 1500000,
CUTOFF = 85;
CUTOFF = 85;
Line 32: Line 37:
nonPositive: capped <= 0
nonPositive: capped <= 0
};
};
}
/** A monospace post block with a copy button. */
function postBlock( text ) {
var wrap = document.createElement( 'div' );
wrap.className = 'tc-calc-postwrap';
var pre = document.createElement( 'div' );
pre.className = 'tc-calc-post';
pre.textContent = text;
wrap.appendChild( pre );
var btn = document.createElement( 'button' );
btn.className = 'tc-calc-copy';
btn.type = 'button';
btn.textContent = 'Copy';
btn.addEventListener( 'click', function () {
function done( ok ) {
btn.textContent = ok ? 'Copied' : 'Press \u2318C / Ctrl+C';
setTimeout( function () { btn.textContent = 'Copy'; }, 2000 );
}
if ( navigator.clipboard && navigator.clipboard.writeText ) {
navigator.clipboard.writeText( text ).then( function () { done( true ); },
function () { selectFallback( pre ); done( false ); } );
} else {
selectFallback( pre );
done( false );
}
} );
wrap.appendChild( btn );
var actions = document.createElement( 'div' );
actions.className = 'tc-calc-actions';
var link = document.createElement( 'a' );
link.href = NEW_POST_URL;
link.target = '_blank';
link.rel = 'noopener';
link.textContent = 'Copy and start a new topic in NBA: Re-Signing';
// IPB has no parameter for seeding the post body, so the next best thing
// is to put it on the clipboard on the way out.
link.addEventListener( 'click', function () {
if ( navigator.clipboard && navigator.clipboard.writeText ) {
navigator.clipboard.writeText( text );
}
} );
actions.appendChild( link );
var outer = document.createElement( 'div' );
outer.appendChild( wrap );
outer.appendChild( actions );
return outer;
}
/** Clipboard API unavailable or refused: select the text so the reader can copy it. */
function selectFallback( el ) {
var range = document.createRange();
range.selectNodeContents( el );
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange( range );
}
}


Line 39: Line 105:
var form = document.createElement( 'div' );
var form = document.createElement( 'div' );
form.className = 'tc-calc';
form.className = 'tc-calc';
/**
* One labelled row. Controls live in their own flex wrapper so that on a
* narrow screen the label can stack above them while they stay in a row.
*/
function row( labelText, controls, extraClass ) {
var r = document.createElement( 'div' );
r.className = 'tc-calc-row' + ( extraClass ? ' ' + extraClass : '' );
var l = document.createElement( 'label' );
l.textContent = labelText;
var c = document.createElement( 'div' );
c.className = 'tc-calc-controls';
controls.forEach( function ( el ) { c.appendChild( el ); } );
r.appendChild( l );
r.appendChild( c );
form.appendChild( r );
return c;
}


// --- Fantrax scores ---
// --- Fantrax scores ---
var scoreRow = document.createElement( 'div' );
scoreRow.className = 'tc-calc-row tc-scores';
var scoreLabel = document.createElement( 'label' );
scoreLabel.textContent = 'Fantrax scores';
scoreRow.appendChild( scoreLabel );
for ( var i = 0; i < 3; i++ ) {
for ( var i = 0; i < 3; i++ ) {
var input = document.createElement( 'input' );
var input = document.createElement( 'input' );
Line 52: Line 131:
input.min = '0';
input.min = '0';
input.placeholder = [ 'season 1', 'season 2', 'season 3' ][ i ];
input.placeholder = [ 'season 1', 'season 2', 'season 3' ][ i ];
scoreRow.appendChild( input );
scoreInputs.push( input );
scoreInputs.push( input );
}
}
form.appendChild( scoreRow );
row( 'Fantrax scores', scoreInputs, 'tc-scores' );
 
var hint = document.createElement( 'div' );
hint.className = 'tc-calc-note';
hint.textContent = 'Only seasons with 40+ games played count. If he has never had three, ' +
'fill in the ones he did reach 40 games in and leave the rest blank.';
form.appendChild( hint );


// --- term ---
// --- term ---
var termRow = document.createElement( 'div' );
termRow.className = 'tc-calc-row';
var termLabel = document.createElement( 'label' );
termLabel.textContent = 'Contract length';
var term = document.createElement( 'select' );
var term = document.createElement( 'select' );
[ 3, 4, 5 ].forEach( function ( y ) {
[ 3, 4, 5 ].forEach( function ( y ) {
Line 75: Line 143:
term.appendChild( o );
term.appendChild( o );
} );
} );
termRow.appendChild( termLabel );
row( 'Contract length', [ term ] );
termRow.appendChild( term );
form.appendChild( termRow );


// --- optional first season, to generate the contract line ---
// --- first season, to generate the contract line ---
var seasonRow = document.createElement( 'div' );
seasonRow.className = 'tc-calc-row';
var seasonLabel = document.createElement( 'label' );
seasonLabel.textContent = 'First season (optional)';
var season = document.createElement( 'input' );
var season = document.createElement( 'input' );
season.type = 'number';
season.type = 'number';
season.step = '1';
season.step = '1';
season.placeholder = 'e.g. 2028';
season.placeholder = String( UPCOMING_SEASON );
seasonRow.appendChild( seasonLabel );
season.value = String( UPCOMING_SEASON );
seasonRow.appendChild( season );
row( 'First season', [ season ] );
form.appendChild( seasonRow );
 
// --- team and player, for the post block ---
var team = document.createElement( 'input' );
team.type = 'text';
team.placeholder = 'Sonics';
team.className = 'tc-calc-wide';
row( 'Your team (optional)', [ team ] );


// --- player name, for the post block ---
var nameRow = document.createElement( 'div' );
nameRow.className = 'tc-calc-row';
var nameLabel = document.createElement( 'label' );
nameLabel.textContent = 'Player (optional)';
var name = document.createElement( 'input' );
var name = document.createElement( 'input' );
name.type = 'text';
name.type = 'text';
name.placeholder = 'Larry Bird';
name.placeholder = 'Larry Bird';
name.style.width = '14em';
name.className = 'tc-calc-wide';
nameRow.appendChild( nameLabel );
row( 'Player (optional)', [ name ] );
nameRow.appendChild( name );
form.appendChild( nameRow );


var out = document.createElement( 'div' );
var out = document.createElement( 'div' );
Line 167: Line 228:
var years = Number( term.value ),
var years = Number( term.value ),
first = parseInt( season.value, 10 ),
first = parseInt( season.value, 10 ),
endYear = isNaN( first ) ? null : first + years - 1,
who = name.value.trim();
who = name.value.trim() || 'Player Name';
if ( isNaN( first ) ) {
first = UPCOMING_SEASON;
}
var endYear = first + years - 1;


var post = document.createElement( 'div' );
// "Sonics offer Larry Bird 5 years" — team and player drop out if blank.
post.className = 'tc-calc-post';
var tm = team.value.trim(),
post.textContent = who + '\n' +
term_ = years + ( years === 1 ? ' year' : ' years' ),
'(' + scores.join( ', ' ) + ' = ' + ( Number.isInteger( r.average ) ? r.average : r.average.toFixed( 2 ) ) + ')\n' +
prefix = tm && who ? tm + ' offer ' + who :
money( r.salary ) + ( endYear ? ' (' + endYear + ')' : ' (' + years + ' years)' );
( who || ( tm ? tm + ' offer' : '' ) );
out.appendChild( post );


var note = document.createElement( 'div' );
var lines = [ prefix ? prefix + ' ' + term_ : term_ ];
note.className = 'tc-calc-note';
lines.push( '(' + scores.join( ', ' ) + ' = ' +
note.textContent = endYear ?
( Number.isInteger( r.average ) ? r.average : r.average.toFixed( 2 ) ) + ')' );
years + ' years, ' + first + ' through ' + endYear + '. Post this in the NBA: Re-Signing forum.' :
lines.push( money( r.salary ) + ' (' + endYear + ')' );
'Add a first season above to get the contract’s end year.';
out.appendChild( postBlock( lines.join( '\n' ) ) );
out.appendChild( note );
}
}


[].concat( scoreInputs, [ term, season, name ] ).forEach( function ( el ) {
[].concat( scoreInputs, [ term, season, team, name ] ).forEach( function ( el ) {
el.addEventListener( 'input', render );
el.addEventListener( 'input', render );
el.addEventListener( 'change', render );
el.addEventListener( 'change', render );